twitter.lib.php in Twitter 6.3
Same filename and directory in other branches
Classes to implement the full Twitter API
File
twitter.lib.phpView source
<?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 {
/**
* Overrides constructor to log the error.
*/
public function __construct($message = NULL, $code = 0, Exception $previous = NULL) {
watchdog('twitter', 'Unexpected error: @message', array(
'@message' => $message,
), WATCHDOG_ERROR);
if (is_null($previous)) {
parent::__construct($message, $code);
}
else {
parent::__construct($message, $code, $previous);
}
}
}
/**
* 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) {
$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;
}
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);
}
/**
* Post a new status.
*
* @see https://dev.twitter.com/docs/api/1/post/statuses/update
*/
public function status_update($status, $params = array()) {
$params['status'] = $status;
if ($this->source) {
$params['source'] = $this->source;
}
if ($values = $this
->call('statuses/update', $params, 'POST', TRUE)) {
return new TwitterStatus($values);
}
}
/**
* Returns profile information about a user.
*
* @see https://dev.twitter.com/docs/api/1/get/users/show
*/
public function users_show($id, $use_auth = TRUE) {
$params = array();
if (is_numeric($id)) {
$params['user_id'] = $id;
}
else {
$params['screen_name'] = $id;
}
if ($values = $this
->call('users/show', $params, 'GET', $use_auth)) {
return new TwitterUser($values);
}
}
/**
*
* @see https://dev.twitter.com/docs/api/1/get/account/verify_credentials
*/
public function verify_credentials() {
if ($values = $this
->call('account/verify_credentials', array(), 'GET', TRUE)) {
return new TwitterUser($values);
}
}
/**
* Calls a twitter api resource
*
* @param $path
* string REST resource to be called
* @param $params
* array of settings to be sent along
* @param $method
* string method to be used (GET or POST)
* @param $use_oauth
* boolean indicating if the call should use OAuth authentication of not
*/
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);
drupal_set_message('Twitter returned an error: ' . $e
->getMessage(), '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, $headers, $method, $data);
if (!property_exists($response, 'error')) {
return $response->data;
}
else {
$error = $response->error;
$data = $this
->parse_response($response->data);
if ($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':
$response_decoded = json_decode($response, TRUE);
if (isset($response_decoded['id_str'])) {
// if we're getting a single object back as JSON
$response_decoded['id'] = $response_decoded['id_str'];
}
else {
// if we're getting an array of objects back as JSON
foreach ($response_decoded as &$item) {
$item['id'] = $item['id_str'];
}
}
return $response_decoded;
}
}
protected function create_url($path, $format = NULL) {
if (is_null($format)) {
$format = $this->format;
}
$conf = TwitterConf::instance();
$url = 'http://' . $conf
->get('api') . '/1/' . $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);
}
}
protected function create_oauth_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;
}
public function get_request_token() {
$url = $this
->create_oauth_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_oauth_url('oauth/authorize', '');
$url .= '?oauth_token=' . $token['oauth_token'];
return $url;
}
public function get_authenticate_url($token) {
$url = $this
->create_oauth_url('oauth/authenticate', '');
$url .= '?oauth_token=' . $token['oauth_token'];
return $url;
}
public function get_access_token() {
$url = $this
->create_oauth_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 $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(
'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;
}
}
Classes
Name | Description |
---|---|
Primary Twitter API implementation class Supports the full REST API for twitter. | |
TwitterConf | Class TwitterConfig |
TwitterException | Exception handling class. |
TwitterOAuth | A class to provide OAuth enabled access to the twitter API |
TwitterSearch | Twitter search is not used in this module yet |
TwitterStatus | Class for containing an individual twitter status. |
TwitterUser |