/application/libraries/tweet.php
PHP | 641 lines | 489 code | 146 blank | 6 comment | 55 complexity | 14ddb646e7e2862c0b3eb8ca9e1bcd49 MD5 | raw file
- <?php
-
- class tweet {
-
- private $_oauth = NULL;
-
- function __construct()
- {
- $this->_oauth = new tweetOauth();
- }
-
- function __call($method, $args)
- {
- if ( method_exists($this, $method) )
- {
- return call_user_func_array(array($this, $method), $args);
- }
-
- return call_user_func_array(array($this->_oauth, $method), $args);
- }
-
- function logged_in()
- {
- return $this->_oauth->loggedIn();
- }
-
- function set_callback($url)
- {
- $this->_oauth->setCallback($url);
- }
-
- function login()
- {
- return $this->_oauth->login();
- }
-
- function logout()
- {
- return $this->_oauth->logout();
- }
-
- function get_tokens()
- {
- $tokens = array(
- 'oauth_token' => $this->_oauth->getAccessKey(),
- 'oauth_token_secret' => $this->_oauth->getAccessSecret()
- );
-
- return $tokens;
- }
-
- function set_tokens($tokens)
- {
- return $this->_oauth->setAccessTokens($tokens);
- }
- }
-
- class tweetException extends Exception {
-
- function __construct($string)
- {
- parent::__construct($string);
- }
-
- public function __toString() {
- return "exception '".__CLASS__ ."' with message '".$this->getMessage()."' in ".$this->getFile().":".$this->getLine()."\nStack trace:\n".$this->getTraceAsString();
- }
- }
-
- class tweetConnection {
-
- // Allow multi-threading.
-
- private $_mch = NULL;
- private $_properties = array();
-
- function __construct()
- {
- $this->_mch = curl_multi_init();
-
- $this->_properties = array(
- 'code' => CURLINFO_HTTP_CODE,
- 'time' => CURLINFO_TOTAL_TIME,
- 'length' => CURLINFO_CONTENT_LENGTH_DOWNLOAD,
- 'type' => CURLINFO_CONTENT_TYPE
- );
- }
-
- private function _initConnection($url)
- {
- $this->_ch = curl_init($url);
- curl_setopt($this->_ch, CURLOPT_RETURNTRANSFER, TRUE);
- }
-
- public function get($url, $params)
- {
- if ( count($params['request']) > 0 )
- {
- $url .= '?';
-
- foreach( $params['request'] as $k => $v )
- {
- $url .= "{$k}={$v}&";
- }
-
- $url = substr($url, 0, -1);
- }
-
- $this->_initConnection($url);
- $response = $this->_addCurl($url, $params);
- return $response;
- }
-
- public function post($url, $params)
- {
- // Todo
- $post = '';
-
- foreach ( $params['request'] as $k => $v )
- {
- $post .= "{$k}={$v}&";
- }
-
- $post = substr($post, 0, -1);
-
- $this->_initConnection($url, $params);
- curl_setopt($this->_ch, CURLOPT_POST, 1);
- curl_setopt($this->_ch, CURLOPT_POSTFIELDS, $post);
-
- $response = $this->_addCurl($url, $params);
- return $response;
- }
-
- private function _addOauthHeaders(&$ch, $url, $oauthHeaders)
- {
- $_h = array('Expect:');
- $urlParts = parse_url($url);
- $oauth = 'Authorization: OAuth realm="' . $urlParts['path'] . '",';
-
- foreach ( $oauthHeaders as $name => $value )
- {
- $oauth .= "{$name}=\"{$value}\",";
- }
-
- $_h[] = substr($oauth, 0, -1);
-
- curl_setopt($ch, CURLOPT_HTTPHEADER, $_h);
- }
-
- private function _addCurl($url, $params = array())
- {
- if ( !empty($params['oauth']) )
- {
- $this->_addOauthHeaders($this->_ch, $url, $params['oauth']);
- }
-
- $ch = $this->_ch;
-
- $key = (string) $ch;
- $this->_requests[$key] = $ch;
-
- $response = curl_multi_add_handle($this->_mch, $ch);
- if ( $response === CURLM_OK || $response === CURLM_CALL_MULTI_PERFORM )
- {
- do {
- $mch = curl_multi_exec($this->_mch, $active);
- } while ( $mch === CURLM_CALL_MULTI_PERFORM );
-
- return $this->_getResponse($key);
- }
- else
- {
- return $response;
- }
- }
-
- private function _getResponse($key = NULL)
- {
- if ( $key == NULL ) return FALSE;
-
- if ( isset($this->_responses[$key]) )
- {
- return $this->_responses[$key];
- }
-
- $running = NULL;
-
- do
- {
- $response = curl_multi_exec($this->_mch, $running_curl);
-
- if ( $running !== NULL && $running_curl != $running )
- {
- $this->_setResponse($key);
-
- if ( isset($this->_responses[$key]) )
- {
- $response = new tweetResponseOauth( (object) $this->_responses[$key] );
-
- if ( $response->__resp->code !== 200 )
- {
- throw new tweetException($response->__resp->code.' | Request Failed: '.$response->__resp->data->request.' - '.$response->__resp->data->error);
- }
-
- return $response;
- }
- }
-
- $running = $running_curl;
-
- } while ( $running_curl > 0);
-
- }
-
- private function _setResponse($key)
- {
- while( $done = curl_multi_info_read($this->_mch) )
- {
- $key = (string) $done['handle'];
- $this->_responses[$key]['data'] = curl_multi_getcontent($done['handle']);
-
- foreach ( $this->_properties as $curl_key => $value )
- {
- $this->_responses[$key][$curl_key] = curl_getinfo($done['handle'], $value);
-
- curl_multi_remove_handle($this->_mch, $done['handle']);
- }
- }
- }
- }
-
- class tweetResponseOauth {
-
- private $__construct;
- public function __construct($resp)
- {
- $this->__resp = $resp;
- if ( strpos($this->__resp->type, 'json') !== FALSE )
- {
- $this->__resp->data = json_decode($this->__resp->data);
- }
- }
- public function __get($name)
- {
- if ($this->__resp->code < 200 || $this->__resp->code > 299) return FALSE;
-
- if ( is_string($this->__resp->data ) )
- {
- parse_str($this->__resp->data, $result);
- }
- else
- {
- $result = $this->__resp->data;
- }
-
- foreach($result as $k => $v)
- {
- $this->$k = $v;
- }
-
- if ( $name === '_result')
- {
- return $result;
- }
- return $result[$name];
- }
- }
-
- class tweetOauth extends tweetConnection {
-
- private $_obj;
- private $_tokens = array();
- private $_authorizationUrl = 'http://api.twitter.com/oauth/authorize';
- private $_requestTokenUrl = 'http://api.twitter.com/oauth/request_token';
- private $_accessTokenUrl = 'http://api.twitter.com/oauth/access_token';
- private $_signatureMethod = 'HMAC-SHA1';
- private $_version = '1.0';
- private $_apiUrl = 'http://api.twitter.com';
- private $_searchUrl = 'http://search.twitter.com/';
- private $_callback = NULL;
- private $_errors = array();
- private $_enable_debug = FALSE;
-
- function __construct()
- {
- parent::__construct();
-
- $this->_obj =& get_instance();
- $this->_obj->load->config('tweet');
- $this->_obj->load->library('session');
- $this->_obj->load->library('unit_test');
- $this->_obj->load->helper('url');
-
- $this->_tokens = array(
- 'consumer_key' => $this->_obj->config->item('tweet_consumer_key'),
- 'consumer_secret' => $this->_obj->config->item('tweet_consumer_secret'),
- 'access_key' => $this->_getAccessKey(),
- 'access_secret' => $this->_getAccessSecret()
- );
-
- $this->_checkLogin();
- }
-
- function __destruct()
- {
- if ( !$this->_enable_debug ) return;
-
- if ( !empty($this->_errors) )
- {
- foreach ( $this->_errors as $key => $e )
- {
- echo '<pre>'.$e.'</pre>';
- }
- }
- }
-
- public function enable_debug($debug)
- {
- $debug = (bool) $debug;
- $this->_enable_debug = $debug;
- }
-
- public function call($method, $path, $args = NULL)
- {
- $response = $this->_httpRequest(strtoupper($method), $this->_apiUrl.'/'.$path.'.json', $args);
-
- // var_dump($response);
- // die();
-
- return ( $response === NULL ) ? FALSE : $response->_result;
- }
-
- public function search($args = NULL)
- {
- $response = $this->_httpRequest('GET', $this->_searchUrl.'search.json', $args);
-
- return ( $response === NULL ) ? FALSE : $response->_result;
- }
-
- public function loggedIn()
- {
- $access_key = $this->_getAccessKey();
- $access_secret = $this->_getAccessSecret();
-
- $loggedIn = FALSE;
-
- if ( $this->_getAccessKey() !== NULL && $this->_getAccessSecret() !== NULL )
- {
- $loggedIn = TRUE;
- }
-
- $this->_obj->unit->run($loggedIn, TRUE, 'Logged In');
- return $loggedIn;
- }
-
- private function _checkLogin()
- {
- if ( isset($_GET['oauth_token']) )
- {
- $this->_setAccessKey($_GET['oauth_token']);
- $token = $this->_getAccessToken();
-
- $token = $token->_result;
-
- $token = ( is_bool($token) ) ? $token : (object) $token;
-
- if ( !empty($token->oauth_token) && !empty($token->oauth_token_secret) )
- {
- $this->_setAccessKey($token->oauth_token);
- $this->_setAccessSecret($token->oauth_token_secret);
- }
-
- redirect(current_url());
- return NULL;
- }
- }
-
- public function login()
- {
- if ( ($this->_getAccessKey() === NULL || $this->_getAccessSecret() === NULL) )
- {
- header('Location: '.$this->_getAuthorizationUrl());
- return;
- }
-
- return $this->_checkLogin();
- }
-
- public function logout()
- {
- $this->_obj->session->unset_userdata('twitter_oauth_tokens');
- }
-
- public function getTokens()
- {
- return $this->_tokens;
- }
-
- private function _getConsumerKey()
- {
- return $this->_tokens['consumer_key'];
- }
-
- private function _getConsumerSecret()
- {
- return $this->_tokens['consumer_secret'];
- }
-
- public function getAccessKey(){ return $this->_getAccessKey(); }
-
- private function _getAccessKey()
- {
- $tokens = $this->_obj->session->userdata('twitter_oauth_tokens');
- return ( $tokens === FALSE || !isset($tokens['access_key']) || empty($tokens['access_key']) ) ? NULL : $tokens['access_key'];
- }
-
- private function _setAccessKey($access_key)
- {
- $tokens = $this->_obj->session->userdata('twitter_oauth_tokens');
-
- if ( $tokens === FALSE || !is_array($tokens) )
- {
- $tokens = array('access_key' => $access_key);
- }
- else
- {
- $tokens['access_key'] = $access_key;
- }
-
- $this->_obj->session->set_userdata('twitter_oauth_tokens', $tokens);
- }
-
- public function getAccessSecret(){ return $this->_getAccessSecret(); }
-
- private function _getAccessSecret()
- {
- $tokens = $this->_obj->session->userdata('twitter_oauth_tokens');
- return ( $tokens === FALSE || !isset($tokens['access_secret']) || empty($tokens['access_secret']) ) ? NULL : $tokens['access_secret'];
- }
-
- private function _setAccessSecret($access_secret)
- {
- $tokens = $this->_obj->session->userdata('twitter_oauth_tokens');
-
- if ( $tokens === FALSE || !is_array($tokens) )
- {
- $tokens = array('access_secret' => $access_secret);
- }
- else
- {
- $tokens['access_secret'] = $access_secret;
- }
-
- $this->_obj->session->set_userdata('twitter_oauth_tokens', $tokens);
- }
-
- private function _setAccessTokens($tokens)
- {
- $this->_setAccessKey($tokens['oauth_token']);
- $this->_setAccessSecret($tokens['oauth_token_secret']);
- }
-
- public function setAccessTokens($tokens)
- {
- return $this->_setAccessTokens($tokens);
- }
-
- private function _getAuthorizationUrl()
- {
- $token = $this->_getRequestToken();
- return $this->_authorizationUrl.'?oauth_token=' . $token->oauth_token;
- }
-
- private function _getRequestToken()
- {
- return $this->_httpRequest('GET', $this->_requestTokenUrl);
- }
-
- private function _getAccessToken()
- {
- return $this->_httpRequest('GET', $this->_accessTokenUrl);
- }
-
- protected function _httpRequest($method = null, $url = null, $params = null)
- {
- if( empty($method) || empty($url) ) return FALSE;
- if ( empty($params['oauth_signature']) ) $params = $this->_prepareParameters($method, $url, $params);
-
- $this->_connection = new tweetConnection();
-
- try {
- switch ( $method )
- {
- case 'GET':
- return $this->_connection->get($url, $params);
- break;
- case 'POST':
- return $this->_connection->post($url, $params);
- break;
- case 'PUT':
- return NULL;
- break;
- case 'DELETE':
- return NULL;
- break;
- }
- } catch (tweetException $e) {
- $this->_errors[] = $e;
- }
- }
-
- private function _getCallback()
- {
- return $this->_callback;
- }
-
- public function setCallback($url)
- {
- $this->_callback = $url;
- }
-
- private function _prepareParameters($method = NULL, $url = NULL, $params = NULL)
- {
- if ( empty($method) || empty($url) ) return FALSE;
-
- $callback = $this->_getCallback();
-
- if ( !empty($callback) )
- {
- $oauth['oauth_callback'] = $callback;
- }
-
- $this->setCallback(NULL);
-
- $oauth['oauth_consumer_key'] = $this->_getConsumerKey();
- $oauth['oauth_token'] = $this->_getAccessKey();
- $oauth['oauth_nonce'] = $this->_generateNonce();
- $oauth['oauth_timestamp'] = time();
- $oauth['oauth_signature_method'] = $this->_signatureMethod;
- $oauth['oauth_version'] = $this->_version;
-
- array_walk($oauth, array($this, '_encode_rfc3986'));
-
- if ( is_array($params) )
- {
- array_walk($params, array($this, '_encode_rfc3986'));
- }
-
- $encodedParams = array_merge($oauth, (array)$params);
-
- ksort($encodedParams);
-
- $oauth['oauth_signature'] = $this->_encode_rfc3986($this->_generateSignature($method, $url, $encodedParams));
- return array('request' => $params, 'oauth' => $oauth);
- }
-
- private function _generateNonce()
- {
- return md5(uniqid(rand(), TRUE));
- }
-
- private function _encode_rfc3986($string)
- {
- return str_replace('+', ' ', str_replace('%7E', '~', rawurlencode(($string))));
- }
-
- private function _generateSignature($method = null, $url = null, $params = null)
- {
- if( empty($method) || empty($url) ) return FALSE;
-
- // concatenating
- $concatenatedParams = '';
-
- foreach ($params as $k => $v)
- {
- $v = $this->_encode_rfc3986($v);
- $concatenatedParams .= "{$k}={$v}&";
- }
-
- $concatenatedParams = $this->_encode_rfc3986(substr($concatenatedParams, 0, -1));
- // normalize url
- $normalizedUrl = $this->_encode_rfc3986($this->_normalizeUrl($url));
- $method = $this->_encode_rfc3986($method); // don't need this but why not?
- $signatureBaseString = "{$method}&{$normalizedUrl}&{$concatenatedParams}";
- return $this->_signString($signatureBaseString);
- }
-
- private function _normalizeUrl($url = NULL)
- {
- $urlParts = parse_url($url);
- if ( !isset($urlParts['port']) ) $urlParts['port'] = 80;
- $scheme = strtolower($urlParts['scheme']);
- $host = strtolower($urlParts['host']);
- $port = intval($urlParts['port']);
- $retval = "{$scheme}://{$host}";
-
- if ( $port > 0 && ( $scheme === 'http' && $port !== 80 ) || ( $scheme === 'https' && $port !== 443 ) )
- {
- $retval .= ":{$port}";
- }
-
- $retval .= $urlParts['path'];
-
- if ( !empty($urlParts['query']) )
- {
- $retval .= "?{$urlParts['query']}";
- }
-
- return $retval;
- }
-
- private function _signString($string)
- {
- $retval = FALSE;
- switch ( $this->_signatureMethod )
- {
- case 'HMAC-SHA1':
- $key = $this->_encode_rfc3986($this->_getConsumerSecret()) . '&' . $this->_encode_rfc3986($this->_getAccessSecret());
- $retval = base64_encode(hash_hmac('sha1', $string, $key, true));
- break;
- }
- return $retval;
- }
- }