first import
This commit is contained in:
535
sites/all/modules/twitter/twitter.lib.php
Normal file
535
sites/all/modules/twitter/twitter.lib.php
Normal file
@@ -0,0 +1,535 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Classes to implement the full Twitter API
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class TwitterConfig
|
||||
*
|
||||
* Singleton which stores common configuration
|
||||
* @see http://php.net/manual/en/language.oop5.patterns.php
|
||||
*/
|
||||
class TwitterConf {
|
||||
private static $instance;
|
||||
private $attributes = array(
|
||||
'host' => 'twitter.com',
|
||||
'api' => 'api.twitter.com',
|
||||
'search' => 'search.twitter.com',
|
||||
'tiny_url' => 'tinyurl.com',
|
||||
);
|
||||
|
||||
private function __construct() {}
|
||||
|
||||
public static function instance() {
|
||||
if (!isset(self::$instance)) {
|
||||
$className = __CLASS__;
|
||||
self::$instance = new $className;
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic getter
|
||||
*
|
||||
* @param $attribute
|
||||
* string attribute name to return
|
||||
* @return
|
||||
* mixed value or NULL
|
||||
*/
|
||||
public function get($attribute) {
|
||||
if (array_key_exists($attribute, $this->attributes)) {
|
||||
return $this->attributes[$attribute];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic setter
|
||||
* @param $attribute
|
||||
* string attribute name to be set
|
||||
* @param $value
|
||||
* mixed value
|
||||
*/
|
||||
public function set($attribute, $value) {
|
||||
if (array_key_exists($attribute, $this->attributes)) {
|
||||
$this->attributes[$attribute] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception handling class.
|
||||
*/
|
||||
class TwitterException extends Exception {}
|
||||
|
||||
/**
|
||||
* Primary Twitter API implementation class
|
||||
* Supports the full REST API for twitter.
|
||||
*/
|
||||
class Twitter {
|
||||
|
||||
/**
|
||||
* @var $format API format to use: can be json or xml
|
||||
*/
|
||||
protected $format = 'json';
|
||||
|
||||
/**
|
||||
* @var $source the twitter api 'source'
|
||||
*/
|
||||
protected $source = 'drupal';
|
||||
|
||||
/**
|
||||
* @var $username Twitter username to use for authenticated requests
|
||||
*/
|
||||
protected $username;
|
||||
|
||||
/**
|
||||
* @var $password Twitter password to use for authenticated requests
|
||||
*/
|
||||
protected $password;
|
||||
|
||||
/**
|
||||
* Constructor for the Twitter class
|
||||
*/
|
||||
public function __construct($username = NULL, $password = NULL) {
|
||||
if (!empty($username) && !empty($password)) {
|
||||
$this->set_auth($username, $password);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the username and password
|
||||
*/
|
||||
public function set_auth($username, $password) {
|
||||
$this->username = $username;
|
||||
$this->password = $password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of TwitterStatus objects from an API endpoint
|
||||
*/
|
||||
protected function get_statuses($path, $params = array(), $use_auth = FALSE) {
|
||||
$values = $this->call($path, $params, 'GET', $use_auth);
|
||||
// Check on successfull call
|
||||
if ($values) {
|
||||
$statuses = array();
|
||||
foreach ($values as $status) {
|
||||
$statuses[] = new TwitterStatus($status);
|
||||
}
|
||||
return $statuses;
|
||||
}
|
||||
// Call might return FALSE , e.g. on failed authentication
|
||||
else {
|
||||
// As call allready throws an exception, we can return an empty array to
|
||||
// break no code.
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the public timeline
|
||||
*
|
||||
* @see http://apiwiki.twitter.com/Twitter-REST-API-Method%3A-statuses-public_timeline
|
||||
*/
|
||||
public function public_timeline() {
|
||||
return $this->get_statuses('statuses/public_timeline');
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the authenticated user's friends timeline
|
||||
*
|
||||
* @see http://apiwiki.twitter.com/Twitter-REST-API-Method%3A-statuses-friends_timeline
|
||||
*/
|
||||
public function friends_timeline($params = array()) {
|
||||
return $this->get_statuses('statuses/friends_timeline', $params, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a user's timeline
|
||||
*
|
||||
* @see http://apiwiki.twitter.com/Twitter-REST-API-Method%3A-statuses-user_timeline
|
||||
*/
|
||||
public function user_timeline($id, $params = array(), $use_auth = FALSE) {
|
||||
if (is_numeric($id)) {
|
||||
$params['user_id'] = $id;
|
||||
}
|
||||
else {
|
||||
$params['screen_name'] = $id;
|
||||
}
|
||||
|
||||
return $this->get_statuses('statuses/user_timeline', $params, $use_auth);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @see http://apiwiki.twitter.com/Twitter-REST-API-Method%3A-statuses-mentions
|
||||
*/
|
||||
public function mentions($params = array()) {
|
||||
return $this->get_statuses('statuses/mentions', $params, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @see http://apiwiki.twitter.com/Twitter-REST-API-Method%3A-statuses%C2%A0update
|
||||
*/
|
||||
public function status_update($status, $params = array()) {
|
||||
$params['status'] = $status;
|
||||
if ($this->source) {
|
||||
$params['source'] = $this->source;
|
||||
}
|
||||
$values = $this->call('statuses/update', $params, 'POST', TRUE);
|
||||
|
||||
return new TwitterStatus($values);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @see http://apiwiki.twitter.com/Twitter-REST-API-Method%3A-users%C2%A0show
|
||||
*/
|
||||
public function users_show($id, $use_auth = TRUE) {
|
||||
$params = array();
|
||||
if (is_numeric($id)) {
|
||||
$params['user_id'] = $id;
|
||||
}
|
||||
else {
|
||||
$params['screen_name'] = $id;
|
||||
}
|
||||
|
||||
$values = $this->call('users/show', $params, 'GET', $use_auth);
|
||||
return new TwitterUser($values);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @see http://apiwiki.twitter.com/Twitter-REST-API-Method%3A-account%C2%A0verify_credentials
|
||||
*/
|
||||
public function verify_credentials() {
|
||||
$values = $this->call('account/verify_credentials', array(), 'GET', TRUE);
|
||||
if (!$values) {
|
||||
return FALSE;
|
||||
}
|
||||
return new TwitterUser($values);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method for calling any twitter api resource
|
||||
*/
|
||||
public function call($path, $params = array(), $method = 'GET', $use_auth = FALSE) {
|
||||
$url = $this->create_url($path);
|
||||
|
||||
try {
|
||||
if ($use_auth) {
|
||||
$response = $this->auth_request($url, $params, $method);
|
||||
}
|
||||
else {
|
||||
$response = $this->request($url, $params, $method);
|
||||
}
|
||||
}
|
||||
catch (TwitterException $e) {
|
||||
watchdog('twitter', '!message', array('!message' => $e->__toString()), WATCHDOG_ERROR);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!$response) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return $this->parse_response($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform an authentication required request.
|
||||
*/
|
||||
protected function auth_request($path, $params = array(), $method = 'GET') {
|
||||
if (empty($this->username) || empty($this->password)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->request($path, $params, $method, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a request
|
||||
*/
|
||||
protected function request($url, $params = array(), $method = 'GET', $use_auth = FALSE) {
|
||||
$data = '';
|
||||
if (count($params) > 0) {
|
||||
if ($method == 'GET') {
|
||||
$url .= '?'. http_build_query($params, '', '&');
|
||||
}
|
||||
else {
|
||||
$data = http_build_query($params, '', '&');
|
||||
}
|
||||
}
|
||||
|
||||
$headers = array();
|
||||
|
||||
if ($use_auth) {
|
||||
$headers['Authorization'] = 'Basic '. base64_encode($this->username .':'. $this->password);
|
||||
$headers['Content-type'] = 'application/x-www-form-urlencoded';
|
||||
}
|
||||
|
||||
$response = drupal_http_request($url, array('headers' => $headers, 'method' => $method, 'data' => $data));
|
||||
if (!isset($response->error)) {
|
||||
return $response->data;
|
||||
}
|
||||
else {
|
||||
$error = $response->error;
|
||||
$data = $this->parse_response($response->data);
|
||||
if (isset($data['error'])) {
|
||||
$error = $data['error'];
|
||||
}
|
||||
throw new TwitterException($error);
|
||||
}
|
||||
}
|
||||
|
||||
protected function parse_response($response, $format = NULL) {
|
||||
if (empty($format)) {
|
||||
$format = $this->format;
|
||||
}
|
||||
|
||||
switch ($format) {
|
||||
case 'json':
|
||||
// http://drupal.org/node/985544 - json_decode large integer issue
|
||||
$length = strlen(PHP_INT_MAX);
|
||||
$response = preg_replace('/"(id|in_reply_to_status_id)":(\d{' . $length . ',})/', '"\1":"\2"', $response);
|
||||
return json_decode($response, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
protected function create_url($path, $format = NULL) {
|
||||
if (is_null($format)) {
|
||||
$format = $this->format;
|
||||
}
|
||||
$conf = TwitterConf::instance();
|
||||
$url = 'http://'. $conf->get('api') .'/'. $path;
|
||||
if (!empty($format)) {
|
||||
$url .= '.'. $this->format;
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A class to provide OAuth enabled access to the twitter API
|
||||
*/
|
||||
class TwitterOAuth extends Twitter {
|
||||
|
||||
protected $signature_method;
|
||||
|
||||
protected $consumer;
|
||||
|
||||
protected $token;
|
||||
|
||||
public function __construct($consumer_key, $consumer_secret, $oauth_token = NULL, $oauth_token_secret = NULL) {
|
||||
$this->signature_method = new OAuthSignatureMethod_HMAC_SHA1();
|
||||
$this->consumer = new OAuthConsumer($consumer_key, $consumer_secret);
|
||||
if (!empty($oauth_token) && !empty($oauth_token_secret)) {
|
||||
$this->token = new OAuthConsumer($oauth_token, $oauth_token_secret);
|
||||
}
|
||||
}
|
||||
|
||||
public function get_request_token() {
|
||||
$url = $this->create_url('oauth/request_token', '');
|
||||
try {
|
||||
$response = $this->auth_request($url);
|
||||
}
|
||||
catch (TwitterException $e) {
|
||||
}
|
||||
parse_str($response, $token);
|
||||
$this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']);
|
||||
return $token;
|
||||
}
|
||||
|
||||
public function get_authorize_url($token) {
|
||||
$url = $this->create_url('oauth/authorize', '');
|
||||
$url.= '?oauth_token=' . $token['oauth_token'];
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
public function get_authenticate_url($token) {
|
||||
$url = $this->create_url('oauth/authenticate', '');
|
||||
$url.= '?oauth_token=' . $token['oauth_token'];
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
public function get_access_token() {
|
||||
$url = $this->create_url('oauth/access_token', '');
|
||||
try {
|
||||
$response = $this->auth_request($url);
|
||||
}
|
||||
catch (TwitterException $e) {
|
||||
}
|
||||
parse_str($response, $token);
|
||||
$this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']);
|
||||
return $token;
|
||||
}
|
||||
|
||||
public function auth_request($url, $params = array(), $method = 'GET') {
|
||||
$request = OAuthRequest::from_consumer_and_token($this->consumer, $this->token, $method, $url, $params);
|
||||
$request->sign_request($this->signature_method, $this->consumer, $this->token);
|
||||
switch ($method) {
|
||||
case 'GET':
|
||||
return $this->request($request->to_url());
|
||||
case 'POST':
|
||||
return $this->request($request->get_normalized_http_url(), $request->get_parameters(), 'POST');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Twitter search is not used in this module yet
|
||||
*/
|
||||
class TwitterSearch extends Twitter {
|
||||
public function search($params = array()) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class for containing an individual twitter status.
|
||||
*/
|
||||
class TwitterStatus {
|
||||
/**
|
||||
* @var created_at
|
||||
*/
|
||||
public $created_at;
|
||||
|
||||
public $id;
|
||||
|
||||
public $text;
|
||||
|
||||
public $source;
|
||||
|
||||
public $truncated;
|
||||
|
||||
public $favorited;
|
||||
|
||||
public $in_reply_to_status_id;
|
||||
|
||||
public $in_reply_to_user_id;
|
||||
|
||||
public $in_reply_to_screen_name;
|
||||
|
||||
public $user;
|
||||
|
||||
/**
|
||||
* Constructor for TwitterStatus
|
||||
*/
|
||||
public function __construct($values = array()) {
|
||||
$this->created_at = $values['created_at'];
|
||||
$this->id = $values['id'];
|
||||
$this->text = $values['text'];
|
||||
$this->source = $values['source'];
|
||||
$this->truncated = $values['truncated'];
|
||||
$this->favorited = $values['favorited'];
|
||||
$this->in_reply_to_status_id = $values['in_reply_to_status_id'];
|
||||
$this->in_reply_to_user_id = $values['in_reply_to_user_id'];
|
||||
$this->in_reply_to_screen_name = $values['in_reply_to_screen_name'];
|
||||
if (isset($values['user'])) {
|
||||
$this->user = new TwitterUser($values['user']);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class TwitterUser {
|
||||
|
||||
public $id;
|
||||
|
||||
public $screen_name;
|
||||
|
||||
public $name;
|
||||
|
||||
public $location;
|
||||
|
||||
public $description;
|
||||
|
||||
public $followers_count;
|
||||
|
||||
public $friends_count;
|
||||
|
||||
public $statuses_count;
|
||||
|
||||
public $favourites_count;
|
||||
|
||||
public $url;
|
||||
|
||||
public $protected;
|
||||
|
||||
public $profile_image_url;
|
||||
|
||||
public $profile_background_color;
|
||||
|
||||
public $profile_text_color;
|
||||
|
||||
public $profile_link_color;
|
||||
|
||||
public $profile_sidebar_fill_color;
|
||||
|
||||
public $profile_sidebar_border_color;
|
||||
|
||||
public $profile_background_image_url;
|
||||
|
||||
public $profile_background_tile;
|
||||
|
||||
public $verified;
|
||||
|
||||
public $created_at;
|
||||
|
||||
public $created_time;
|
||||
|
||||
public $utc_offset;
|
||||
|
||||
public $status;
|
||||
|
||||
protected $password;
|
||||
|
||||
protected $oauth_token;
|
||||
|
||||
protected $oauth_token_secret;
|
||||
|
||||
public function __construct($values = array()) {
|
||||
$this->id = $values['id'];
|
||||
$this->screen_name = $values['screen_name'];
|
||||
$this->name = $values['name'];
|
||||
$this->location = $values['location'];
|
||||
$this->description = $values['description'];
|
||||
$this->url = $values['url'];
|
||||
$this->followers_count = $values['followers_count'];
|
||||
$this->friends_count = $values['friends_count'];
|
||||
$this->statuses_count = $values['statuses_count'];
|
||||
$this->favourites_count = $values['favourites_count'];
|
||||
$this->protected = $values['protected'];
|
||||
$this->profile_image_url = $values['profile_image_url'];
|
||||
$this->profile_background_color = $values['profile_background_color'];
|
||||
$this->profile_text_color = $values['profile_text_color'];
|
||||
$this->profile_link_color = $values['profile_link_color'];
|
||||
$this->profile_sidebar_fill_color = $values['profile_sidebar_fill_color'];
|
||||
$this->profile_sidebar_border_color = $values['profile_sidebar_border_color'];
|
||||
$this->profile_background_image_url = $values['profile_background_image_url'];
|
||||
$this->profile_background_tile = $values['profile_background_tile'];
|
||||
$this->verified = $values['verified'];
|
||||
$this->created_at = $values['created_at'];
|
||||
if ($values['created_at'] && $created_time = strtotime($values['created_at'])) {
|
||||
$this->created_time = $created_time;
|
||||
}
|
||||
$this->utc_offset = $values['utc_offset']?$values['utc_offset']:0;
|
||||
|
||||
if (isset($values['status'])) {
|
||||
$this->status = new TwitterStatus($values['status']);
|
||||
}
|
||||
}
|
||||
|
||||
public function get_auth() {
|
||||
return array('password' => $this->password, 'oauth_token' => $this->oauth_token, 'oauth_token_secret' => $this->oauth_token_secret);
|
||||
}
|
||||
|
||||
public function set_auth($values) {
|
||||
$this->oauth_token = isset($values['oauth_token'])?$values['oauth_token']:NULL;
|
||||
$this->oauth_token_secret = isset($values['oauth_token_secret'])?$values['oauth_token_secret']:NULL;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user