PageRenderTime 50ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/Phlickr/Request.php

https://bitbucket.org/haichau59/manga
PHP | 329 lines | 111 code | 21 blank | 197 comment | 10 complexity | 93d9e7cf377441e547f305bab2bc65eb MD5 | raw file
  1. <?php
  2. /**
  3. * @version $Id$
  4. * @author Andrew Morton <drewish@katherinehouse.com>
  5. * @license http://opensource.org/licenses/lgpl-license.php
  6. * GNU Lesser General Public License, Version 2.1
  7. * @package Phlickr
  8. */
  9. /**
  10. * Phlickr_Api includes the core classes.
  11. */
  12. require_once 'Phlickr/Api.php';
  13. /**
  14. * The Phlickr_Request executes a Flickr API method and returns a
  15. * Phlickr_Response object with the results.
  16. *
  17. * Sample usage:
  18. * <code>
  19. * <?php
  20. * include_once 'Phlickr/Api.php';
  21. * $api = new Phlickr_Api(FLICKR_API_KEY, FLICKR_API_SECRET, FLICKR_TOKEN);
  22. *
  23. * // create a request to search for photos tagged with person and happy
  24. * // from all users.
  25. * $request = $api->createRequest(
  26. * 'flickr.photos.search',
  27. * array(
  28. * 'tags' => 'person,happy',
  29. * 'tag_mode' => 'all',
  30. * 'user_id' => ''
  31. * )
  32. * );
  33. *
  34. * // use the photo list and photo list iterator to display the titles and urls
  35. * // of each of the photos.
  36. * $photolist = new Phlickr_PhotoList($request);
  37. * $iterator = new Phlickr_PhotoListIterator($photolist);
  38. * foreach ($iterator as $photos) {
  39. * foreach ($photos as $photo) {
  40. * print "Photo: {$photo->getTitle()}\n";
  41. * print "\t{$photo->buildImgUrl()}\n";
  42. * }
  43. * }
  44. * ?>
  45. * </code>
  46. *
  47. * This class is responsible for:
  48. * - Assembling the information needed to build a REST URL.
  49. * - Submitting an HTTP POST request.
  50. * - Creating a Phlickr_Response from the results of an HTTP request.
  51. * - Providing callers with the details of the HTTP request for debugging
  52. * purposes.
  53. *
  54. * @package Phlickr
  55. * @author Andrew Morton <drewish@katherinehouse.com>
  56. * @since 0.1.0
  57. */
  58. class Phlickr_Request {
  59. /**
  60. * Number of seconds to wait while connecting to the server.
  61. */
  62. const TIMEOUT_CONNECTION = 20;
  63. /**
  64. * Total number of seconds to wait for a request.
  65. */
  66. const TIMEOUT_TOTAL = 50;
  67. /**
  68. * Phlickr_API object
  69. *
  70. * @var object
  71. */
  72. public $_api = null;
  73. /**
  74. * Name of the method.
  75. *
  76. * @var string
  77. */
  78. private $_method = null;
  79. /**
  80. * Parameters used in the last request.
  81. *
  82. * @var array
  83. */
  84. private $_params = array();
  85. /**
  86. * Should an exception be thrown when an API call fails?
  87. *
  88. * @var boolean
  89. */
  90. private $_throwOnFail = true;
  91. /**
  92. * Constructor.
  93. *
  94. * See the {@link http://flickr.com/services/api/ Flickr API} for a complete
  95. * list of methods and parameters.
  96. *
  97. * @param object Phlickr_API $api
  98. * @param string $method The name of the method.
  99. * @param array $params Associative array of parameter name/value pairs.
  100. */
  101. public function __construct(Phlickr_Api $api, $method, $params = array())
  102. {
  103. $this->_api = $api;
  104. $this->_method = (string) $method;
  105. if (!is_null($params)) {
  106. $this->_params = $params;
  107. }
  108. }
  109. public function __toString()
  110. {
  111. return $this->buildUrl();
  112. }
  113. /**
  114. * Submit a POST request with to the specified URL with given parameters.
  115. *
  116. * @param string $url
  117. * @param array $params An optional array of parameter name/value
  118. * pairs to include in the POST.
  119. * @param integer $timeout The total number of seconds, including the
  120. * wait for the initial connection, wait for a request to complete.
  121. * @return string
  122. * @throws Phlickr_ConnectionException
  123. * @uses TIMEOUT_CONNECTION to determine how long to wait for a
  124. * for a connection.
  125. * @uses TIMEOUT_TOTAL to determine how long to wait for a request
  126. * to complete.
  127. * @uses set_time_limit() to ensure that PHP's script timer is five
  128. * seconds longer than the sum of $timeout and TIMEOUT_CONNECTION.
  129. */
  130. static function submitHttpPost($url, $postParams = null, $timeout = self::TIMEOUT_TOTAL)
  131. {
  132. $ch = curl_init();
  133. // set up the request
  134. curl_setopt($ch, CURLOPT_URL, $url);
  135. // make sure we submit this as a post
  136. curl_setopt($ch, CURLOPT_POST, true);
  137. if (isset($postParams)) {
  138. curl_setopt($ch, CURLOPT_POSTFIELDS, $postParams);
  139. }else{
  140. curl_setopt($ch, CURLOPT_POSTFIELDS, "");
  141. }
  142. // make sure problems are caught
  143. curl_setopt($ch, CURLOPT_FAILONERROR, 1);
  144. // return the output
  145. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  146. // set the timeouts
  147. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, self::TIMEOUT_CONNECTION);
  148. curl_setopt($ch, CURLOPT_TIMEOUT,$timeout);
  149. // set the PHP script's timeout to be greater than CURL's
  150. set_time_limit(self::TIMEOUT_CONNECTION + $timeout + 5);
  151. $result = curl_exec($ch);
  152. // check for errors
  153. if (0 == curl_errno($ch)) {
  154. curl_close($ch);
  155. return $result;
  156. } else {
  157. $ex = new Phlickr_ConnectionException(
  158. 'Request failed. ' . curl_error($ch), curl_errno($ch), $url);
  159. curl_close($ch);
  160. throw $ex;
  161. }
  162. }
  163. /**
  164. * Create a signed signature of the parameters.
  165. *
  166. * Return a parameter string that can be tacked onto the end of a URL.
  167. * Items will be sorted and an api_sig element will be on the end.
  168. *
  169. * @param string $secret
  170. * @param array $params
  171. * @return string
  172. * @since 0.2.3
  173. * @link http://flickr.com/services/api/auth.spec.html
  174. */
  175. static function signParams($secret, $params)
  176. {
  177. $signing = '';
  178. $values = array();
  179. ksort($params);
  180. foreach($params as $key => $value) {
  181. $signing .= $key . $value;
  182. $values[] = $key . '=' . urlencode($value);
  183. }
  184. $values[] = 'api_sig=' . md5($secret . $signing);
  185. return implode('&', $values);
  186. }
  187. /**
  188. * Return a reference to this Request's Phlickr_Api.
  189. *
  190. * @return object Phlickr_Api
  191. * @see __construct()
  192. */
  193. public function getApi()
  194. {
  195. return $this->_api;
  196. }
  197. /**
  198. * Return the name of the method
  199. *
  200. * @return string
  201. * @see __construct()
  202. */
  203. public function getMethod()
  204. {
  205. return $this->_method;
  206. }
  207. /**
  208. * Return the array of parameters.
  209. *
  210. * @return array
  211. * @see setParams()
  212. */
  213. public function &getParams()
  214. {
  215. return $this->_params;
  216. }
  217. /**
  218. * Assign parameters to the request.
  219. *
  220. * @param array $params Associative array of parameter name/value pairs
  221. * @return void
  222. * @see __construct, getParams()
  223. */
  224. public function setParams($params)
  225. {
  226. if (is_null($params)) {
  227. $this->_params = array();
  228. } else {
  229. $this->_params = $params;
  230. }
  231. }
  232. /**
  233. * Return true if an exception will be thrown if the API returns a fail
  234. * for the request.
  235. *
  236. * @return boolean
  237. * @see setExceptionThrownOnFailure()
  238. */
  239. public function isExceptionThrownOnFailure()
  240. {
  241. return $this->_throwOnFail;
  242. }
  243. /**
  244. * Set an exception will be thrown if the API returns a fail for the
  245. * request.
  246. *
  247. * @param boolean $throwOnFail
  248. * @return void
  249. * @see isExceptionThrownOnFailure()
  250. */
  251. public function setExceptionThrownOnFailure($throwOnFail)
  252. {
  253. $this->_throwOnFail = (boolean) $throwOnFail;
  254. }
  255. /**
  256. * Build a signed URL for this Request.
  257. *
  258. * The Api will provide the key and secret and token values.
  259. *
  260. * @return string
  261. * @link http://flickr.com/services/api/auth.spec.html
  262. * @see buildUrl, Phlickr_Api::getKey(), Phlickr_Api::getSecret()
  263. * @uses signParams() to create a signed URL.
  264. */
  265. public function buildUrl()
  266. {
  267. $api = $this->getApi();
  268. // merge the api's parameters with the user's. the order of array_merge
  269. // parameters is designed so that user values will overwrite api values
  270. // if there are duplicates.
  271. $params = array_merge(
  272. $api->getParamsForRequest(),
  273. $this->getParams()
  274. );
  275. $params['method'] = $this->getMethod();
  276. return $api->getEndpointUrl() . '?'
  277. . self::signParams($api->getSecret(), $params);
  278. }
  279. /**
  280. * Execute a Flickr API method.
  281. *
  282. * All requests are cached but cached data is only used when the caller
  283. * specifically allows it. This allows the unittests to load a cache full
  284. * of expected responses and avoid a network connection.
  285. *
  286. * @param boolean $allowCached If a cached result exists, should it be returned?
  287. * @return object Flicrk_Response
  288. * @throws Phlickr_XmlParseException, Phlickr_ConnectionException
  289. * @uses submitHttpPost() to submit the request.
  290. * @uses Phlickr_Cache to load and cached requests.
  291. * @uses Phlickr_Response to return results.
  292. */
  293. public function execute($allowCached = false)
  294. {
  295. $url = $this->buildUrl();
  296. $cache = &$this->getApi()->getCache();
  297. // print "\nREQUEST: $url\n";
  298. // if($url == '') return NULL;
  299. if ($allowCached && $cache->has($url)) {
  300. $result = $cache->get($url);
  301. } else {
  302. $result = self::submitHttpPost($url);
  303. $cache->set($url, $result);
  304. }
  305. // print "RESULT: $result\n";
  306. return new Phlickr_Response($result, $this->_throwOnFail);
  307. }
  308. }