Services_Amazon
[ class tree: Services_Amazon ] [ index: Services_Amazon ] [ all elements ]

Source for file Amazon.php

Documentation is available at Amazon.php

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. /**
  4.  * PHP interface to Amazon Product Advertising API
  5.  *
  6.  * PHP versions 4 and 5
  7.  *
  8.  * LICENSE: Copyright 2004-2009 John Downey. All rights reserved.
  9.  *
  10.  * Redistribution and use in source and binary forms, with or without
  11.  * modification, are permitted provided that the following conditions are met:
  12.  *
  13.  * o Redistributions of source code must retain the above copyright notice, this
  14.  *   list of conditions and the following disclaimer.
  15.  * o Redistributions in binary form must reproduce the above copyright notice,
  16.  *   this list of conditions and the following disclaimer in the documentation
  17.  *   and/or other materials provided with the distribution.
  18.  *
  19.  * THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT "AS IS" AND ANY EXPRESS OR
  20.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  21.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
  22.  * EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  23.  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  24.  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  26.  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  27.  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  28.  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29.  *
  30.  * The views and conclusions contained in the software and documentation are
  31.  * those of the authors and should not be interpreted as representing official
  32.  * policies, either expressed or implied, of The PEAR Group.
  33.  *
  34.  * @category  Web Services
  35.  * @package   Services_Amazon
  36.  * @author    John Downey <jdowney@gmail.com>
  37.  * @author    Tatsuya Tsuruoka <tatsuya.tsuruoka@gmail.com>
  38.  * @copyright 2004-2009 John Downey
  39.  * @license   http://www.freebsd.org/copyright/freebsd-license.html 2 Clause BSD License
  40.  * @version   CVS: $Id: Amazon.php 280260 2009-05-10 09:40:30Z ttsuruoka $
  41.  * @link      http://pear.php.net/package/Services_Amazon/
  42.  * @filesource
  43.  */
  44.  
  45. /**
  46.  * Uses PEAR class for error management.
  47.  */
  48. require_once 'PEAR.php';
  49.  
  50. /**
  51.  * Uses HTTP_Request class to send and receive data from Amazon web servers.
  52.  */
  53. require_once 'HTTP/Request.php';
  54.  
  55. /**
  56.  * Uses XML_Unserializer class to parse data received from Amazon.
  57.  */
  58. require_once 'XML/Unserializer.php';
  59.  
  60. /**
  61.  * A default base URL that is specific to the locale
  62.  *
  63.  * Locale    Endpoint
  64.  * ----------------------------------------------
  65.  * CA        http://ecs.amazonaws.ca/onca/xml
  66.  *           https://aws.amazonaws.ca/onca/xml
  67.  * DE        http://ecs.amazonaws.de/onca/xml
  68.  *           https://aws.amazonaws.de/onca/xml
  69.  * FR        http://ecs.amazonaws.fr/onca/xml
  70.  *           https://aws.amazonaws.fr/onca/xml
  71.  * JP        http://ecs.amazonaws.jp/onca/xml
  72.  *           https://aws.amazonaws.jp/onca/xml
  73.  * UK        http://ecs.amazonaws.co.uk/onca/xml
  74.  *           https://aws.amazonaws.co.uk/onca/xml
  75.  * US        http://ecs.amazonaws.com/onca/xml
  76.  *           https://aws.amazonaws.com/onca/xml
  77.  */
  78. if (!defined('SERVICES_AMAZON_BASEURL')) {
  79.     define('SERVICES_AMAZON_BASEURL''http://ecs.amazonaws.com/onca/xml');
  80. }
  81.  
  82. /**
  83.  * An API version
  84.  *
  85.  * Use this to retrieve a particular version of the Product Advertising API.
  86.  */
  87. if (!defined('SERVICES_AMAZON_ECSVERSION')) {
  88.     define('SERVICES_AMAZON_ECSVERSION''2011-08-01');
  89. }
  90.  
  91. /**
  92.  * Class for accessing and retrieving information from Amazon's Web Services
  93.  *
  94.  * @package Services_Amazon
  95.  * @author  John Downey <jdowney@gmail.com>
  96.  * @author  Tatsuya Tsuruoka <tatsuya.tsuruoka@gmail.com>
  97.  * @access  public
  98.  * @version Release: 0.9.0
  99.  * @uses    PEAR
  100.  * @uses    HTTP_Request
  101.  * @uses    XML_Unserializer
  102.  */
  103. {
  104.     /**
  105.      * An Amazon Access Key ID used when quering Amazon servers
  106.      *
  107.      * @access private
  108.      * @var    string 
  109.      */
  110.     var $_access_key_id = null;
  111.  
  112.     /**
  113.      * An Amazon Secret Access Key used when quering Amazon servers
  114.      *
  115.      * @access private
  116.      * @var    string 
  117.      */
  118.     var $_secret_access_key = null;
  119.  
  120.     /**
  121.      * An Amazon Associate Tag used in the URL's so a commision may be payed
  122.      *
  123.      * @access private
  124.      * @var    string 
  125.      */
  126.     var $_associate_tag = null;
  127.  
  128.     /**
  129.      * A base URL used to build the query for the Amazon servers
  130.      *
  131.      * @access private
  132.      * @var    string 
  133.      */
  134.     var $_baseurl = SERVICES_AMAZON_BASEURL;
  135.  
  136.     /**
  137.      * A service version
  138.      *
  139.      * @access private
  140.      * @var    string 
  141.      */
  142.     var $_version = SERVICES_AMAZON_ECSVERSION;
  143.  
  144.     /**
  145.      * The time that the Amazon took to process the request
  146.      * 
  147.      * @access private
  148.      * @var    string 
  149.      */
  150.     var $_processing_time = null;
  151.  
  152.     /**
  153.      * The last URL accessed to the Amazon (for debugging)
  154.      *
  155.      * @access private
  156.      * @var    string 
  157.      */
  158.     var $_lasturl = null;
  159.  
  160.     /**
  161.      * The raw result returned from the request
  162.      *
  163.      * @access private
  164.      * @var    string 
  165.      */
  166.     var $_raw_result = null;
  167.  
  168.     /**
  169.      * The cache object
  170.      *
  171.      * @access private
  172.      * @var    object 
  173.      */
  174.     var $_cache = null;
  175.  
  176.     /**
  177.      * The cache expire time
  178.      *
  179.      * Defaults to one hour.
  180.      *
  181.      * @access private
  182.      * @var    integer 
  183.      */
  184.     var $_cache_expire = 3600;
  185.  
  186.     /**
  187.      * Proxy server
  188.      *
  189.      * @access private
  190.      * @var    string 
  191.      */
  192.     var $_proxy_host = null;
  193.  
  194.     /**
  195.      * Proxy port
  196.      *
  197.      * @access private
  198.      * @var    integer 
  199.      */
  200.     var $_proxy_port = null;
  201.  
  202.     /**
  203.      * Proxy username
  204.      *
  205.      * @access private
  206.      * @var    string 
  207.      */
  208.     var $_proxy_user = null;
  209.  
  210.     /**
  211.      * Proxy password
  212.      *
  213.      * @access private
  214.      * @var    string 
  215.      */
  216.     var $_proxy_pass = null;
  217.  
  218.     /**
  219.      * Timestamp (for debugging)
  220.      *
  221.      * @access private
  222.      * @var    integer 
  223.      */
  224.     var $_timestamp = null;
  225.  
  226.     /**
  227.      * Errors
  228.      *
  229.      * @access private
  230.      * @var    array 
  231.      */
  232.     var $_errors = array();
  233.  
  234.     /**
  235.      * Constructor
  236.      *
  237.      * @access public
  238.      * @param  string $access_key_id An Amazon Access Key ID used when quering Amazon servers
  239.      * @param  string $secret_access_key An Amazon Secret Access Key used when quering Amazon servers
  240.      * @param  string $associate_tag An Amazon Associate Tag used in the URL's so a commision may be payed
  241.      * @see    setAccessKeyID
  242.      * @see    setSecretAccessKey
  243.      * @see    setAssociateTag
  244.      * @see    setBaseUrl
  245.      * @see    setVersion
  246.      */
  247.     function Services_Amazon($access_key_id$secret_access_key$associate_tag = null)
  248.     {
  249.         $this->setAccessKeyID($access_key_id);
  250.         $this->setSecretAccessKey($secret_access_key);
  251.         $this->setAssociateTag($associate_tag);
  252.     }
  253.  
  254.     /**
  255.      * Retrieves the current version of this classes API
  256.      *
  257.      * @access public
  258.      * @static
  259.      * @return string The API version
  260.      */
  261.     function getApiVersion()
  262.     {
  263.         return '0.9.0';
  264.     }
  265.  
  266.     /**
  267.      * Sets an Access Key ID
  268.      *
  269.      * @access public
  270.      * @param  string $access_key_id An Access Key ID
  271.      * @return void 
  272.      */
  273.     function setAccessKeyID($access_key_id)
  274.     {
  275.         $this->_access_key_id $access_key_id;
  276.     }
  277.  
  278.     /**
  279.      * Sets a Subscription ID (for backward compatibility)
  280.      *
  281.      * @access public
  282.      * @param  string $subid A Subscription ID
  283.      * @return void 
  284.      */
  285.     function setSubscriptionID($subid)
  286.     {
  287.         $this->setAccessKeyID($subid);
  288.     }
  289.  
  290.     /**
  291.      * Sets a Secret Access Key
  292.      *
  293.      * @access public
  294.      * @param  string $subid A Secret Access Key
  295.      * @return void 
  296.      */
  297.     function setSecretAccessKey($secret_access_key)
  298.     {
  299.         $this->_secret_access_key $secret_access_key;
  300.     }
  301.  
  302.     /**
  303.      * Sets an Associate Tag
  304.      *
  305.      * @access public
  306.      * @param  string $associate_tag An Associate Tag
  307.      * @return void 
  308.      */
  309.     function setAssociateTag($associate_tag)
  310.     {
  311.         $this->_associate_tag $associate_tag;
  312.     }
  313.     /**
  314.      * Sets an Associate ID
  315.      *
  316.      * @access public
  317.      * @param  string $associd An Associate ID
  318.      * @return void 
  319.      */
  320.     function setAssociateID($associd)
  321.     {
  322.         $this->setAssociateTag($associd);
  323.     }
  324.  
  325.     /**
  326.      * Sets the base URL
  327.      *
  328.      * @access public
  329.      * @param  string $url The base url
  330.      * @return void 
  331.      */
  332.     function setBaseUrl($url)
  333.     {
  334.         $this->_baseurl $url;
  335.     }
  336.  
  337.     /**
  338.      * Sets the locale passed when making a query to Amazon
  339.      *
  340.      * Currently US, UK, DE, JP, FR, and CA are supported
  341.      *
  342.      * @access public
  343.      * @param  string $locale The new locale to use
  344.      * @return mixed A PEAR_Error on error, a true on success
  345.      */
  346.     function setLocale($locale)
  347.     {
  348.         $urls = array(
  349.             'US' => 'http://ecs.amazonaws.com/onca/xml',
  350.             'UK' => 'http://ecs.amazonaws.co.uk/onca/xml',
  351.             'DE' => 'http://ecs.amazonaws.de/onca/xml',
  352.             'JP' => 'http://ecs.amazonaws.jp/onca/xml',
  353.             'FR' => 'http://ecs.amazonaws.fr/onca/xml',
  354.             'CA' => 'http://ecs.amazonaws.ca/onca/xml',
  355.         );
  356.         $locale strtoupper($locale);
  357.         if (empty($urls[$locale])) {
  358.             return PEAR::raiseError('Invalid locale');
  359.         }
  360.         $this->setBaseUrl($urls[$locale]);
  361.         return true;
  362.     }
  363.  
  364.     /**
  365.      * Sets a version
  366.      *
  367.      * @access public
  368.      * @param  string $version A service version
  369.      * @return void 
  370.      */
  371.     function setVersion($version)
  372.     {
  373.         $this->_version $version;
  374.     }
  375.  
  376.     /**
  377.      * Enables caching the data
  378.      *
  379.      * Requires Cache to be installed.
  380.      * Example:
  381.      * <code>
  382.      * <?php
  383.      * $amazon = new Services_Amazon('[your Access Key ID here]', '[your Secret Access key here]');
  384.      * $amazon->setCache('file', array('cache_dir' => 'cache/'));
  385.      * $amazon->setCacheExpire(86400); // 86400 seconds = 24 hours
  386.      * $result = $amazon->BrowseNodeLookup('283155');
  387.      * ?>
  388.      * </code>
  389.      *
  390.      * @access public
  391.      * @param  string $container Name of container class
  392.      * @param  array $container_options Array with container class options
  393.      * @return mixed A PEAR_Error on error, a true on success
  394.      * @see    setCacheExpire()
  395.      */
  396.     function setCache($container 'file'$container_options = array())
  397.     {
  398.         if(!class_exists('Cache')){
  399.             @include_once 'Cache.php';
  400.         }
  401.         
  402.         @$cache = new Cache($container$container_options);
  403.         
  404.         if (is_object($cache)) {
  405.             $this->_cache $cache;
  406.         else {
  407.             $this->_cache = null;
  408.             return PEAR::raiseError('Cache init failed');
  409.         }
  410.  
  411.         return true;
  412.     }
  413.     
  414.     /**
  415.      * Sets cache expire time
  416.      * 
  417.      * Amazon dictates that any prices that are displayed that may be over an
  418.      * hour old should be accompanied by some sort of timestamp. You can get
  419.      * around that by expiring any queries that use the time in an hour (3600
  420.      * seconds).
  421.      *
  422.      * @access public
  423.      * @param  integer $secs Expire time in seconds
  424.      * @return void 
  425.      * @see    setCache()
  426.      */
  427.     function setCacheExpire($secs)
  428.     {
  429.         $this->_cache_expire $secs;
  430.     }
  431.  
  432.     /**
  433.      * Sets a proxy
  434.      *
  435.      * @access public
  436.      * @param string $host Proxy host
  437.      * @param int $port Proxy port
  438.      * @param string $user Proxy username
  439.      * @param string $pass Proxy password
  440.      */
  441.     function setProxy($host$port = 8080$user = null$pass = null)
  442.     {
  443.         $this->_proxy_host $host;
  444.         $this->_proxy_port $port;
  445.         $this->_proxy_user $user;
  446.         $this->_proxy_pass $pass;
  447.     }
  448.  
  449.     /**
  450.      * Sets a timestamp (for debugging)
  451.      *
  452.      * @access public
  453.      * @param integer $time A timestamp
  454.      */
  455.     function setTimestamp($time)
  456.     {
  457.         $this->_timestamp $time;
  458.     }
  459.  
  460.     /**
  461.      * Retrieves all error codes and messages
  462.      *
  463.      * <code>
  464.      * if (PEAR::isError($result)) {
  465.      *     foreach ($amazon->getErrors() as $error) {
  466.      *         echo $error['Code'];
  467.      *         echo $error['Message'];
  468.      *     }
  469.      * }
  470.      * </code>
  471.      *
  472.      * @access public
  473.      * @return array All errors
  474.      */
  475.     function getErrors()
  476.     {
  477.         return $this->_errors;
  478.     }
  479.     
  480.     /**
  481.      * Retrieves the error code and message
  482.      *
  483.      * <code>
  484.      * if (PEAR::isError($result)) {
  485.      *     $error = $amazon->getError();
  486.      *     echo $error['Code'];
  487.      *     echo $error['Message'];
  488.      * }
  489.      * </code>
  490.      *
  491.      * @access public
  492.      * @return array All errors
  493.      */
  494.     function getError()
  495.     {
  496.         return current($this->_errors);
  497.     }
  498.  
  499.     /**
  500.      * Retrieves the processing time
  501.      *
  502.      * @access public
  503.      * @return string Processing time
  504.      */
  505.     function getProcessingTime()
  506.     {
  507.         return $this->_processing_time;
  508.     }
  509.  
  510.     /**
  511.      * Retrieves the last URL accessed to the Amazon (for debugging)
  512.      *
  513.      * @access public
  514.      * @return string The Last URL
  515.      */
  516.     function getLastUrl()
  517.     {
  518.         return $this->_lasturl;
  519.     }
  520.  
  521.     /**
  522.       * Retrieves the raw result
  523.       *
  524.       * @access public
  525.       * @return string The raw result
  526.       */
  527.     function getRawResult()
  528.     {
  529.         return $this->_raw_result;
  530.     }
  531.  
  532.     /**
  533.      * Retrieves information about a browse node
  534.      *
  535.      * Example:
  536.      * <code>
  537.      * <?php
  538.      * $amazon = new Services_Amazon('[your Access Key ID here]', '[your Secret Access key here]');
  539.      * $result = $amazon->BrowseNodeLookup('283155'); // 283155='Books'
  540.      * ?>
  541.      * </code>
  542.      *
  543.      * @access public
  544.      * @param  string $browsenode_id The browse node ID
  545.      * @param  array $options The optional parameters
  546.      * @return array The array of information returned by the query
  547.      */
  548.     function BrowseNodeLookup($browsenode_id$options = array())
  549.     {
  550.         $params $options;
  551.         $params['Operation''BrowseNodeLookup';
  552.         $params['BrowseNodeId'$browsenode_id;
  553.         return $this->_sendRequest($params);
  554.     }
  555.  
  556.     /**
  557.      * Adds items to an existing remote shopping cart
  558.      *
  559.      * Example:
  560.      * <code>
  561.      * <?php
  562.      * $amazon = new Services_Amazon('[your Access Key ID here]', '[your Secret Access key here]');
  563.      * $item = array('ASIN' => 'aaaaaaaaaa', 'Quantity' => 1);
  564.      * // $item = array(array('ASIN' => 'aaaaaaaaaa', 'Quantity' => 1),
  565.      * //               array('OfferListingId' => 'bbbbbbbbbb', 'Quantity' => 10),
  566.      * //               array('ASIN' => 'cccccccccc', 'Quantity' => 20));
  567.      * $result = $amazon->CartAdd('[Cart ID]', '[HMAC]', $item);
  568.      * ?>
  569.      * </code>
  570.      *
  571.      * @access public
  572.      * @param  string $cart_id A unique identifier for a cart
  573.      * @param  string $hmac A unique security token
  574.      * @param  array $item Products and the quantities
  575.      * @param  array $options The optional parameters
  576.      * @return array The array of information returned by the query
  577.      * @see    CartClear(), CartCreate(), CartModify()
  578.      */
  579.     function CartAdd($cart_id$hmac$item$options = array())
  580.     {
  581.         $params $options;
  582.         $params['Operation''CartAdd';
  583.         $params['CartId'$cart_id;
  584.         $params['HMAC'$hmac;
  585.         $params += $this->_assembleItemParameter($item);
  586.         return $this->_sendRequest($params);
  587.     }
  588.  
  589.     /**
  590.      * Removes all the contents of a remote shopping cart
  591.      *
  592.      * @access public
  593.      * @param  string $cart_id A unique identifier for a cart
  594.      * @param  string $hmac A unique security token
  595.      * @param  array $options The optional parameters
  596.      * @return array The array of information returned by the query
  597.      * @see    CartAdd(), CartCreate(), CartGet(), CartModify()
  598.      */
  599.     function CartClear($cart_id$hmac$options = array())
  600.     {
  601.         $params $options;
  602.         $params['Operation''CartClear';
  603.         $params['CartId'$cart_id;
  604.         $params['HMAC'$hmac;
  605.         return $this->_sendRequest($params);
  606.     }
  607.  
  608.     /**
  609.      * Creates a new remote shopping cart
  610.      *
  611.      * Example:
  612.      * <code>
  613.      * <?php
  614.      * $amazon = new Services_Amazon('[your Access Key ID here]', '[your Secret Access key here]');
  615.      * $item = array('ASIN' => 'aaaaaaaaaa', 'Quantity' => 1);
  616.      * // $item = array(array('ASIN' => 'aaaaaaaaaa', 'Quantity' => 1),
  617.      * //               array('ASIN' => 'cccccccccc', 'Quantity' => 20));
  618.      * $result = $amazon->CartCreate($item);
  619.      * ?>
  620.      * </code>
  621.      *
  622.      * @access public
  623.      * @param  array $item Products and the quantities
  624.      * @param  array $options The optional parameters
  625.      * @return array The array of information returned by the query
  626.      * @see    CartAdd(), CartClear(), CartGet(), CartModify()
  627.      */
  628.     function CartCreate($item$options = array())
  629.     {
  630.         $params $options;
  631.         $params['Operation''CartCreate';
  632.         $params += $this->_assembleItemParameter($item);
  633.         return $this->_sendRequest($params);
  634.     }
  635.  
  636.     /**
  637.      * Retrieves the contents of a remote shopping cart
  638.      *
  639.      * @access public
  640.      * @param  string $cart_id A unique identifier for a cart
  641.      * @param  string $hmac A unique security token
  642.      * @param  array $options The optional parameters
  643.      * @return array The array of information returned by the query
  644.      * @see    CartAdd(), CartClear(), CartCreate(), CartModify()
  645.      */
  646.     function CartGet($cart_id$hmac$options = array())
  647.     {
  648.         $params $options;
  649.         $params['Operation''CartGet';
  650.         $params['CartId'$cart_id;
  651.         $params['HMAC'$hmac;
  652.         return $this->_sendRequest($params);
  653.     }
  654.  
  655.     /**
  656.      * Modifies the quantity of items in a cart and changes cart items to saved items
  657.      *
  658.      * Example:
  659.      * <code>
  660.      * <?php
  661.      * $amazon = new Services_Amazon('[your Access Key ID here]', '[your Secret Access key here]');
  662.      * $item = array('CartItemId' => 'aaaaaaaaaa', 'Quantity' => 1);
  663.      * // $item = array('CartItemId' => 'aaaaaaaaaa', 'Action' => 'SaveForLater');
  664.      * // $item = array(array('CartItemId' => 'aaaaaaaaaa', 'Quantity' => 1),
  665.      * //               array('CartItemId' => 'cccccccccc', 'Quantity' => 20));
  666.      * $result = $amazon->CartModify('[Cart ID]', '[HMAC]', $item);
  667.      * ?>
  668.      * </code>
  669.      *
  670.      * @access public
  671.      * @param  string $cart_id A unique identifier for a cart
  672.      * @param  string $hmac A unique security token
  673.      * @param  array $item The CartItemId and the quantities or the Action
  674.      * @param  array $options The optional parameters
  675.      * @return array The array of information returned by the query
  676.      * @see    CartAdd(), CartClear(), CartCreate(), CartGet()
  677.      */
  678.     function CartModify($cart_id$hmac$item$options = array())
  679.     {
  680.         $params $options;
  681.         $params['Operation''CartModify';
  682.         $params['CartId'$cart_id;
  683.         $params['HMAC'$hmac;
  684.         $params += $this->_assembleItemParameter($item);
  685.         return $this->_sendRequest($params);
  686.     }
  687.  
  688.     /**
  689.      * Retrieves information for products
  690.      *
  691.      * Example:
  692.      * <code>
  693.      * <?php
  694.      * $amazon = new Services_Amazon('[your Access Key ID here]', '[your Secret Access key here]');
  695.      * $options = array();
  696.      * $options['ResponseGroup'] = 'Large';
  697.      * $result = $amazon->ItemLookup('[ASIN(s)]', $options);
  698.      * ?>
  699.      * </code>
  700.      *
  701.      * @access public
  702.      * @param  string $item_id Product IDs
  703.      * @param  array $options The optional parameters
  704.      * @return array The array of information returned by the query
  705.      * @see    ItemSearch()
  706.      */
  707.     function ItemLookup($item_id$options = array())
  708.     {
  709.         $params $options;
  710.         $params['Operation''ItemLookup';
  711.         if (is_array($item_id)) {
  712.             $item_id implode(','$item_id);
  713.         }
  714.         $params['ItemId'$item_id;
  715.         return $this->_sendRequest($params);
  716.     }
  717.  
  718.     /**
  719.      * Searches for products
  720.      *
  721.      * Example:
  722.      * <code>
  723.      * <?php
  724.      * $amazon = new Services_Amazon('[your Access Key ID here]', '[your Secret Access key here]');
  725.      * $options = array();
  726.      * $options['Keywords'] = 'sushi';
  727.      * $options['Sort'] = 'salesrank';
  728.      * $options['ResponseGroup'] = 'ItemIds,ItemAttributes,Images';
  729.      * $result = $amazon->ItemSearch('Books', $options);
  730.      * ?>
  731.      * </code>
  732.      *
  733.      * @access public
  734.      * @param  string $search_index A search index
  735.      * @param  array $options The optional parameters
  736.      * @return array The array of information returned by the query
  737.      * @see    ItemLookup()
  738.      */
  739.     function ItemSearch($search_index$options = array())
  740.     {
  741.         $params $options;
  742.         $params['Operation''ItemSearch';
  743.         $params['SearchIndex'$search_index;
  744.         return $this->_sendRequest($params);
  745.     }
  746.  
  747.     /**
  748.      * Retrieves products that are similar to Amazon products
  749.      *
  750.      * @access public
  751.      * @param  string $item_id Product IDs
  752.      * @param  array $options The optional parameters
  753.      * @return array The array of information returned by the query
  754.      */
  755.     function SimilarityLookup($item_id$options = array())
  756.     {
  757.         $params $options;
  758.         $params['Operation''SimilarityLookup';
  759.         if (is_array($item_id)) {
  760.             $item_id implode(','$item_id);
  761.         }
  762.         $params['ItemId'$item_id;
  763.         return $this->_sendRequest($params);
  764.     }
  765.  
  766.     /**
  767.      * Combines requests for the same operation into a single request
  768.      *
  769.      * Example:
  770.      * <code>
  771.      * <?php
  772.      * $amazon = new Services_Amazon('[your Access Key ID here]', '[your Secret Access key here]');
  773.      * $shared = array('SearchIndex' => 'Books',
  774.      *                 'Keywords' => 'php');
  775.      * $params1 = array('ItemPage' => '1');
  776.      * $params2 = array('ItemPage' => '2');
  777.      * $result = $amazon->doBatch('ItemSearch', $shared, $params1, $params2);
  778.      * ?>
  779.      * </code>
  780.      *
  781.      * @access public
  782.      * @param  string $operation The operation
  783.      * @param  array $shared Shared parameters
  784.      * @param  array $params1 The parameters specific to the first request
  785.      * @param  array $params2 The parameters specific to the second request
  786.      * @return array The array of information returned by the query
  787.      */
  788.     function doBatch($operation$shared$params1 = array()$params2 = array())
  789.     {
  790.         $params = array();
  791.         $params['Operation'$operation;
  792.         foreach ($shared as $k => $v{
  793.             $params[$operation '.Shared.' $k$v;
  794.         }
  795.         foreach ($params1 as $k => $v{
  796.             $params[$operation '.1.' $k$v;
  797.         }
  798.         foreach ($params2 as $k => $v{
  799.             $params[$operation '.2.' $k$v;
  800.         }
  801.         return $this->_sendRequest($params);
  802.     }
  803.  
  804.     /**
  805.      * Assembles the Item parameters
  806.      *
  807.      * @access private
  808.      * @param  array $items The items
  809.      * @return array The item parameters
  810.      */
  811.     function _assembleItemParameter($items)
  812.     {
  813.         $params = array();
  814.         if (!is_array(current($items))) {
  815.             $items = array(0 => $items);
  816.         }
  817.         $i = 1;
  818.         foreach ($items as $item{
  819.             foreach ($item as $k => $v{
  820.                 $params['Item.' $i '.' $k$v;
  821.             }
  822.             $i++;
  823.         }
  824.         return $params;
  825.     }
  826.  
  827.     /**
  828.      * Ignores the caching of specific operations
  829.      *
  830.      * @access private
  831.      * @param  string $operation The operation
  832.      * @return bool Returns true if the operation isn't cached, false otherwise
  833.      */
  834.     function _ignoreCache($operation)
  835.     {
  836.         $ignore = array('CartAdd''CartClear''CartGet''CartModify');
  837.         if (!strchr($operation',')) {
  838.             return in_array($operation$ignore);
  839.         }
  840.         $operations explode(','$operation);
  841.         foreach ($operations as $v{
  842.             if (in_array($v$ignore)) {
  843.                 return true;
  844.             }
  845.         }
  846.         return false;
  847.     }
  848.  
  849.     /**
  850.      * Generates ID used as cache identifier
  851.      *
  852.      * @access private
  853.      * @param  array $params 
  854.      * @return string Cache ID
  855.      */
  856.     function _generateCacheId($params)
  857.     {
  858.         unset($params['AWSAccessKeyId']);
  859.         unset($params['AssociateTag']);
  860.         $str '';
  861.         foreach ($params as $k => $v{
  862.             $str .= $k $v;
  863.         }
  864.         return md5($str);
  865.     }
  866.  
  867.     /**
  868.      * Encode URL according to RFC 3986
  869.      *
  870.      * @access private
  871.      * @param string $str UTF-8 string
  872.      * @return string Encoded string
  873.      */
  874.     function _urlencode($str)
  875.     {
  876.         return str_replace('%7E''~'rawurlencode($str));
  877.     }
  878.  
  879.     /**
  880.      * Create an HMAC-SHA256
  881.      *
  882.      * @access private
  883.      * @param string $string_to_sign 
  884.      * @param string $secret_access_key 
  885.      * @return string hash
  886.      */
  887.     function _hash($string_to_sign$secret_access_key)
  888.     {
  889.         if (function_exists('hash_hmac')) {
  890.             return hash_hmac('sha256'$string_to_sign$secret_access_keytrue);
  891.         elseif (function_exists('mhash')) {
  892.             return mhash(MHASH_SHA256$string_to_sign$secret_access_key);
  893.         }
  894.  
  895.         return PEAR::raiseError('hash_hmac/mhash is required');
  896.     }
  897.  
  898.     /**
  899.      * Builds a URL
  900.      *
  901.      * @access private
  902.      * @param array $params 
  903.      * @return string URL
  904.      */
  905.     function _buildUrl($params)
  906.     {
  907.         $params['Service''AWSECommerceService';
  908.         $params['AWSAccessKeyId'$this->_access_key_id;
  909.         if (!empty($this->_associate_tag)) {
  910.             $params['AssociateTag'$this->_associate_tag;
  911.         }
  912.         $params['Version'$this->_version;
  913.         $params['Timestamp'gmdate('Y-m-d\TH:i:s\Z'is_null($this->_timestamptime($this->_timestamp);
  914.  
  915.         // sort parameters by byte value
  916.         ksort($params);
  917.  
  918.         // create a canonical string
  919.         $canonical_string '';
  920.         foreach ($params as $k => $v{
  921.             $canonical_string .= '&' $this->_urlencode($k'=' $this->_urlencode($v);
  922.         }
  923.         $canonical_string substr($canonical_string1);
  924.  
  925.         // create a signature for request
  926.         $parsed_url parse_url($this->_baseurl);
  927.         $string_to_sign = "GET\n{$parsed_url['host']}\n{$parsed_url['path']}\n{$canonical_string}";
  928.         $signature $this->_hash($string_to_sign$this->_secret_access_key);
  929.         if (PEAR::isError($signature)) {
  930.             return $signature;
  931.         }
  932.         $signature base64_encode($signature);
  933.  
  934.         // create a signed url
  935.         $url $this->_baseurl '?' $canonical_string '&Signature=' $this->_urlencode($signature);
  936.  
  937.         return $url;
  938.     }
  939.  
  940.     /**
  941.      * Sends a request
  942.      *
  943.      * @access private
  944.      * @param string $url 
  945.      * @return string The response
  946.      */
  947.     function _sendHttpRequest($url)
  948.     {
  949.         $http &new HTTP_Request($url);
  950.         $http->setHttpVer('1.0');
  951.         $http->addHeader('User-Agent''Services_Amazon/' $this->getApiVersion());
  952.         if ($this->_proxy_host{
  953.             $http->setProxy($this->_proxy_host$this->_proxy_port$this->_proxy_user$this->_proxy_pass);
  954.         }
  955.  
  956.         $result $http->sendRequest();
  957.         if (PEAR::isError($result)) {
  958.             return PEAR::raiseError('HTTP_Request::sendRequest failed: ' $result->message);
  959.         }
  960.  
  961.         if ($http->getResponseCode(!= 200){
  962.             return PEAR::raiseError('Amazon returned invalid HTTP response code ' $http->getResponseCode());
  963.         }
  964.         return $http->getResponseBody();
  965.     }
  966.  
  967.     /**
  968.      * Parses raw XML result
  969.      *
  970.      * @access private
  971.      * @param string $raw_result 
  972.      * @return string The contents
  973.      */
  974.     function _parseRawResult($raw_result)
  975.     {
  976.         $xml &new XML_Unserializer();
  977.         $xml->setOption(XML_UNSERIALIZER_OPTION_ATTRIBUTES_PARSEtrue);
  978.         $xml->setOption(XML_UNSERIALIZER_OPTION_FORCE_ENUM,
  979.                         array('Item''Review''EditorialReview',
  980.                               'Parameter''Author''Creator''ResponseGroup''Error'));
  981.         $xml->unserialize($raw_resultfalse);
  982.         $data $xml->getUnserializedData();
  983.         if (PEAR::isError($data)) {
  984.             return $data;
  985.         }
  986.  
  987.         if (isset($data['Error'])) {
  988.             $this->_errors $data['Error'];
  989.             return PEAR::raiseError(implode(':'$this->getError()));
  990.         }
  991.  
  992.         if (isset($data['OperationRequest']['RequestProcessingTime'])) {
  993.             $this->_processing_time $data['OperationRequest']['RequestProcessingTime'];
  994.         }
  995.  
  996.         if (isset($data['OperationRequest']['Errors'])) {
  997.             $this->_errors $data['OperationRequest']['Errors']['Error'];
  998.             return PEAR::raiseError(implode(':'$this->getError()));
  999.         }
  1000.  
  1001.         // Get values of the second level content elements
  1002.         unset($data['xmlns']);
  1003.         unset($data['OperationRequest']);
  1004.         $contents = array();
  1005.         $keys array_keys($data);
  1006.         foreach ($keys as $v{
  1007.             if (strstr($v'Response')) {
  1008.                 $data[$vcurrent($data[$v]);
  1009.                 $contents[$v$data[$v];
  1010.             else {
  1011.                 $contents $data[$v];
  1012.             }
  1013.             $result $this->_checkContentError($data[$v]);
  1014.             if (PEAR::isError($result)) {
  1015.                 return $result;
  1016.             }
  1017.         }
  1018.         return $contents;
  1019.     }
  1020.  
  1021.     /**
  1022.      * Checks error codes at the content elements
  1023.      *
  1024.      * @access private
  1025.      * @param  array $content Values of the content elements
  1026.      * @return array mixed A PEAR_Error on error, a true on success
  1027.      * @see    _parseRawResult
  1028.      */
  1029.     function _checkContentError($content)
  1030.     {
  1031.         if (isset($content['Request']['Errors'])) {
  1032.             $this->_errors $content['Request']['Errors']['Error'];
  1033.             return PEAR::raiseError(implode(':'$this->getError()));
  1034.         else if (isset($content[0])) {
  1035.             $errors = array();
  1036.             foreach ($content as $v{
  1037.                 if (isset($v['Request']['Errors']['Error'])) {
  1038.                     $errors array_merge($errors$v['Request']['Errors']['Error']);
  1039.                 }
  1040.             }
  1041.             if (!empty($errors)) {
  1042.                 $this->_errors $errors;
  1043.                 return PEAR::raiseError(implode(':'$this->getError()));
  1044.             }
  1045.         }
  1046.         return true;
  1047.     }
  1048.  
  1049.     /**
  1050.      * Sends the request to Amazon
  1051.      *
  1052.      * @access private
  1053.      * @param  array $params The array of request parameters
  1054.      * @return array The array of information returned by the query
  1055.      */
  1056.     function _sendRequest($params)
  1057.     {
  1058.         $this->_errors = array();
  1059.  
  1060.         if (is_null($this->_access_key_id)) {
  1061.             return PEAR::raiseError('Access Key ID have not been set');
  1062.         }
  1063.  
  1064.         $url $this->_buildUrl($params);
  1065.         $this->_lasturl $url;
  1066.         if (PEAR::isError($url)) {
  1067.             return $url;
  1068.         }
  1069.  
  1070.         // Return cached data if available
  1071.         $cache_id = false;
  1072.         if (isset($this->_cache&& !$this->_ignoreCache($params['Operation'])) {
  1073.             $cache_id $this->_generateCacheId($params);
  1074.             $cache $this->_cache->get($cache_id);
  1075.             if (!is_null($cache)) {
  1076.                 $this->_processing_time = 0;
  1077.                 return $cache;
  1078.             }
  1079.         }
  1080.  
  1081.         $result $this->_sendHttpRequest($url);
  1082.         $this->_raw_result $result;
  1083.         if (PEAR::isError($result)) {
  1084.             return $result;
  1085.         }
  1086.  
  1087.         $contents $this->_parseRawResult($result);
  1088.         if (PEAR::isError($contents)) {
  1089.             return $contents;
  1090.         }
  1091.  
  1092.         if ($cache_id{
  1093.             $this->_cache->save($cache_id$contents$this->_cache_expire);
  1094.         }
  1095.  
  1096.         return $contents;
  1097.     }
  1098.  
  1099. }
  1100. ?>

Documentation generated on Mon, 11 Mar 2019 15:46:56 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.