/application/helpers/account/jmathai-twitter-async/EpiTwitter.php
PHP | 294 lines | 227 code | 44 blank | 23 comment | 19 complexity | 105aaeaed22e80b78ca9ae6acacefdcb MD5 | raw file
- <?php
- /*
- * Class to integrate with Twitter's API.
- * Authenticated calls are done using OAuth and require access tokens for a user.
- * API calls which do not require authentication do not require tokens (i.e. search/trends)
- *
- * Full documentation available on github
- * http://wiki.github.com/jmathai/twitter-async
- *
- * @author Jaisen Mathai <jaisen@jmathai.com>
- */
- class EpiTwitter extends EpiOAuth {
- const EPITWITTER_SIGNATURE_METHOD = 'HMAC-SHA1';
- const EPITWITTER_AUTH_OAUTH = 'oauth';
- const EPITWITTER_AUTH_BASIC = 'basic';
- protected $requestTokenUrl = 'https://api.twitter.com/oauth/request_token';
- protected $accessTokenUrl = 'https://api.twitter.com/oauth/access_token';
- protected $authorizeUrl = 'https://api.twitter.com/oauth/authorize';
- protected $authenticateUrl = 'https://api.twitter.com/oauth/authenticate';
- protected $apiUrl = 'http://api.twitter.com';
- protected $apiVersionedUrl = 'http://api.twitter.com';
- protected $searchUrl = 'http://search.twitter.com';
- protected $userAgent = 'EpiTwitter (http://github.com/jmathai/twitter-async/tree/)';
- protected $apiVersion = '1.1';
- protected $isAsynchronous = FALSE;
- /* OAuth methods */
- public function delete($endpoint, $params = NULL)
- {
- return $this->request('DELETE', $endpoint, $params);
- }
- public function get($endpoint, $params = NULL)
- {
- return $this->request('GET', $endpoint, $params);
- }
- public function post($endpoint, $params = NULL)
- {
- return $this->request('POST', $endpoint, $params);
- }
- /* Basic auth methods */
- public function delete_basic($endpoint, $params = NULL, $username = NULL, $password = NULL)
- {
- return $this->request_basic('DELETE', $endpoint, $params, $username, $password);
- }
- public function get_basic($endpoint, $params = NULL, $username = NULL, $password = NULL)
- {
- return $this->request_basic('GET', $endpoint, $params, $username, $password);
- }
- public function post_basic($endpoint, $params = NULL, $username = NULL, $password = NULL)
- {
- return $this->request_basic('POST', $endpoint, $params, $username, $password);
- }
- public function useApiVersion($version = NULL)
- {
- $this->apiVersion = $version;
- }
- public function useAsynchronous($async = TRUE)
- {
- $this->isAsynchronous = (bool)$async;
- }
- public function __construct($consumerKey = NULL, $consumerSecret = NULL, $oauthToken = NULL, $oauthTokenSecret = NULL)
- {
- parent::__construct($consumerKey, $consumerSecret, self::EPITWITTER_SIGNATURE_METHOD);
- $this->setToken($oauthToken, $oauthTokenSecret);
- }
- public function __call($name, $params = NULL /*, $username, $password*/)
- {
- $parts = explode('_', $name);
- $method = strtoupper(array_shift($parts));
- $parts = implode('_', $parts);
- $endpoint = '/'.preg_replace('/[A-Z]|[0-9]+/e', "'/'.strtolower('\\0')", $parts).'.json';
- /* HACK: this is required for list support that starts with a user id */
- $endpoint = str_replace('//', '/', $endpoint);
- $args = ! empty($params) ? array_shift($params) : NULL;
- // calls which do not have a consumerKey are assumed to not require authentication
- if ($this->consumerKey === NULL)
- {
- $username = NULL;
- $password = NULL;
- if ( ! empty($params))
- {
- $username = array_shift($params);
- $password = ! empty($params) ? array_shift($params) : NULL;
- }
- return $this->request_basic($method, $endpoint, $args, $username, $password);
- }
- return $this->request($method, $endpoint, $args);
- }
- private function getApiUrl($endpoint)
- {
- if (preg_match('@^/search[./]?(?=(json|daily|current|weekly))@', $endpoint)) return "{$this->searchUrl}{$endpoint}";
- elseif ( ! empty($this->apiVersion)) return "{$this->apiVersionedUrl}/{$this->apiVersion}{$endpoint}";
- else
- return "{$this->apiUrl}{$endpoint}";
- }
- private function request($method, $endpoint, $params = NULL)
- {
- $url = $this->getUrl($this->getApiUrl($endpoint));
- $resp = new EpiTwitterJson(call_user_func(array($this, 'httpRequest'), $method, $url, $params, $this->isMultipart($params)), $this->debug);
- if ( ! $this->isAsynchronous) $resp->response;
- return $resp;
- }
- private function request_basic($method, $endpoint, $params = NULL, $username = NULL, $password = NULL)
- {
- $url = $this->getApiUrl($endpoint);
- if ($method === 'GET') $url .= is_null($params) ? '' : '?'.http_build_query($params, '', '&');
- $ch = curl_init($url);
- curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
- curl_setopt($ch, CURLOPT_TIMEOUT, $this->requestTimeout);
- curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
- if ($method === 'POST' && $params !== NULL)
- {
- if ($this->isMultipart($params)) curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
- else
- curl_setopt($ch, CURLOPT_POSTFIELDS, $this->buildHttpQueryRaw($params));
- }
- if ( ! empty($username) && ! empty($password)) curl_setopt($ch, CURLOPT_USERPWD, "{$username}:{$password}");
- $resp = new EpiTwitterJson(EpiCurl::getInstance()->addCurl($ch), $this->debug);
- if ( ! $this->isAsynchronous) $resp->response;
- return $resp;
- }
- }
- class EpiTwitterJson implements ArrayAccess, Countable, IteratorAggregate {
- private $debug;
- private $__resp;
- public function __construct($response, $debug = FALSE)
- {
- $this->__resp = $response;
- $this->debug = $debug;
- }
- // ensure that calls complete by blocking for results, NOOP if already returned
- public function __destruct()
- {
- $this->responseText;
- }
- // Implementation of the IteratorAggregate::getIterator() to support foreach ($this as $...)
- public function getIterator()
- {
- if ($this->__obj)
- {
- return new ArrayIterator($this->__obj);
- }
- else
- {
- return new ArrayIterator($this->response);
- }
- }
- // Implementation of Countable::count() to support count($this)
- public function count()
- {
- return count($this->response);
- }
- // Next four functions are to support ArrayAccess interface
- // 1
- public function offsetSet($offset, $value)
- {
- $this->response[$offset] = $value;
- }
- // 2
- public function offsetExists($offset)
- {
- return isset($this->response[$offset]);
- }
- // 3
- public function offsetUnset($offset)
- {
- unset($this->response[$offset]);
- }
- // 4
- public function offsetGet($offset)
- {
- return isset($this->response[$offset]) ? $this->response[$offset] : NULL;
- }
- public function __get($name)
- {
- $accessible = array('responseText' => 1, 'headers' => 1, 'code' => 1);
- $this->responseText = $this->__resp->data;
- $this->headers = $this->__resp->headers;
- $this->code = $this->__resp->code;
- if (isset($accessible[$name]) && $accessible[$name]) return $this->$name;
- elseif (($this->code < 200 || $this->code >= 400) && ! isset($accessible[$name])) EpiTwitterException::raise($this->__resp, $this->debug);
- // Call appears ok so we can fill in the response
- $this->response = json_decode($this->responseText, 1);
- $this->__obj = json_decode($this->responseText);
- if (gettype($this->__obj) === 'object')
- {
- foreach ($this->__obj as $k => $v)
- {
- $this->$k = $v;
- }
- }
- if (property_exists($this, $name))
- {
- return $this->$name;
- }
- return NULL;
- }
- public function __isset($name)
- {
- $value = self::__get($name);
- return ! empty($name);
- }
- }
- class EpiTwitterException extends Exception {
- public static function raise($response, $debug)
- {
- $message = $response->data;
- switch ($response->code)
- {
- case 400:
- throw new EpiTwitterBadRequestException($message, $response->code);
- case 401:
- throw new EpiTwitterNotAuthorizedException($message, $response->code);
- case 403:
- throw new EpiTwitterForbiddenException($message, $response->code);
- case 404:
- throw new EpiTwitterNotFoundException($message, $response->code);
- case 406:
- throw new EpiTwitterNotAcceptableException($message, $response->code);
- case 420:
- throw new EpiTwitterEnhanceYourCalmException($message, $response->code);
- case 500:
- throw new EpiTwitterInternalServerException($message, $response->code);
- case 502:
- throw new EpiTwitterBadGatewayException($message, $response->code);
- case 503:
- throw new EpiTwitterServiceUnavailableException($message, $response->code);
- default:
- throw new EpiTwitterException($message, $response->code);
- }
- }
- }
- class EpiTwitterBadRequestException extends EpiTwitterException {
- }
- class EpiTwitterNotAuthorizedException extends EpiTwitterException {
- }
- class EpiTwitterForbiddenException extends EpiTwitterException {
- }
- class EpiTwitterNotFoundException extends EpiTwitterException {
- }
- class EpiTwitterNotAcceptableException extends EpiTwitterException {
- }
- class EpiTwitterEnhanceYourCalmException extends EpiTwitterException {
- }
- class EpiTwitterInternalServerException extends EpiTwitterException {
- }
- class EpiTwitterBadGatewayException extends EpiTwitterException {
- }
- class EpiTwitterServiceUnavailableException extends EpiTwitterException {
- }