PageRenderTime 53ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/EpiFoursquare.php

https://github.com/ecdiddy/foursquare-async
PHP | 252 lines | 200 code | 31 blank | 21 comment | 17 complexity | 52e374410a1285f2bc44d9a901d82185 MD5 | raw file
  1. <?php
  2. /*
  3. * Class to integrate with Foursquare's API.
  4. * Authenticated calls are done using OAuth and require access tokens for a user.
  5. * API calls which do not require authentication do not require tokens
  6. *
  7. * Full documentation available on github
  8. * http://wiki.github.com/jmathai/foursquare-async
  9. *
  10. * @author Jaisen Mathai <jaisen@jmathai.com>
  11. */
  12. class EpiFoursquare
  13. {
  14. protected $clientId, $clientSecret, $accessToken;
  15. protected $requestTokenUrl= 'https://foursquare.com/oauth2/authenticate';
  16. protected $accessTokenUrl = 'https://foursquare.com/oauth2/access_token';
  17. protected $authorizeUrl = 'https://foursquare.com/oauth/authorize';
  18. protected $apiUrl = 'https://api.foursquare.com';
  19. protected $userAgent = 'EpiFoursquare (http://github.com/jmathai/foursquare-async/tree/)';
  20. protected $apiVersion = 'v2';
  21. protected $isAsynchronous = false;
  22. protected $followLocation = false;
  23. protected $connectionTimeout = 5;
  24. protected $requestTimeout = 30;
  25. protected $debug = false;
  26. protected $verifyCert = false;
  27. public function getAccessToken($code, $redirectUri)
  28. {
  29. $params = array('client_id' => $this->clientId, 'client_secret' => $this->clientSecret, 'grant_type' => 'authorization_code', 'redirect_uri' => $redirectUri, 'code' => $code);
  30. $qs = http_build_query($params);
  31. return $this->request('GET', "{$this->accessTokenUrl}", $params);
  32. }
  33. public function getAuthorizeUrl($redirectUri)
  34. {
  35. $params = array('client_id' => $this->clientId, 'response_type' => 'code', 'redirect_uri' => $redirectUri);
  36. $qs = http_build_query($params);
  37. return "{$this->requestTokenUrl}?{$qs}";
  38. }
  39. public function setAccessToken($accessToken)
  40. {
  41. $this->accessToken = $accessToken;
  42. }
  43. public function setTimeout($requestTimeout = null, $connectionTimeout = null)
  44. {
  45. if($requestTimeout !== null)
  46. $this->requestTimeout = floatval($requestTimeout);
  47. if($connectionTimeout !== null)
  48. $this->connectionTimeout = floatval($connectionTimeout);
  49. }
  50. public function useApiVersion($version = null)
  51. {
  52. $this->apiVersion = $version;
  53. }
  54. public function useAsynchronous($async = true)
  55. {
  56. $this->isAsynchronous = (bool)$async;
  57. }
  58. // Public api interface for most calls GET/POST/DELETE
  59. public function delete($endpoint, $params = null)
  60. {
  61. return $this->request('DELETE', $endpoint, $params);
  62. }
  63. public function get($endpoint, $params = null)
  64. {
  65. return $this->request('GET', $endpoint, $params);
  66. }
  67. public function post($endpoint, $params = null)
  68. {
  69. return $this->request('POST', $endpoint, $params);
  70. }
  71. public function __construct($clientId = null, $clientSecret = null, $accessToken = null)
  72. {
  73. $this->clientId = $clientId;
  74. $this->clientSecret = $clientSecret;
  75. $this->accessToken = $accessToken;
  76. }
  77. private function getApiUrl($endpoint)
  78. {
  79. if(!empty($this->apiVersion))
  80. return "{$this->apiUrl}/{$this->apiVersion}{$endpoint}";
  81. else
  82. return "{$this->apiUrl}{$endpoint}";
  83. }
  84. private function request($method, $endpoint, $params = null)
  85. {
  86. if(preg_match('#^https?://#', $endpoint))
  87. $url = $endpoint;
  88. else
  89. $url = $this->getApiUrl($endpoint);
  90. if($this->accessToken)
  91. {
  92. $params['oauth_token'] = $this->accessToken;
  93. }
  94. else
  95. {
  96. $params['client_id'] = $this->clientId;
  97. $params['client_secret'] = $this->clientSecret;
  98. }
  99. if($method === 'GET')
  100. $url .= is_null($params) ? '' : '?'.http_build_query($params, '', '&');
  101. $ch = curl_init($url);
  102. //print_r($url);exit;
  103. curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
  104. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $this->verifyCert);
  105. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  106. curl_setopt($ch, CURLOPT_TIMEOUT, $this->requestTimeout);
  107. curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
  108. if($method === 'POST' && $params !== null)
  109. {
  110. curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
  111. }
  112. $resp = new EpiFoursquareJson(EpiCurl::getInstance()->addCurl($ch), $this->debug);
  113. if(!$this->isAsynchronous)
  114. $resp->responseText;
  115. return $resp;
  116. }
  117. }
  118. class EpiFoursquareJson implements ArrayAccess, Countable, IteratorAggregate
  119. {
  120. private $debug;
  121. private $__resp;
  122. public function __construct($response, $debug = false)
  123. {
  124. $this->__resp = $response;
  125. $this->debug = $debug;
  126. }
  127. // ensure that calls complete by blocking for results, NOOP if already returned
  128. public function __destruct()
  129. {
  130. $this->responseText;
  131. }
  132. // Implementation of the IteratorAggregate::getIterator() to support foreach ($this as $...)
  133. public function getIterator ()
  134. {
  135. if ($this->__obj) {
  136. return new ArrayIterator($this->__obj);
  137. } else {
  138. return new ArrayIterator($this->response);
  139. }
  140. }
  141. // Implementation of Countable::count() to support count($this)
  142. public function count ()
  143. {
  144. return count($this->response);
  145. }
  146. // Next four functions are to support ArrayAccess interface
  147. // 1
  148. public function offsetSet($offset, $value)
  149. {
  150. $this->response[$offset] = $value;
  151. }
  152. // 2
  153. public function offsetExists($offset)
  154. {
  155. return isset($this->response[$offset]);
  156. }
  157. // 3
  158. public function offsetUnset($offset)
  159. {
  160. unset($this->response[$offset]);
  161. }
  162. // 4
  163. public function offsetGet($offset)
  164. {
  165. return isset($this->response[$offset]) ? $this->response[$offset] : null;
  166. }
  167. public function __get($name)
  168. {
  169. $accessible = array('responseText'=>1,'headers'=>1,'code'=>1);
  170. $this->responseText = $this->__resp->data;
  171. $this->headers = $this->__resp->headers;
  172. $this->code = $this->__resp->code;
  173. if(isset($accessible[$name]) && $accessible[$name])
  174. return $this->$name;
  175. elseif(($this->code < 200 || $this->code >= 400) && !isset($accessible[$name]))
  176. EpiFoursquareException::raise($this->__resp, $this->debug);
  177. // Call appears ok so we can fill in the response
  178. $this->response = json_decode($this->responseText, 1);
  179. $this->__obj = json_decode($this->responseText);
  180. if(gettype($this->__obj) === 'object')
  181. {
  182. foreach($this->__obj as $k => $v)
  183. {
  184. $this->$k = $v;
  185. }
  186. }
  187. if (property_exists($this, $name)) {
  188. return $this->$name;
  189. }
  190. return null;
  191. }
  192. public function __isset($name)
  193. {
  194. $value = self::__get($name);
  195. return !empty($name);
  196. }
  197. }
  198. class EpiFoursquareException extends Exception
  199. {
  200. public static function raise($response, $debug)
  201. {
  202. $message = $response->data;
  203. switch($response->code)
  204. {
  205. case 400:
  206. throw new EpiFoursquareBadRequestException($message, $response->code);
  207. case 401:
  208. throw new EpiFoursquareNotAuthorizedException($message, $response->code);
  209. case 403:
  210. throw new EpiFoursquareForbiddenException($message, $response->code);
  211. case 404:
  212. throw new EpiFoursquareNotFoundException($message, $response->code);
  213. default:
  214. throw new EpiFoursquareException($message, $response->code);
  215. }
  216. }
  217. }
  218. class EpiFoursquareBadRequestException extends EpiFoursquareException{}
  219. class EpiFoursquareNotAuthorizedException extends EpiFoursquareException{}
  220. class EpiFoursquareForbiddenException extends EpiFoursquareException{}
  221. class EpiFoursquareNotFoundException extends EpiFoursquareException{}