PageRenderTime 55ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/models/datasources/amazon_associates_source.php

https://github.com/radig/datasources
PHP | 216 lines | 85 code | 19 blank | 112 comment | 4 complexity | fcf21052eb804ecfb5d8ab7c801b3f68 MD5 | raw file
  1. <?php
  2. /**
  3. * Amazon Associates API Datasource
  4. *
  5. * PHP versions 4 and 5
  6. *
  7. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  8. * Copyright 2005-2009, Cake Software Foundation, Inc. (http://cakefoundation.org)
  9. *
  10. * Licensed under The MIT License
  11. * Redistributions of files must retain the above copyright notice.
  12. *
  13. * @copyright Copyright 2005-2009, Cake Software Foundation, Inc. (http://cakefoundation.org)
  14. * @link http://cakephp.org CakePHP(tm) Project
  15. * @package datasources
  16. * @subpackage datasources.models.datasources
  17. * @since CakePHP Datasources v 0.3
  18. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  19. *
  20. * A CakePHP datasource for interacting with the amazon associates API.
  21. *
  22. * Create a datasource in your config/database.php
  23. * public $amazon = array(
  24. * 'datasource' => 'Datasources.AmazonAssociatesSource',
  25. * 'key' => 'PUBLIC KEY',
  26. * 'secret' => 'SECRET KEY',
  27. * 'tag' => 'YOUR ASSOCIATE ID',
  28. * 'locale' => 'com' //(ca,com,co,uk,de,fr,jp)
  29. * );
  30. */
  31. /**
  32. * Import XML, required library
  33. *
  34. */
  35. App::import('Xml');
  36. /**
  37. * Amazon Associates Datasource
  38. *
  39. * @package datasources
  40. * @subpackage datasources.models.datasources
  41. */
  42. class AmazonAssociatesSource extends DataSource {
  43. /**
  44. * Description of datasource
  45. *
  46. * @var string
  47. */
  48. public $description = 'AmazonAssociates Data Source';
  49. /**
  50. * Region / Locale
  51. * (ca,com,co,ul,de.fr,jp)
  52. *
  53. * @var string
  54. */
  55. public $region = 'com';
  56. /**
  57. * Query array
  58. *
  59. * @var array
  60. */
  61. public $query = null;
  62. /**
  63. * Signed request string to pass to Amazon
  64. *
  65. * @var string
  66. */
  67. protected $_request = null;
  68. /**
  69. * HttpSocket object
  70. *
  71. * @var HttpSocket
  72. */
  73. public $Http = null;
  74. /**
  75. * Request Logs
  76. *
  77. * @var array
  78. */
  79. private $__requestLog = array();
  80. /**
  81. * Constructor
  82. *
  83. * Creates new HttpSocket
  84. *
  85. * @param array $config Configuration array
  86. */
  87. public function __construct($config) {
  88. parent::__construct($config);
  89. App::import('HttpSocket');
  90. $this->Http = new HttpSocket();
  91. }
  92. /**
  93. * Query the Amazon Database
  94. *
  95. * @param string $type (DVD, Book, Movie, etc...)
  96. * @param array $query (title search, etc...)
  97. * @return mixed array of the resulting request or false if unable to contact server
  98. */
  99. public function find($type = null, $query = array()) {
  100. if ($type) {
  101. $query['SearchIndex'] = $type;
  102. }
  103. if (!is_array($query)) {
  104. $query = array('Title' => $query);
  105. }
  106. foreach ($query as $key => $val) {
  107. if (preg_match('/^[a-z]/', $key)) {
  108. $query[Inflector::camelize($key)] = $val;
  109. unset($query[$key]);
  110. }
  111. }
  112. $this->query = array_merge(
  113. array(
  114. 'Service' => 'AWSECommerceService',
  115. 'AWSAccessKeyId' => $this->config['key'],
  116. 'Timestamp' => gmdate("Y-m-d\TH:i:s\Z"),
  117. 'AccociateTag' => $this->config['tag'],
  118. 'Operation' => 'ItemSearch',
  119. 'Version' => '2009-03-31',
  120. ),
  121. $query
  122. );
  123. return $this->__request();
  124. }
  125. /**
  126. * Find an item by it's ID
  127. *
  128. * @param string $id of amazon product
  129. * @return mixed array of the resulting request or false if unable to contact server
  130. */
  131. public function findById($id) {
  132. $this->query = array_merge(
  133. array(
  134. 'Service' => 'AWSECommerceService',
  135. 'AWSAccessKeyId' => $this->config['key'],
  136. 'Timestamp' => gmdate("Y-m-d\TH:i:s\Z"),
  137. 'AccociateTag' => $this->config['tag'],
  138. 'Version' => '2009-03-31',
  139. 'Operation' => 'ItemLookup',
  140. ),
  141. array('ItemId' => $id)
  142. );
  143. return $this->__request();
  144. }
  145. /**
  146. * Play nice with the DebugKit
  147. *
  148. * @param boolean sorted ignored
  149. * @param boolean clear will clear the log if set to true (default)
  150. * @return array of log requested
  151. */
  152. public function getLog($sorted = false, $clear = true) {
  153. $log = $this->__requestLog;
  154. if($clear){
  155. $this->__requestLog = array();
  156. }
  157. return array('log' => $log, 'count' => count($log), 'time' => 'Unknown');
  158. }
  159. /**
  160. * Perform the request to AWS
  161. *
  162. * @return mixed array of the resulting request or false if unable to contact server
  163. */
  164. private function __request() {
  165. $this->_request = $this->__signQuery();
  166. $this->__requestLog[] = $this->_request;
  167. $retval = $this->Http->get($this->_request);
  168. return Set::reverse(new Xml($retval));
  169. }
  170. /**
  171. * Sign a query using sha256.
  172. * This is a required step for the new Amazon API
  173. *
  174. * @return string request signed string.
  175. */
  176. private function __signQuery() {
  177. $method = 'GET';
  178. $host = 'ecs.amazonaws.' . $this->region;
  179. $uri = '/onca/xml';
  180. ksort($this->query);
  181. // create the canonicalized query
  182. $canonicalized_query = array();
  183. foreach ($this->query as $param=>$value) {
  184. $param = str_replace('%7E', '~', rawurlencode($param));
  185. $value = str_replace('%7E', '~', rawurlencode($value));
  186. $canonicalized_query[] = $param."=".$value;
  187. }
  188. $canonicalized_query = implode('&', $canonicalized_query);
  189. $string_to_sign = implode("\n", array($method, $host, $uri, $canonicalized_query));
  190. // calculate HMAC with SHA256 and base64-encoding
  191. $signature = base64_encode(hash_hmac("sha256", $string_to_sign, $this->config['secret'], true));
  192. // encode the signature for the request
  193. $signature = str_replace('%7E', '~', rawurlencode($signature));
  194. // create request
  195. return sprintf('http://%s%s?%s&signature=%s', $host, $uri, $canonicalized_query, $signature);
  196. }
  197. }