home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / Services / AmazonECS4.php < prev    next >
Encoding:
PHP Script  |  2008-07-02  |  34.8 KB  |  1,212 lines

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