* @author Aaron Brazell * @author Keith Casey * @version 1.1 * @package php-twitter * @subpackage classes */ class twitter{ /** * Authenticating Twitter user * @var string */ var $username=''; /** * Autenticating Twitter user password * @var string */ var $password=''; /** * Recommend setting a user-agent so Twitter knows how to contact you inc case of abuse. Include your email * @var string */ var $user_agent=''; /** * Can be set to JSON (requires PHP 5.2 or the json pecl module) or XML - json|xml * @var string */ var $type='json'; /** * It is unclear if Twitter header preferences are standardized, but I would suggest using them. * More discussion at http://tinyurl.com/3xtx66 * @var array */ var $headers=array('Expect:', 'X-Twitter-Client: ','X-Twitter-Client-Version: ','X-Twitter-Client-URL: '); /** * @var array */ var $responseInfo=array(); /** * @var boolean */ var $suppress_response_code = false; /** * @var boolean */ var $debug = false; function twitter() { // Nothing } /****** Statuses ******/ /** * Send a status update to Twitter. * @param string $status total length of the status update must be 140 chars or less. * @return string|boolean */ function update( $status, $replying_to = false ) { if( !in_array( $this->type, array( 'xml','json' ) ) ) return false; $request = 'http://twitter.com/statuses/update.' . $this->type; //$status = $this->shorturl($status); $postargs = array( 'status' => $status ); if( $replying_to ) $postargs['in_reply_to_status_id'] = (int) $replying_to; return $this->objectify( $this->process($request, $postargs) ); } /** * Get @ replies * @param integer Optional. Paging of tweets. Number specifies which page of results * @param string $since (HTTP-formatted date) Optional. Narrows the resulting list of direct messages to just those sent after the specified date. * @param integer $since_id Optional. Returns results posted that have an ID greater than $since_id * @return string **/ function getReplies( $page = false, $since = false, $since_id = false ) { if( !in_array( $this->type, array( 'xml','json','rss','atom' ) ) ) return false; $args = array(); if( $page ) $args['page'] = (int) $page; if( $since ) $args['since'] = (string) $since; if( $since_id ) $args['since_id'] = (int) $since_id; $qs = ''; if( !empty( $args ) ) $qs = $this->_glue( $args ); $request = 'http://twitter.com/statuses/replies.' . $this->type . $qs; return $this->objectify( $this->process( $request ) ); } /** * Destroy a tweet * @param integer $id Required. * @return string **/ function deleteStatus( $id ) { if( !in_array( $this->type, array( 'xml','json' ) ) ) return false; $request = 'http://twitter.com/statuses/destroy/' . (int) $id . '.' . $this->type; return $this->objectify( $this->process( $request, true ) ); } /** * Send an unauthenticated request to Twitter for the public timeline. * Returns the last 20 updates by default * @param boolean|integer $sinceid Returns only public statuses with an ID greater of $sinceid * @return string */ function publicTimeline( $sinceid = false ) { if( !in_array( $this->type, array( 'xml','json','rss','atom' ) ) ) return false; $qs=''; if( $sinceid !== false ) $qs = '?since_id=' . intval($sinceid); $request = 'http://twitter.com/statuses/public_timeline.' . $this->type . $qs; return $this->objectify( $this->process($request) ); } /** * Send an authenticated request to Twitter for the timeline of authenticating user. * Returns the last 20 updates by default * @param boolean|integer $id Specifies the ID or screen name of the user for whom to return the friends_timeline. (set to false if you want to use authenticated user). * @param boolean|integer $since Narrows the returned results to just those statuses created after the specified date. * @deprecated integer $count. As of July 7 2008, Twitter has requested the limitation of the count keyword. Therefore, we deprecate * @return string */ function userTimeline($id=false,$count=20,$since=false,$since_id=false,$page=false) { if( !in_array( $this->type, array( 'xml','json','rss','atom' ) ) ) return false; $args = array(); if( $id ) $args['id'] = $id; if( $count ) $args['count'] = (int) $count; if( $since ) $args['since'] = (string) $since; if( $since_id ) $args['since_id'] = (int) $since_id; if( $page ) $args['page'] = (int) $page; $qs = ''; if( !empty( $args ) ) $qs = $this->_glue( $args ); if( $id === false ) $request = 'http://twitter.com/statuses/user_timeline.' . $this->type . $qs; else $request = 'http://twitter.com/statuses/user_timeline/' . rawurlencode($id) . '.' . $this->type . $qs; return $this->objectify( $this->process($request) ); } /** * Returns a single status, specified by the id parameter below. The status's author will be returned inline. * @param integer $id The id number of the tweet to be returned. * @return string */ function showStatus( $id ) { if( !in_array( $this->type, array( 'xml','json' ) ) ) return false; $request = 'http://twitter.com/statuses/show/'.intval($id) . '.' . $this->type; return $this->objectify( $this->process($request) ); } /** * Returns the authenticating user's friends, each with current status inline. It's also possible to request another user's friends list via the id parameter below. * @param integer|string $id Optional. The user ID or name of the Twitter user to query. * @param integer $page Optional. * @return string */ function friends( $id = false, $page = false ) { if( !in_array( $this->type, array( 'xml','json' ) ) ) return false; $args = array(); if( $id ) $args['id'] = $page; if( $page ) $args['page'] = (int) $page; $qs = ''; if( !empty( $args ) ) $qs = $this->_glue( $args ); $request = ( $id ) ? 'http://twitter.com/statuses/friends/' . $id . '.' . $this->type . $qs : 'http://twitter.com/statuses/friends.' . $this->type . $qs; return $this->objectify( $this->process($request) ); } /** * Returns the authenticating user's followers, each with current status inline. * @param integer $page Optional. * @return string */ function followers( $page = false ) { if( !in_array( $this->type, array( 'xml','json' ) ) ) return false; $request = 'http://twitter.com/statuses/followers.' . $this->type; if( $page ) $request .= '?page=' . (int) $page; return $this->objectify( $this->process($request) ); } /****** Favorites ******/ /** * Retrieves favorited tweets * @param integer|string $id Required. The username or ID of the user to be fetched * @param integer $page Optional. Tweets are returned in 20 tweet blocks. This int refers to the page/block * @return string */ function getFavorites( $id, $page=false ) { if( !in_array( $this->type, array( 'xml','json','rss','atom' ) ) ) return false; if( $page != false ) $qs = '?page=' . $page; $request = 'http://twitter.com/favorites.' . $this->type . $qs; return $this->objectify( $this->process($request) ); } /** * Favorites a tweet * @param integer $id Required. The ID number of a tweet to be added to the authenticated user favorites * @return string */ function makeFavorite( $id ) { if( !in_array( $this->type, array( 'xml','json' ) ) ) return false; $request = 'http://twitter.com/favorites/create/' . $id . '.' . $this->type; return $this->objectify( $this->process($request) ); } /** * Unfavorites a tweet * @param integer $id Required. The ID number of a tweet to be removed to the authenticated user favorites * @return string */ function removeFavorite( $id ) { if( !in_array( $this->type, array( 'xml','json' ) ) ) return false; $request = 'http://twitter.com/favorites/destroy/' . $id . '.' . $this->type; return $this->objectify( $this->process($request) ); } /****** Friendships ******/ /** * Checks to see if a friendship already exists * @param string|integer $user_a Required. The username or ID of a Twitter user * @param string|integer $user_b Required. The username or ID of a Twitter user * @return string */ function isFriend( $user_a, $user_b ) { if( !in_array( $this->type, array( 'xml','json' ) ) ) return false; $qs = '?user_a=' . rawurlencode( $user_a ) . '&' . rawurlencode( $user_b ); $request = 'http://twitter.com/friendships/exists.' . $this->type . $qs; return $this->objectify( $this->process($request) ); } /** * Sends a request to follow a user specified by ID * @param integer|string $id The twitter ID or screenname of the user to follow * @param boolean $notifications Optional. If true, you will recieve notifications from the users updates * @return string */ function followUser( $id, $notifications = false ) { if( !in_array( $this->type, array( 'xml','json' ) ) ) return false; $request = 'http://twitter.com/friendships/create/' . (int) $id . '.' . $this->type; if( $notifications ) $request .= '?follow=true'; return $this->objectify( $this->process($request) ); } /** * Unfollows a user * @param integer|string $id the username or ID of a person you want to unfollow * @return string */ function leaveUser( $id ) { if( !in_array( $this->type, array( 'xml','json' ) ) ) return false; $request = 'http://twitter.com/friendships/destroy/' . $id . '.' . $this->type; return $this->objectify( $this->process($request) ); } /****** Blocks ******/ /** * Blocks a user * @param integer|string $id the username or ID of a person you want to block * @return string */ function blockUser( $id ) { if( !in_array( $this->type, array( 'xml','json' ) ) ) return false; $request = 'http://twitter.com/blocks/create/' . $id . '.' . $this->type; return $this->objectify( $this->process($request) ); } /** * Unblocks a user * @param integer|string $id the username or ID of a person you want to unblock * @return string */ function unblockUser() { if( !in_array( $this->type, array( 'xml','json' ) ) ) return false; $request = 'http://twitter.com/blocks/destroy/' . $id . '.' . $this->type; return $this->objectify( $this->process($request) ); } /****** Social Graph ******/ /** * Returns a list of IDs of all friends for the specified user * @param integer $id Required. User ID to request list of friend IDs for * return string */ /* @todo same as friends()? */ function socialGraphFollowing( $id = false) { if( !in_array( $this->type, array( 'xml','json' ) ) ) return false; $request = 'http://twitter.com/friends/ids'; if( $id ) $request .= '/' . (int) $id . '.' . $this->type; return $this->objectify( $this->process($request) ); } /** * Returns a list of IDs of all followers for the specified user * @param integer $id Required. User ID to request list of friend IDs for * return string */ /* @todo same as followers() */ function socialGraphFollowedBy( $id = false ) { if( !in_array( $this->type, array( 'xml','json' ) ) ) return false; $request = 'http://twitter.com/followers/ids'; if( $id ) $request .= '/' . (int) $id . '.' . $this->type; return $this->objectify( $this->process($request) ); } /****** Users ******/ /** * Returns extended information of a given user, specified by ID or screen name as per the required * id parameter below. This information includes design settings, so third party developers can theme * their widgets according to a given user's preferences. * @param integer $id Optional. The user ID. * @param string $email Optional. The email address of the user being requested (can use in place of $id) * @param integer $user_id Optional. The user ID (can use in place of $id) * @param string $screen_name Optional. The screen name of the user being requested (can use in place of $id) * @return string */ function showUser( $id, $email = false, $user_id = false, $screen_name=false ) { if( !in_array( $this->type, array( 'xml','json' ) ) ) return false; if( $user_id ) : $qs = '?user_id=' . (int) $user_id; elseif ( $screen_name ) : $qs = '?screen_name=' . (string) $screen_name; elseif ( $email ) : $qs = '?email=' . (string) $email; else : $qs = (int) $id; endif; $request = 'http://twitter.com/users/show/' . $qs . $this->type; return $this->objectify( $this->process($request) ); } /****** Direct Messages ******/ /** * Returns a list of the direct messages sent to the authenticating user. * @param string $since (HTTP-formatted date) Optional. Narrows the resulting list of direct messages to just those sent after the specified date. * @param int $count DEPRECATED. Remains for Backwards Compat * @param integer $since_id * @param integer $page * @deprecated $count * @return string */ function directMessages( $since = false, $count = null, $since_id = false, $page = false ) { if( !in_array( $this->type, array( 'xml','json','rss','atom' ) ) ) return false; $qs='?'; $qsparams = array(); if( $since !== false ) $qsparams['since'] = '?since='.rawurlencode($since); if( $since_id != false ) $qsparams['since_id'] = '?since_id='.(int) $since_id; if( $page != false) $qsparams['page'] = '?page='.(int) $page; $request = 'http://twitter.com/direct_messages.' . $this->type . implode( '&', $qsparams ); return $this->objectify( $this->process($request) ); } /** * Returns a list of the sent direct messages from the authenticating user. * @param string $since (HTTP-formatted date) Optional. Narrows the resulting list of direct messages to just those sent after the specified date. * @param integer $since_id * @param integer $page * @deprecated $count * @return string */ function sentDirectMessage( $since = false, $since_id = false, $page = false ) { if( !in_array( $this->type, array( 'xml','json' ) ) ) return false; $qs = '?'; $qsparams = array(); if( $since !== false ) $qsparams['since'] = rawurlencode($since); if( $since_id ) $qsparams['since_id'] = (int) $since_id; if( $page ) $qsparams['page'] = (int) $page; $request = 'http://twitter.com/direct_messages/sent.' . $this->type . implode( '&', $qsparams ); return $this->objectify( $this->process($request) ); } /** * Sends a new direct message to the specified user from the authenticating user. Requires both the user * and text parameters below. * @param string|integer Required. The ID or screen name of the recipient user. * @param string $user The text of your direct message. Be sure to URL encode as necessary, and keep it under 140 characters. * @return string */ function sendDirectMessage( $user, $text ) { if( !in_array( $this->type, array( 'xml','json' ) ) ) return false; $request = 'http://twitter.com/direct_messages/new.' . $this->type; $postargs = 'user=' . rawurlencode($user) . '&text=' . rawurlencode($text); return $this->objectify( $this->process($request, $postargs) ); } /** * Deletes a direct message * @param integer $id Required * @return string */ function deleteDirectMessage( $id ) { if( !in_array( $this->type, array( 'xml','json' ) ) ) return false; $request = 'http://twitter.com/direct_messages/destroy/' . (int) $id . '.' . $this->type; return $this->objectify( $this->process( $request ) ); } /****** Account ******/ /** * Updates delivery device * @param string $device Required. Must be of type 'im', 'sms' or 'none' * @return string */ function updateDevice( $device ) { if( !in_array( $this->type, array( 'xml','json' ) ) ) return false; if( !in_array( $device, array('im','sms','none') ) ) return false; $qs = '?device=' . $device; $request = 'http://twitter.com/account/update_delivery_device.' . $this->type . $qs; return $this->objectify( $this->process( $request ) ); } /** * @param binary Required. Use your script to pass a binary image (GIF, JPG, PNG <700kb) to update Twitter profile avatar * @return string */ function updateAvatar( $file ) { if( !in_array( $this->type, array( 'xml','json' ) ) ) return false; // Adding @ ensures the POST will be raw multipart data encoded. This MUST be a file, not a URL. Handle it outside of the class. $postdata = array( 'image' => "@$file"); $request = 'http://twitter.com/account/update_profile_image.' . $this->type; return $this->objectify( $this->process( $request, $postdata ) ); } /** * @param binary Required. Use your script to pass a binary image (GIF, JPG, PNG <800kb) to update Twitter profile avatar. Images over 2048px wide will be scaled down * @return string */ function updateBackground( $file ) { if( !in_array( $this->type, array( 'xml','json' ) ) ) return false; // Adding @ ensures the POST will be raw multipart data encoded. This MUST be a file, not a URL. Handle it outside of the class. $postdata = array( 'image' => "@$file"); $request = 'http://twitter.com/account/update_profile_background_image.' . $this->type; return $this->objectify( $this->process( $request, $postdata ) ); } /** * @param array Requires. Pass an array of all optional members: name, email, url, location, or description. Email address must be valid if passed. Refer to Twitter RESTful API instructions on length allowed for other members * @return string */ function updateProfile( $fields = array() ) { if( !in_array( $this->type, array( 'xml','json' ) ) ) return false; $postdata = array(); foreach( $fields as $pk => $pv ) : switch( $pk ) { case 'name' : $postdata[$pk] = (string) substr( $pv, 0, 20 ); break; case 'email' : if( preg_match( '/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b/i', $pv ) ) $postdata[$pk] = (string) $pv; break; case 'url' : $postdata[$pk] = (string) substr( $pv, 0, 100 ); break; case 'location' : $postdata[$pk] = (string) substr( $pv, 0, 30 ); break; case 'description' : $postdata[$pk] = (string) substr( $pv, 0, 160 ); break; default : break; } endforeach; $request = 'http://twitter.com/account/update_profile.' . $this->type; return $this->objectify( $this->process( $request, $postdata ) ); } /** * Pass an array of values to Twitter to update Twitter profile colors * @param array Required. All array members are optional. Optional color fields are: profile_background_color, profile_text_color, profile_link_color, profile_sidebar_fill_color, profile_sidebar_border_color * @return string */ function updateColors( $colors = array() ) { if( !in_array( $this->type, array( 'xml','json' ) ) ) return false; $postdata = array(); foreach( $colors as $ck => $cv ) : if( preg_match('/^(?:(?:[a-f\d]{3}){1,2})$/i', $hex) ) : $postdata[$ck] = (string) $cv; endif; endforeach; $request = 'http://twitter.com/account/update_profile_colors.' . $this->type; return $this->objectify( $this->process( $request, $postdata ) ); } /** * Rate Limit API Call. Sometimes Twitter needs to degrade. Use this non-ratelimited API call to work your logic out * @return integer|boolean */ function ratelimit() { if( !in_array( $this->type, array( 'xml','json' ) ) ) return false; $request = 'http://twitter.com/account/rate_limit_status.' . $this->type; return $this->objectify( $out ); } /** * Rate Limit statuses (extended). Provides helper data like remaining-hits, hourly limit, reset time and reset time in seconds * @deprecated */ function ratelimit_status() { return $this->ratelimit(); } /****** Tests ******/ /** * Detects if Twitter is up or down. Chances are, it will be down. ;-) Here's a hint - display CPM ads whenever Twitter is down * @return boolean */ function twitterAvailable() { if( !in_array( $this->type, array( 'xml','json' ) ) ) return false; $request = 'http://twitter.com/help/test.' . $this->type; if( $this->objectify( $this->process($request) ) == 'ok' ) return true; return false; } /** * Any prescheduled maintenance? * @deprecated * @return false */ function maintenanceSchedule() { return false; } /****** Private and Helpers Methods ******/ /** * Uses the http://is.gd API to produce a shortened URL. Pluggable by extending the twitter class * @param string $url The URL needing to be shortened * @return string */ function shorturl( $url ) { // Using is.gd because it's good $request = 'http://is.gd/api.php?longurl=' . $url; return $this->process( $request ); } /** * Internal function where all the juicy curl fun takes place * this should not be called by anything external unless you are * doing something else completely then knock youself out. * @access private * @param string $url Required. API URL to request * @param string $postargs Optional. Urlencoded query string to append to the $url */ function process($url,$postargs=false) { $url = ( $this->suppress_response_code ) ? $url . '&suppress_response_code=true' : $url; $ch = curl_init($url); if($postargs !== false) { curl_setopt ($ch, CURLOPT_POST, true); curl_setopt ($ch, CURLOPT_POSTFIELDS, $postargs); } if($this->username !== false && $this->password !== false) curl_setopt($ch, CURLOPT_USERPWD, $this->username.':'.$this->password ); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_VERBOSE, 1); curl_setopt($ch, CURLOPT_NOBODY, 0); if( $this->debug ) : curl_setopt($ch, CURLOPT_HEADER, true); else : curl_setopt($ch, CURLOPT_HEADER, false); endif; curl_setopt($ch, CURLOPT_USERAGENT, $this->user_agent); @curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1); curl_setopt($ch, CURLOPT_HTTPHEADER, $this->headers); $response = curl_exec($ch); $this->responseInfo=curl_getinfo($ch); curl_close($ch); if( $this->debug ) : $debug = preg_split("#\n\s*\n|\r\n\s*\r\n#m", $response); echo'
' . $debug[0] . '
'; exit; endif; if( intval( $this->responseInfo['http_code'] ) == 200 ) return $response; else return false; } /***DEPRECATED***/ /** * Returns a list of the users currently featured on the site with their current statuses inline. * @deprecated * @return string */ function featured() { return false; } /** * Updates Geo location * @deprecated * @param string $location Required. * @return string */ function updateLocation( $location ) { return $this->updateProfile( array( 'location' => $location ) ); } /** * Send an authenticated request to Twitter for the timeline of authenticating users friends. * Returns the last 20 updates by default * @deprecated true * @param boolean|integer $id Specifies the ID or screen name of the user for whom to return the friends_timeline. (set to false if you want to use authenticated user). * @param boolean|integer $since Narrows the returned results to just those statuses created after the specified date. * @return string */ function friendsTimeline( $id = false, $since = false, $since_id = false, $count = 20, $page = false ) { return $this->userTimeline( $id, $count, $since, $since_id, $page ); } /** * Function to prepare data for return to client * @access private * @param string $data */ function objectify( $data ) { if( $this->type == 'json' ) return json_decode( $data ); else if( $this->type == 'xml' ) { if( function_exists('simplexml_load_string') ) : $obj = simplexml_load_string( $data ); endif; return $obj; } else return false; } /** * Function to piece together a cohesive query string * @access private * @param array $array * @return string */ function _glue( $array ) { $query_string = ''; foreach( $array as $key => $val ) : $query_string .= $key . '=' . rawurlencode( $val ) . '&'; endforeach; return '?' . substr( $query_string, 0, strlen( $query_string )-1 ); } } /** * Wrapper class around the Twitter Search (formerly, and affectionately known as Summize) * @author Aaron Brazell * @author Keith Casey * @version 1.1 * @package php-twitter * @subpackage classes */ class summize extends twitter { /** * Can be set to JSON (requires PHP 5.2 or the json pecl module) or Atom - json|atom * @var string */ var $stype='json'; function search( $terms=false, $callback=false ) { if( !$terms ) return false; $qs = array(); $request = 'http://search.twitter.com/search.' . $this->stype; $qs[] = 'q=' . rawurlencode( $terms ); if( $callback && $this->stype == 'json' ) $qs[] = 'callback=' . $callback; return $this->objectify( $this->process($request . '?' . implode('&',$qs) ) ); } function trends( $callback = false ) { $qs = ( $callback ) ? '?callback=' . $callback : ''; $request = 'http://search.twitter.com/trends.' . $this->stype . $qs; return $this->objectify( $this->process( $request ) ); } } ?>