File indexing completed on 2024-12-22 05:37:06
0001 <?php 0002 0003 /** 0004 * Zend Framework 0005 * 0006 * LICENSE 0007 * 0008 * This source file is subject to the new BSD license that is bundled 0009 * with this package in the file LICENSE.txt. 0010 * It is also available through the world-wide-web at this URL: 0011 * http://framework.zend.com/license/new-bsd 0012 * If you did not receive a copy of the license and are unable to 0013 * obtain it through the world-wide-web, please send an email 0014 * to license@zend.com so we can send you a copy immediately. 0015 * 0016 * @category Zend 0017 * @package Zend_Service 0018 * @subpackage Amazon 0019 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0020 * @license http://framework.zend.com/license/new-bsd New BSD License 0021 * @version $Id$ 0022 */ 0023 0024 /** 0025 * @see Zend_Rest_Client 0026 */ 0027 // require_once 'Zend/Rest/Client.php'; 0028 0029 /** @see Zend_Xml_Security */ 0030 // require_once 'Zend/Xml/Security.php'; 0031 0032 /** 0033 * @category Zend 0034 * @package Zend_Service 0035 * @subpackage Amazon 0036 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0037 * @license http://framework.zend.com/license/new-bsd New BSD License 0038 */ 0039 class Zend_Service_Amazon 0040 { 0041 /** 0042 * Amazon Web Services Access Key ID 0043 * 0044 * @var string 0045 */ 0046 public $appId; 0047 0048 /** 0049 * @var string 0050 */ 0051 protected $_secretKey = null; 0052 0053 /** 0054 * @var string 0055 */ 0056 protected $_baseUri = null; 0057 0058 /** 0059 * List of Amazon Web Service base URLs, indexed by country code 0060 * 0061 * @var array 0062 */ 0063 protected $_baseUriList = array('US' => 'http://webservices.amazon.com', 0064 'UK' => 'http://webservices.amazon.co.uk', 0065 'DE' => 'http://webservices.amazon.de', 0066 'JP' => 'http://webservices.amazon.co.jp', 0067 'FR' => 'http://webservices.amazon.fr', 0068 'CA' => 'http://webservices.amazon.ca'); 0069 0070 /** 0071 * Reference to REST client object 0072 * 0073 * @var Zend_Rest_Client 0074 */ 0075 protected $_rest = null; 0076 0077 0078 /** 0079 * Constructs a new Amazon Web Services Client 0080 * 0081 * @param string $appId Developer's Amazon appid 0082 * @param string $countryCode Country code for Amazon service; may be US, UK, DE, JP, FR, CA 0083 * @throws Zend_Service_Exception 0084 * @return Zend_Service_Amazon 0085 */ 0086 public function __construct($appId, $countryCode = 'US', $secretKey = null) 0087 { 0088 $this->appId = (string) $appId; 0089 $this->_secretKey = $secretKey; 0090 0091 $countryCode = (string) $countryCode; 0092 if (!isset($this->_baseUriList[$countryCode])) { 0093 /** 0094 * @see Zend_Service_Exception 0095 */ 0096 // require_once 'Zend/Service/Exception.php'; 0097 throw new Zend_Service_Exception("Unknown country code: $countryCode"); 0098 } 0099 0100 $this->_baseUri = $this->_baseUriList[$countryCode]; 0101 } 0102 0103 0104 /** 0105 * Search for Items 0106 * 0107 * @param array $options Options to use for the Search Query 0108 * @throws Zend_Service_Exception 0109 * @return Zend_Service_Amazon_ResultSet 0110 * @see http://www.amazon.com/gp/aws/sdk/main.html/102-9041115-9057709?s=AWSEcommerceService&v=2011-08-01&p=ApiReference/ItemSearchOperation 0111 */ 0112 public function itemSearch(array $options) 0113 { 0114 $client = $this->getRestClient(); 0115 $client->setUri($this->_baseUri); 0116 0117 $defaultOptions = array('ResponseGroup' => 'Small'); 0118 $options = $this->_prepareOptions('ItemSearch', $options, $defaultOptions); 0119 $client->getHttpClient()->resetParameters(); 0120 $response = $client->restGet('/onca/xml', $options); 0121 0122 if ($response->isError()) { 0123 /** 0124 * @see Zend_Service_Exception 0125 */ 0126 // require_once 'Zend/Service/Exception.php'; 0127 throw new Zend_Service_Exception('An error occurred sending request. Status code: ' 0128 . $response->getStatus()); 0129 } 0130 0131 $dom = new DOMDocument(); 0132 $dom = Zend_Xml_Security::scan($response->getBody(), $dom); 0133 self::_checkErrors($dom); 0134 0135 /** 0136 * @see Zend_Service_Amazon_ResultSet 0137 */ 0138 // require_once 'Zend/Service/Amazon/ResultSet.php'; 0139 return new Zend_Service_Amazon_ResultSet($dom); 0140 } 0141 0142 0143 /** 0144 * Look up item(s) by ASIN 0145 * 0146 * @param string $asin Amazon ASIN ID 0147 * @param array $options Query Options 0148 * @see http://www.amazon.com/gp/aws/sdk/main.html/102-9041115-9057709?s=AWSEcommerceService&v=2011-08-01&p=ApiReference/ItemLookupOperation 0149 * @throws Zend_Service_Exception 0150 * @return Zend_Service_Amazon_Item|Zend_Service_Amazon_ResultSet 0151 */ 0152 public function itemLookup($asin, array $options = array()) 0153 { 0154 $client = $this->getRestClient(); 0155 $client->setUri($this->_baseUri); 0156 $client->getHttpClient()->resetParameters(); 0157 0158 $defaultOptions = array('ResponseGroup' => 'Small'); 0159 $options['ItemId'] = (string) $asin; 0160 $options = $this->_prepareOptions('ItemLookup', $options, $defaultOptions); 0161 $response = $client->restGet('/onca/xml', $options); 0162 0163 if ($response->isError()) { 0164 /** 0165 * @see Zend_Service_Exception 0166 */ 0167 // require_once 'Zend/Service/Exception.php'; 0168 throw new Zend_Service_Exception( 0169 'An error occurred sending request. Status code: ' . $response->getStatus() 0170 ); 0171 } 0172 0173 $dom = new DOMDocument(); 0174 $dom = Zend_Xml_Security::scan($response->getBody(), $dom); 0175 self::_checkErrors($dom); 0176 $xpath = new DOMXPath($dom); 0177 $xpath->registerNamespace('az', 'http://webservices.amazon.com/AWSECommerceService/2011-08-01'); 0178 $items = $xpath->query('//az:Items/az:Item'); 0179 0180 if ($items->length == 1) { 0181 /** 0182 * @see Zend_Service_Amazon_Item 0183 */ 0184 // require_once 'Zend/Service/Amazon/Item.php'; 0185 return new Zend_Service_Amazon_Item($items->item(0)); 0186 } 0187 0188 /** 0189 * @see Zend_Service_Amazon_ResultSet 0190 */ 0191 // require_once 'Zend/Service/Amazon/ResultSet.php'; 0192 return new Zend_Service_Amazon_ResultSet($dom); 0193 } 0194 0195 0196 /** 0197 * Returns a reference to the REST client 0198 * 0199 * @return Zend_Rest_Client 0200 */ 0201 public function getRestClient() 0202 { 0203 if($this->_rest === null) { 0204 $this->_rest = new Zend_Rest_Client(); 0205 } 0206 return $this->_rest; 0207 } 0208 0209 /** 0210 * Set REST client 0211 * 0212 * @param Zend_Rest_Client 0213 * @return Zend_Service_Amazon 0214 */ 0215 public function setRestClient(Zend_Rest_Client $client) 0216 { 0217 $this->_rest = $client; 0218 return $this; 0219 } 0220 0221 0222 /** 0223 * Prepare options for request 0224 * 0225 * @param string $query Action to perform 0226 * @param array $options User supplied options 0227 * @param array $defaultOptions Default options 0228 * @return array 0229 */ 0230 protected function _prepareOptions($query, array $options, array $defaultOptions) 0231 { 0232 $options['AWSAccessKeyId'] = $this->appId; 0233 $options['Service'] = 'AWSECommerceService'; 0234 $options['Operation'] = (string) $query; 0235 $options['Version'] = '2011-08-01'; 0236 0237 // de-canonicalize out sort key 0238 if (isset($options['ResponseGroup'])) { 0239 $responseGroup = explode(',', $options['ResponseGroup']); 0240 0241 if (!in_array('Request', $responseGroup)) { 0242 $responseGroup[] = 'Request'; 0243 $options['ResponseGroup'] = implode(',', $responseGroup); 0244 } 0245 } 0246 0247 $options = array_merge($defaultOptions, $options); 0248 0249 if($this->_secretKey !== null) { 0250 $options['Timestamp'] = gmdate("Y-m-d\TH:i:s\Z");; 0251 ksort($options); 0252 $options['Signature'] = self::computeSignature($this->_baseUri, $this->_secretKey, $options); 0253 } 0254 0255 return $options; 0256 } 0257 0258 /** 0259 * Compute Signature for Authentication with Amazon Product Advertising Webservices 0260 * 0261 * @param string $baseUri 0262 * @param string $secretKey 0263 * @param array $options 0264 * @return string 0265 */ 0266 static public function computeSignature($baseUri, $secretKey, array $options) 0267 { 0268 // require_once "Zend/Crypt/Hmac.php"; 0269 0270 $signature = self::buildRawSignature($baseUri, $options); 0271 return base64_encode( 0272 Zend_Crypt_Hmac::compute($secretKey, 'sha256', $signature, Zend_Crypt_Hmac::BINARY) 0273 ); 0274 } 0275 0276 /** 0277 * Build the Raw Signature Text 0278 * 0279 * @param string $baseUri 0280 * @param array $options 0281 * @return string 0282 */ 0283 static public function buildRawSignature($baseUri, $options) 0284 { 0285 ksort($options); 0286 $params = array(); 0287 foreach($options AS $k => $v) { 0288 $params[] = $k."=".rawurlencode($v); 0289 } 0290 0291 return sprintf("GET\n%s\n/onca/xml\n%s", 0292 str_replace('http://', '', $baseUri), 0293 implode("&", $params) 0294 ); 0295 } 0296 0297 0298 /** 0299 * Check result for errors 0300 * 0301 * @param DOMDocument $dom 0302 * @throws Zend_Service_Exception 0303 * @return void 0304 */ 0305 protected static function _checkErrors(DOMDocument $dom) 0306 { 0307 $xpath = new DOMXPath($dom); 0308 $xpath->registerNamespace('az', 'http://webservices.amazon.com/AWSECommerceService/2011-08-01'); 0309 0310 if ($xpath->query('//az:Error')->length >= 1) { 0311 $code = $xpath->query('//az:Error/az:Code/text()')->item(0)->data; 0312 $message = $xpath->query('//az:Error/az:Message/text()')->item(0)->data; 0313 0314 switch($code) { 0315 case 'AWS.ECommerceService.NoExactMatches': 0316 break; 0317 default: 0318 /** 0319 * @see Zend_Service_Exception 0320 */ 0321 // require_once 'Zend/Service/Exception.php'; 0322 throw new Zend_Service_Exception("$message ($code)"); 0323 } 0324 } 0325 } 0326 }