web/enmi/Zend/Service/Twitter.php
changeset 19 1c2f13fd785c
parent 0 4eba9c11703f
equal deleted inserted replaced
18:bd595ad770fc 19:1c2f13fd785c
       
     1 <?php
       
     2 /**
       
     3  * Zend Framework
       
     4  *
       
     5  * LICENSE
       
     6  *
       
     7  * This source file is subject to the new BSD license that is bundled
       
     8  * with this package in the file LICENSE.txt.
       
     9  * It is also available through the world-wide-web at this URL:
       
    10  * http://framework.zend.com/license/new-bsd
       
    11  * If you did not receive a copy of the license and are unable to
       
    12  * obtain it through the world-wide-web, please send an email
       
    13  * to license@zend.com so we can send you a copy immediately.
       
    14  *
       
    15  * @category   Zend
       
    16  * @package    Zend_Service
       
    17  * @subpackage Twitter
       
    18  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    19  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    20  * @version    $Id: Twitter.php 23312 2010-11-08 19:45:00Z matthew $
       
    21  */
       
    22 
       
    23 /**
       
    24  * @see Zend_Rest_Client
       
    25  */
       
    26 require_once 'Zend/Rest/Client.php';
       
    27 
       
    28 /**
       
    29  * @see Zend_Rest_Client_Result
       
    30  */
       
    31 require_once 'Zend/Rest/Client/Result.php';
       
    32 
       
    33 /**
       
    34  * @see Zend_Oauth_Consumer
       
    35  */
       
    36 require_once 'Zend/Oauth/Consumer.php';
       
    37 
       
    38 /**
       
    39  * @category   Zend
       
    40  * @package    Zend_Service
       
    41  * @subpackage Twitter
       
    42  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    43  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    44  */
       
    45 class Zend_Service_Twitter extends Zend_Rest_Client
       
    46 {
       
    47 
       
    48     /**
       
    49      * 246 is the current limit for a status message, 140 characters are displayed
       
    50      * initially, with the remainder linked from the web UI or client. The limit is
       
    51      * applied to a html encoded UTF-8 string (i.e. entities are counted in the limit
       
    52      * which may appear unusual but is a security measure).
       
    53      *
       
    54      * This should be reviewed in the future...
       
    55      */
       
    56     const STATUS_MAX_CHARACTERS = 246;
       
    57     
       
    58     /**
       
    59      * OAuth Endpoint
       
    60      */
       
    61     const OAUTH_BASE_URI = 'http://twitter.com/oauth';
       
    62     
       
    63     /**
       
    64      * @var Zend_Http_CookieJar
       
    65      */
       
    66     protected $_cookieJar;
       
    67     
       
    68     /**
       
    69      * Date format for 'since' strings
       
    70      *
       
    71      * @var string
       
    72      */
       
    73     protected $_dateFormat = 'D, d M Y H:i:s T';
       
    74     
       
    75     /**
       
    76      * Username
       
    77      *
       
    78      * @var string
       
    79      */
       
    80     protected $_username;
       
    81     
       
    82     /**
       
    83      * Current method type (for method proxying)
       
    84      *
       
    85      * @var string
       
    86      */
       
    87     protected $_methodType;
       
    88     
       
    89     /**
       
    90      * Zend_Oauth Consumer
       
    91      *
       
    92      * @var Zend_Oauth_Consumer
       
    93      */
       
    94     protected $_oauthConsumer = null;
       
    95     
       
    96     /**
       
    97      * Types of API methods
       
    98      *
       
    99      * @var array
       
   100      */
       
   101     protected $_methodTypes = array(
       
   102         'status',
       
   103         'user',
       
   104         'directMessage',
       
   105         'friendship',
       
   106         'account',
       
   107         'favorite',
       
   108         'block'
       
   109     );
       
   110     
       
   111     /**
       
   112      * Options passed to constructor
       
   113      *
       
   114      * @var array
       
   115      */
       
   116     protected $_options = array();
       
   117 
       
   118     /**
       
   119      * Local HTTP Client cloned from statically set client
       
   120      *
       
   121      * @var Zend_Http_Client
       
   122      */
       
   123     protected $_localHttpClient = null;
       
   124 
       
   125     /**
       
   126      * Constructor
       
   127      *
       
   128      * @param  array $options Optional options array
       
   129      * @return void
       
   130      */
       
   131     public function __construct($options = null, Zend_Oauth_Consumer $consumer = null)
       
   132     {
       
   133         $this->setUri('http://api.twitter.com');
       
   134         if (!is_array($options)) $options = array();
       
   135         $options['siteUrl'] = self::OAUTH_BASE_URI;
       
   136         if ($options instanceof Zend_Config) {
       
   137             $options = $options->toArray();
       
   138         }
       
   139         $this->_options = $options;
       
   140         if (isset($options['username'])) {
       
   141             $this->setUsername($options['username']);
       
   142         }
       
   143         if (isset($options['accessToken'])
       
   144         && $options['accessToken'] instanceof Zend_Oauth_Token_Access) {
       
   145             $this->setLocalHttpClient($options['accessToken']->getHttpClient($options));
       
   146         } else {
       
   147             $this->setLocalHttpClient(clone self::getHttpClient());
       
   148             if ($consumer === null) {
       
   149                 $this->_oauthConsumer = new Zend_Oauth_Consumer($options);
       
   150             } else {
       
   151                 $this->_oauthConsumer = $consumer;
       
   152             }
       
   153         }
       
   154     }
       
   155 
       
   156     /**
       
   157      * Set local HTTP client as distinct from the static HTTP client
       
   158      * as inherited from Zend_Rest_Client.
       
   159      *
       
   160      * @param Zend_Http_Client $client
       
   161      * @return self
       
   162      */
       
   163     public function setLocalHttpClient(Zend_Http_Client $client)
       
   164     {
       
   165         $this->_localHttpClient = $client;
       
   166         $this->_localHttpClient->setHeaders('Accept-Charset', 'ISO-8859-1,utf-8');
       
   167         return $this;
       
   168     }
       
   169     
       
   170     /**
       
   171      * Get the local HTTP client as distinct from the static HTTP client
       
   172      * inherited from Zend_Rest_Client
       
   173      *
       
   174      * @return Zend_Http_Client
       
   175      */
       
   176     public function getLocalHttpClient()
       
   177     {
       
   178         return $this->_localHttpClient;
       
   179     }
       
   180     
       
   181     /**
       
   182      * Checks for an authorised state
       
   183      *
       
   184      * @return bool
       
   185      */
       
   186     public function isAuthorised()
       
   187     {
       
   188         if ($this->getLocalHttpClient() instanceof Zend_Oauth_Client) {
       
   189             return true;
       
   190         }
       
   191         return false;
       
   192     }
       
   193 
       
   194     /**
       
   195      * Retrieve username
       
   196      *
       
   197      * @return string
       
   198      */
       
   199     public function getUsername()
       
   200     {
       
   201         return $this->_username;
       
   202     }
       
   203 
       
   204     /**
       
   205      * Set username
       
   206      *
       
   207      * @param  string $value
       
   208      * @return Zend_Service_Twitter
       
   209      */
       
   210     public function setUsername($value)
       
   211     {
       
   212         $this->_username = $value;
       
   213         return $this;
       
   214     }
       
   215 
       
   216     /**
       
   217      * Proxy service methods
       
   218      *
       
   219      * @param  string $type
       
   220      * @return Zend_Service_Twitter
       
   221      * @throws Zend_Service_Twitter_Exception If method not in method types list
       
   222      */
       
   223     public function __get($type)
       
   224     {
       
   225         if (!in_array($type, $this->_methodTypes)) {
       
   226             include_once 'Zend/Service/Twitter/Exception.php';
       
   227             throw new Zend_Service_Twitter_Exception(
       
   228                 'Invalid method type "' . $type . '"'
       
   229             );
       
   230         }
       
   231         $this->_methodType = $type;
       
   232         return $this;
       
   233     }
       
   234 
       
   235     /**
       
   236      * Method overloading
       
   237      *
       
   238      * @param  string $method
       
   239      * @param  array $params
       
   240      * @return mixed
       
   241      * @throws Zend_Service_Twitter_Exception if unable to find method
       
   242      */
       
   243     public function __call($method, $params)
       
   244     {
       
   245         if (method_exists($this->_oauthConsumer, $method)) {
       
   246             $return = call_user_func_array(array($this->_oauthConsumer, $method), $params);
       
   247             if ($return instanceof Zend_Oauth_Token_Access) {
       
   248                 $this->setLocalHttpClient($return->getHttpClient($this->_options));
       
   249             }
       
   250             return $return;
       
   251         }
       
   252         if (empty($this->_methodType)) {
       
   253             include_once 'Zend/Service/Twitter/Exception.php';
       
   254             throw new Zend_Service_Twitter_Exception(
       
   255                 'Invalid method "' . $method . '"'
       
   256             );
       
   257         }
       
   258         $test = $this->_methodType . ucfirst($method);
       
   259         if (!method_exists($this, $test)) {
       
   260             include_once 'Zend/Service/Twitter/Exception.php';
       
   261             throw new Zend_Service_Twitter_Exception(
       
   262                 'Invalid method "' . $test . '"'
       
   263             );
       
   264         }
       
   265 
       
   266         return call_user_func_array(array($this, $test), $params);
       
   267     }
       
   268 
       
   269     /**
       
   270      * Initialize HTTP authentication
       
   271      *
       
   272      * @return void
       
   273      */
       
   274     protected function _init()
       
   275     {
       
   276         if (!$this->isAuthorised() && $this->getUsername() !== null) {
       
   277             require_once 'Zend/Service/Twitter/Exception.php';
       
   278             throw new Zend_Service_Twitter_Exception(
       
   279                 'Twitter session is unauthorised. You need to initialize '
       
   280                 . 'Zend_Service_Twitter with an OAuth Access Token or use '
       
   281                 . 'its OAuth functionality to obtain an Access Token before '
       
   282                 . 'attempting any API actions that require authorisation'
       
   283             );
       
   284         }
       
   285         $client = $this->_localHttpClient;
       
   286         $client->resetParameters();
       
   287         if (null == $this->_cookieJar) {
       
   288             $client->setCookieJar();
       
   289             $this->_cookieJar = $client->getCookieJar();
       
   290         } else {
       
   291             $client->setCookieJar($this->_cookieJar);
       
   292         }
       
   293     }
       
   294 
       
   295     /**
       
   296      * Set date header
       
   297      *
       
   298      * @param  int|string $value
       
   299      * @deprecated Not supported by Twitter since April 08, 2009
       
   300      * @return void
       
   301      */
       
   302     protected function _setDate($value)
       
   303     {
       
   304         if (is_int($value)) {
       
   305             $date = date($this->_dateFormat, $value);
       
   306         } else {
       
   307             $date = date($this->_dateFormat, strtotime($value));
       
   308         }
       
   309         $this->_localHttpClient->setHeaders('If-Modified-Since', $date);
       
   310     }
       
   311 
       
   312     /**
       
   313      * Public Timeline status
       
   314      *
       
   315      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   316      * @return Zend_Rest_Client_Result
       
   317      */
       
   318     public function statusPublicTimeline()
       
   319     {
       
   320         $this->_init();
       
   321         $path = '/1/statuses/public_timeline.xml';
       
   322         $response = $this->_get($path);
       
   323         return new Zend_Rest_Client_Result($response->getBody());
       
   324     }
       
   325 
       
   326     /**
       
   327      * Friend Timeline Status
       
   328      *
       
   329      * $params may include one or more of the following keys
       
   330      * - id: ID of a friend whose timeline you wish to receive
       
   331      * - count: how many statuses to return
       
   332      * - since_id: return results only after the specific tweet
       
   333      * - page: return page X of results
       
   334      *
       
   335      * @param  array $params
       
   336      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   337      * @return void
       
   338      */
       
   339     public function statusFriendsTimeline(array $params = array())
       
   340     {
       
   341         $this->_init();
       
   342         $path = '/1/statuses/friends_timeline';
       
   343         $_params = array();
       
   344         foreach ($params as $key => $value) {
       
   345             switch (strtolower($key)) {
       
   346                 case 'count':
       
   347                     $count = (int) $value;
       
   348                     if (0 >= $count) {
       
   349                         $count = 1;
       
   350                     } elseif (200 < $count) {
       
   351                         $count = 200;
       
   352                     }
       
   353                     $_params['count'] = (int) $count;
       
   354                     break;
       
   355                 case 'since_id':
       
   356                     $_params['since_id'] = $this->_validInteger($value);
       
   357                     break;
       
   358                 case 'page':
       
   359                     $_params['page'] = (int) $value;
       
   360                     break;
       
   361                 default:
       
   362                     break;
       
   363             }
       
   364         }
       
   365         $path .= '.xml';
       
   366         $response = $this->_get($path, $_params);
       
   367         return new Zend_Rest_Client_Result($response->getBody());
       
   368     }
       
   369 
       
   370     /**
       
   371      * User Timeline status
       
   372      *
       
   373      * $params may include one or more of the following keys
       
   374      * - id: ID of a friend whose timeline you wish to receive
       
   375      * - since_id: return results only after the tweet id specified
       
   376      * - page: return page X of results
       
   377      * - count: how many statuses to return
       
   378      * - max_id: returns only statuses with an ID less than or equal to the specified ID
       
   379      * - user_id: specifies the ID of the user for whom to return the user_timeline
       
   380      * - screen_name: specfies the screen name of the user for whom to return the user_timeline
       
   381      * - include_rts: whether or not to return retweets
       
   382      * - trim_user: whether to return just the user ID or a full user object; omit to return full object
       
   383      * - include_entities: whether or not to return entities nodes with tweet metadata
       
   384      *
       
   385      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   386      * @return Zend_Rest_Client_Result
       
   387      */
       
   388     public function statusUserTimeline(array $params = array())
       
   389     {
       
   390         $this->_init();
       
   391         $path = '/1/statuses/user_timeline';
       
   392         $_params = array();
       
   393         foreach ($params as $key => $value) {
       
   394             switch (strtolower($key)) {
       
   395                 case 'id':
       
   396                     $path .= '/' . $value;
       
   397                     break;
       
   398                 case 'page':
       
   399                     $_params['page'] = (int) $value;
       
   400                     break;
       
   401                 case 'count':
       
   402                     $count = (int) $value;
       
   403                     if (0 >= $count) {
       
   404                         $count = 1;
       
   405                     } elseif (200 < $count) {
       
   406                         $count = 200;
       
   407                     }
       
   408                     $_params['count'] = $count;
       
   409                     break;
       
   410                 case 'user_id':
       
   411                     $_params['user_id'] = $this->_validInteger($value);
       
   412                     break;
       
   413                 case 'screen_name':
       
   414                     $_params['screen_name'] = $this->_validateScreenName($value);
       
   415                     break;
       
   416                 case 'since_id':
       
   417                     $_params['since_id'] = $this->_validInteger($value);
       
   418                     break;
       
   419                 case 'max_id':
       
   420                     $_params['max_id'] = $this->_validInteger($value);
       
   421                     break;
       
   422                 case 'include_rts':
       
   423                 case 'trim_user':
       
   424                 case 'include_entities':
       
   425                     $_params[strtolower($key)] = $value ? '1' : '0';
       
   426                     break;
       
   427                 default:
       
   428                     break;
       
   429             }
       
   430         }
       
   431         $path .= '.xml';
       
   432         $response = $this->_get($path, $_params);
       
   433         return new Zend_Rest_Client_Result($response->getBody());
       
   434     }
       
   435 
       
   436     /**
       
   437      * Show a single status
       
   438      *
       
   439      * @param  int $id Id of status to show
       
   440      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   441      * @return Zend_Rest_Client_Result
       
   442      */
       
   443     public function statusShow($id)
       
   444     {
       
   445         $this->_init();
       
   446         $path = '/1/statuses/show/' . $this->_validInteger($id) . '.xml';
       
   447         $response = $this->_get($path);
       
   448         return new Zend_Rest_Client_Result($response->getBody());
       
   449     }
       
   450 
       
   451     /**
       
   452      * Update user's current status
       
   453      *
       
   454      * @param  string $status
       
   455      * @param  int $in_reply_to_status_id
       
   456      * @return Zend_Rest_Client_Result
       
   457      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   458      * @throws Zend_Service_Twitter_Exception if message is too short or too long
       
   459      */
       
   460     public function statusUpdate($status, $inReplyToStatusId = null)
       
   461     {
       
   462         $this->_init();
       
   463         $path = '/1/statuses/update.xml';
       
   464         $len = iconv_strlen(htmlspecialchars($status, ENT_QUOTES, 'UTF-8'), 'UTF-8');
       
   465         if ($len > self::STATUS_MAX_CHARACTERS) {
       
   466             include_once 'Zend/Service/Twitter/Exception.php';
       
   467             throw new Zend_Service_Twitter_Exception(
       
   468                 'Status must be no more than '
       
   469                 . self::STATUS_MAX_CHARACTERS
       
   470                 . ' characters in length'
       
   471             );
       
   472         } elseif (0 == $len) {
       
   473             include_once 'Zend/Service/Twitter/Exception.php';
       
   474             throw new Zend_Service_Twitter_Exception(
       
   475                 'Status must contain at least one character'
       
   476             );
       
   477         }
       
   478         $data = array('status' => $status);
       
   479         if (is_numeric($inReplyToStatusId) && !empty($inReplyToStatusId)) {
       
   480             $data['in_reply_to_status_id'] = $inReplyToStatusId;
       
   481         }
       
   482         $response = $this->_post($path, $data);
       
   483         return new Zend_Rest_Client_Result($response->getBody());
       
   484     }
       
   485 
       
   486     /**
       
   487      * Get status replies
       
   488      *
       
   489      * $params may include one or more of the following keys
       
   490      * - since_id: return results only after the specified tweet id
       
   491      * - page: return page X of results
       
   492      *
       
   493      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   494      * @return Zend_Rest_Client_Result
       
   495      */
       
   496     public function statusReplies(array $params = array())
       
   497     {
       
   498         $this->_init();
       
   499         $path = '/1/statuses/mentions.xml';
       
   500         $_params = array();
       
   501         foreach ($params as $key => $value) {
       
   502             switch (strtolower($key)) {
       
   503                 case 'since_id':
       
   504                     $_params['since_id'] = $this->_validInteger($value);
       
   505                     break;
       
   506                 case 'page':
       
   507                     $_params['page'] = (int) $value;
       
   508                     break;
       
   509                 default:
       
   510                     break;
       
   511             }
       
   512         }
       
   513         $response = $this->_get($path, $_params);
       
   514         return new Zend_Rest_Client_Result($response->getBody());
       
   515     }
       
   516 
       
   517     /**
       
   518      * Destroy a status message
       
   519      *
       
   520      * @param  int $id ID of status to destroy
       
   521      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   522      * @return Zend_Rest_Client_Result
       
   523      */
       
   524     public function statusDestroy($id)
       
   525     {
       
   526         $this->_init();
       
   527         $path = '/1/statuses/destroy/' . $this->_validInteger($id) . '.xml';
       
   528         $response = $this->_post($path);
       
   529         return new Zend_Rest_Client_Result($response->getBody());
       
   530     }
       
   531 
       
   532     /**
       
   533      * User friends
       
   534      *
       
   535      * @param  int|string $id Id or username of user for whom to fetch friends
       
   536      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   537      * @return Zend_Rest_Client_Result
       
   538      */
       
   539     public function userFriends(array $params = array())
       
   540     {
       
   541         $this->_init();
       
   542         $path = '/1/statuses/friends';
       
   543         $_params = array();
       
   544 
       
   545         foreach ($params as $key => $value) {
       
   546             switch (strtolower($key)) {
       
   547                 case 'id':
       
   548                     $path .= '/' . $value;
       
   549                     break;
       
   550                 case 'page':
       
   551                     $_params['page'] = (int) $value;
       
   552                     break;
       
   553                 default:
       
   554                     break;
       
   555             }
       
   556         }
       
   557         $path .= '.xml';
       
   558 
       
   559         $response = $this->_get($path, $_params);
       
   560         return new Zend_Rest_Client_Result($response->getBody());
       
   561     }
       
   562 
       
   563     /**
       
   564      * User Followers
       
   565      *
       
   566      * @param  bool $lite If true, prevents inline inclusion of current status for followers; defaults to false
       
   567      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   568      * @return Zend_Rest_Client_Result
       
   569      */
       
   570     public function userFollowers($lite = false)
       
   571     {
       
   572         $this->_init();
       
   573         $path = '/1/statuses/followers.xml';
       
   574         if ($lite) {
       
   575             $this->lite = 'true';
       
   576         }
       
   577         $response = $this->_get($path);
       
   578         return new Zend_Rest_Client_Result($response->getBody());
       
   579     }
       
   580 
       
   581     /**
       
   582      * Show extended information on a user
       
   583      *
       
   584      * @param  int|string $id User ID or name
       
   585      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   586      * @return Zend_Rest_Client_Result
       
   587      */
       
   588     public function userShow($id)
       
   589     {
       
   590         $this->_init();
       
   591         $path = '/1/users/show.xml';
       
   592         $response = $this->_get($path, array('id'=>$id));
       
   593         return new Zend_Rest_Client_Result($response->getBody());
       
   594     }
       
   595 
       
   596     /**
       
   597      * Retrieve direct messages for the current user
       
   598      *
       
   599      * $params may include one or more of the following keys
       
   600      * - since_id: return statuses only greater than the one specified
       
   601      * - page: return page X of results
       
   602      *
       
   603      * @param  array $params
       
   604      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   605      * @return Zend_Rest_Client_Result
       
   606      */
       
   607     public function directMessageMessages(array $params = array())
       
   608     {
       
   609         $this->_init();
       
   610         $path = '/1/direct_messages.xml';
       
   611         $_params = array();
       
   612         foreach ($params as $key => $value) {
       
   613             switch (strtolower($key)) {
       
   614                 case 'since_id':
       
   615                     $_params['since_id'] = $this->_validInteger($value);
       
   616                     break;
       
   617                 case 'page':
       
   618                     $_params['page'] = (int) $value;
       
   619                     break;
       
   620                 default:
       
   621                     break;
       
   622             }
       
   623         }
       
   624         $response = $this->_get($path, $_params);
       
   625         return new Zend_Rest_Client_Result($response->getBody());
       
   626     }
       
   627 
       
   628     /**
       
   629      * Retrieve list of direct messages sent by current user
       
   630      *
       
   631      * $params may include one or more of the following keys
       
   632      * - since_id: return statuses only greater than the one specified
       
   633      * - page: return page X of results
       
   634      *
       
   635      * @param  array $params
       
   636      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   637      * @return Zend_Rest_Client_Result
       
   638      */
       
   639     public function directMessageSent(array $params = array())
       
   640     {
       
   641         $this->_init();
       
   642         $path = '/1/direct_messages/sent.xml';
       
   643         $_params = array();
       
   644         foreach ($params as $key => $value) {
       
   645             switch (strtolower($key)) {
       
   646                 case 'since_id':
       
   647                     $_params['since_id'] = $this->_validInteger($value);
       
   648                     break;
       
   649                 case 'page':
       
   650                     $_params['page'] = (int) $value;
       
   651                     break;
       
   652                 default:
       
   653                     break;
       
   654             }
       
   655         }
       
   656         $response = $this->_get($path, $_params);
       
   657         return new Zend_Rest_Client_Result($response->getBody());
       
   658     }
       
   659 
       
   660     /**
       
   661      * Send a direct message to a user
       
   662      *
       
   663      * @param  int|string $user User to whom to send message
       
   664      * @param  string $text Message to send to user
       
   665      * @return Zend_Rest_Client_Result
       
   666      * @throws Zend_Service_Twitter_Exception if message is too short or too long
       
   667      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   668      */
       
   669     public function directMessageNew($user, $text)
       
   670     {
       
   671         $this->_init();
       
   672         $path = '/1/direct_messages/new.xml';
       
   673         $len = iconv_strlen($text, 'UTF-8');
       
   674         if (0 == $len) {
       
   675             throw new Zend_Service_Twitter_Exception(
       
   676                 'Direct message must contain at least one character'
       
   677             );
       
   678         } elseif (140 < $len) {
       
   679             throw new Zend_Service_Twitter_Exception(
       
   680                 'Direct message must contain no more than 140 characters'
       
   681             );
       
   682         }
       
   683         $data = array('user' => $user, 'text' => $text);
       
   684         $response = $this->_post($path, $data);
       
   685         return new Zend_Rest_Client_Result($response->getBody());
       
   686     }
       
   687 
       
   688     /**
       
   689      * Destroy a direct message
       
   690      *
       
   691      * @param  int $id ID of message to destroy
       
   692      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   693      * @return Zend_Rest_Client_Result
       
   694      */
       
   695     public function directMessageDestroy($id)
       
   696     {
       
   697         $this->_init();
       
   698         $path = '/1/direct_messages/destroy/' . $this->_validInteger($id) . '.xml';
       
   699         $response = $this->_post($path);
       
   700         return new Zend_Rest_Client_Result($response->getBody());
       
   701     }
       
   702 
       
   703     /**
       
   704      * Create friendship
       
   705      *
       
   706      * @param  int|string $id User ID or name of new friend
       
   707      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   708      * @return Zend_Rest_Client_Result
       
   709      */
       
   710     public function friendshipCreate($id)
       
   711     {
       
   712         $this->_init();
       
   713         $path = '/1/friendships/create/' . $id . '.xml';
       
   714         $response = $this->_post($path);
       
   715         return new Zend_Rest_Client_Result($response->getBody());
       
   716     }
       
   717 
       
   718     /**
       
   719      * Destroy friendship
       
   720      *
       
   721      * @param  int|string $id User ID or name of friend to remove
       
   722      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   723      * @return Zend_Rest_Client_Result
       
   724      */
       
   725     public function friendshipDestroy($id)
       
   726     {
       
   727         $this->_init();
       
   728         $path = '/1/friendships/destroy/' . $id . '.xml';
       
   729         $response = $this->_post($path);
       
   730         return new Zend_Rest_Client_Result($response->getBody());
       
   731     }
       
   732 
       
   733     /**
       
   734      * Friendship exists
       
   735      *
       
   736      * @param int|string $id User ID or name of friend to see if they are your friend
       
   737      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   738      * @return Zend_Rest_Client_result
       
   739      */
       
   740     public function friendshipExists($id)
       
   741     {
       
   742         $this->_init();
       
   743         $path = '/1/friendships/exists.xml';
       
   744         $data = array('user_a' => $this->getUsername(), 'user_b' => $id);
       
   745         $response = $this->_get($path, $data);
       
   746         return new Zend_Rest_Client_Result($response->getBody());
       
   747     }
       
   748 
       
   749     /**
       
   750      * Verify Account Credentials
       
   751      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   752      *
       
   753      * @return Zend_Rest_Client_Result
       
   754      */
       
   755     public function accountVerifyCredentials()
       
   756     {
       
   757         $this->_init();
       
   758         $response = $this->_get('/1/account/verify_credentials.xml');
       
   759         return new Zend_Rest_Client_Result($response->getBody());
       
   760     }
       
   761 
       
   762     /**
       
   763      * End current session
       
   764      *
       
   765      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   766      * @return true
       
   767      */
       
   768     public function accountEndSession()
       
   769     {
       
   770         $this->_init();
       
   771         $this->_get('/1/account/end_session');
       
   772         return true;
       
   773     }
       
   774 
       
   775     /**
       
   776      * Returns the number of api requests you have left per hour.
       
   777      *
       
   778      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   779      * @return Zend_Rest_Client_Result
       
   780      */
       
   781     public function accountRateLimitStatus()
       
   782     {
       
   783         $this->_init();
       
   784         $response = $this->_get('/1/account/rate_limit_status.xml');
       
   785         return new Zend_Rest_Client_Result($response->getBody());
       
   786     }
       
   787 
       
   788     /**
       
   789      * Fetch favorites
       
   790      *
       
   791      * $params may contain one or more of the following:
       
   792      * - 'id': Id of a user for whom to fetch favorites
       
   793      * - 'page': Retrieve a different page of resuls
       
   794      *
       
   795      * @param  array $params
       
   796      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   797      * @return Zend_Rest_Client_Result
       
   798      */
       
   799     public function favoriteFavorites(array $params = array())
       
   800     {
       
   801         $this->_init();
       
   802         $path = '/1/favorites';
       
   803         $_params = array();
       
   804         foreach ($params as $key => $value) {
       
   805             switch (strtolower($key)) {
       
   806                 case 'id':
       
   807                     $path .= '/' . $this->_validInteger($value);
       
   808                     break;
       
   809                 case 'page':
       
   810                     $_params['page'] = (int) $value;
       
   811                     break;
       
   812                 default:
       
   813                     break;
       
   814             }
       
   815         }
       
   816         $path .= '.xml';
       
   817         $response = $this->_get($path, $_params);
       
   818         return new Zend_Rest_Client_Result($response->getBody());
       
   819     }
       
   820 
       
   821     /**
       
   822      * Mark a status as a favorite
       
   823      *
       
   824      * @param  int $id Status ID you want to mark as a favorite
       
   825      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   826      * @return Zend_Rest_Client_Result
       
   827      */
       
   828     public function favoriteCreate($id)
       
   829     {
       
   830         $this->_init();
       
   831         $path = '/1/favorites/create/' . $this->_validInteger($id) . '.xml';
       
   832         $response = $this->_post($path);
       
   833         return new Zend_Rest_Client_Result($response->getBody());
       
   834     }
       
   835 
       
   836     /**
       
   837      * Remove a favorite
       
   838      *
       
   839      * @param  int $id Status ID you want to de-list as a favorite
       
   840      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   841      * @return Zend_Rest_Client_Result
       
   842      */
       
   843     public function favoriteDestroy($id)
       
   844     {
       
   845         $this->_init();
       
   846         $path = '/1/favorites/destroy/' . $this->_validInteger($id) . '.xml';
       
   847         $response = $this->_post($path);
       
   848         return new Zend_Rest_Client_Result($response->getBody());
       
   849     }
       
   850 
       
   851     /**
       
   852      * Blocks the user specified in the ID parameter as the authenticating user.
       
   853      * Destroys a friendship to the blocked user if it exists.
       
   854      *
       
   855      * @param integer|string $id       The ID or screen name of a user to block.
       
   856      * @return Zend_Rest_Client_Result
       
   857      */
       
   858     public function blockCreate($id)
       
   859     {
       
   860         $this->_init();
       
   861         $path = '/1/blocks/create/' . $id . '.xml';
       
   862         $response = $this->_post($path);
       
   863         return new Zend_Rest_Client_Result($response->getBody());
       
   864     }
       
   865 
       
   866     /**
       
   867      * Un-blocks the user specified in the ID parameter for the authenticating user
       
   868      *
       
   869      * @param integer|string $id       The ID or screen_name of the user to un-block.
       
   870      * @return Zend_Rest_Client_Result
       
   871      */
       
   872     public function blockDestroy($id)
       
   873     {
       
   874         $this->_init();
       
   875         $path = '/1/blocks/destroy/' . $id . '.xml';
       
   876         $response = $this->_post($path);
       
   877         return new Zend_Rest_Client_Result($response->getBody());
       
   878     }
       
   879 
       
   880     /**
       
   881      * Returns if the authenticating user is blocking a target user.
       
   882      *
       
   883      * @param string|integer $id    The ID or screen_name of the potentially blocked user.
       
   884      * @param boolean $returnResult Instead of returning a boolean return the rest response from twitter
       
   885      * @return Boolean|Zend_Rest_Client_Result
       
   886      */
       
   887     public function blockExists($id, $returnResult = false)
       
   888     {
       
   889         $this->_init();
       
   890         $path = '/1/blocks/exists/' . $id . '.xml';
       
   891         $response = $this->_get($path);
       
   892 
       
   893         $cr = new Zend_Rest_Client_Result($response->getBody());
       
   894 
       
   895         if ($returnResult === true)
       
   896             return $cr;
       
   897 
       
   898         if (!empty($cr->request)) {
       
   899             return false;
       
   900         }
       
   901 
       
   902         return true;
       
   903     }
       
   904 
       
   905     /**
       
   906      * Returns an array of user objects that the authenticating user is blocking
       
   907      *
       
   908      * @param integer $page         Optional. Specifies the page number of the results beginning at 1. A single page contains 20 ids.
       
   909      * @param boolean $returnUserIds  Optional. Returns only the userid's instead of the whole user object
       
   910      * @return Zend_Rest_Client_Result
       
   911      */
       
   912     public function blockBlocking($page = 1, $returnUserIds = false)
       
   913     {
       
   914         $this->_init();
       
   915         $path = '/1/blocks/blocking';
       
   916         if ($returnUserIds === true) {
       
   917             $path .= '/ids';
       
   918         }
       
   919         $path .= '.xml';
       
   920         $response = $this->_get($path, array('page' => $page));
       
   921         return new Zend_Rest_Client_Result($response->getBody());
       
   922     }
       
   923 
       
   924     /**
       
   925      * Protected function to validate that the integer is valid or return a 0
       
   926      * @param $int
       
   927      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   928      * @return integer
       
   929      */
       
   930     protected function _validInteger($int)
       
   931     {
       
   932         if (preg_match("/(\d+)/", $int)) {
       
   933             return $int;
       
   934         }
       
   935         return 0;
       
   936     }
       
   937 
       
   938     /**
       
   939      * Validate a screen name using Twitter rules
       
   940      *
       
   941      * @param string $name
       
   942      * @throws Zend_Service_Twitter_Exception
       
   943      * @return string
       
   944      */
       
   945     protected function _validateScreenName($name)
       
   946     {
       
   947         if (!preg_match('/^[a-zA-Z0-9_]{0,15}$/', $name)) {
       
   948             require_once 'Zend/Service/Twitter/Exception.php';
       
   949             throw new Zend_Service_Twitter_Exception(
       
   950                 'Screen name, "' . $name
       
   951                 . '" should only contain alphanumeric characters and'
       
   952                 . ' underscores, and not exceed 15 characters.');
       
   953         }
       
   954         return $name;
       
   955     }
       
   956 
       
   957     /**
       
   958      * Call a remote REST web service URI and return the Zend_Http_Response object
       
   959      *
       
   960      * @param  string $path            The path to append to the URI
       
   961      * @throws Zend_Rest_Client_Exception
       
   962      * @return void
       
   963      */
       
   964     protected function _prepare($path)
       
   965     {
       
   966         // Get the URI object and configure it
       
   967         if (!$this->_uri instanceof Zend_Uri_Http) {
       
   968             require_once 'Zend/Rest/Client/Exception.php';
       
   969             throw new Zend_Rest_Client_Exception(
       
   970                 'URI object must be set before performing call'
       
   971             );
       
   972         }
       
   973 
       
   974         $uri = $this->_uri->getUri();
       
   975 
       
   976         if ($path[0] != '/' && $uri[strlen($uri) - 1] != '/') {
       
   977             $path = '/' . $path;
       
   978         }
       
   979 
       
   980         $this->_uri->setPath($path);
       
   981 
       
   982         /**
       
   983          * Get the HTTP client and configure it for the endpoint URI.
       
   984          * Do this each time because the Zend_Http_Client instance is shared
       
   985          * among all Zend_Service_Abstract subclasses.
       
   986          */
       
   987         $this->_localHttpClient->resetParameters()->setUri((string) $this->_uri);
       
   988     }
       
   989 
       
   990     /**
       
   991      * Performs an HTTP GET request to the $path.
       
   992      *
       
   993      * @param string $path
       
   994      * @param array  $query Array of GET parameters
       
   995      * @throws Zend_Http_Client_Exception
       
   996      * @return Zend_Http_Response
       
   997      */
       
   998     protected function _get($path, array $query = null)
       
   999     {
       
  1000         $this->_prepare($path);
       
  1001         $this->_localHttpClient->setParameterGet($query);
       
  1002         return $this->_localHttpClient->request(Zend_Http_Client::GET);
       
  1003     }
       
  1004 
       
  1005     /**
       
  1006      * Performs an HTTP POST request to $path.
       
  1007      *
       
  1008      * @param string $path
       
  1009      * @param mixed $data Raw data to send
       
  1010      * @throws Zend_Http_Client_Exception
       
  1011      * @return Zend_Http_Response
       
  1012      */
       
  1013     protected function _post($path, $data = null)
       
  1014     {
       
  1015         $this->_prepare($path);
       
  1016         return $this->_performPost(Zend_Http_Client::POST, $data);
       
  1017     }
       
  1018 
       
  1019     /**
       
  1020      * Perform a POST or PUT
       
  1021      *
       
  1022      * Performs a POST or PUT request. Any data provided is set in the HTTP
       
  1023      * client. String data is pushed in as raw POST data; array or object data
       
  1024      * is pushed in as POST parameters.
       
  1025      *
       
  1026      * @param mixed $method
       
  1027      * @param mixed $data
       
  1028      * @return Zend_Http_Response
       
  1029      */
       
  1030     protected function _performPost($method, $data = null)
       
  1031     {
       
  1032         $client = $this->_localHttpClient;
       
  1033         if (is_string($data)) {
       
  1034             $client->setRawData($data);
       
  1035         } elseif (is_array($data) || is_object($data)) {
       
  1036             $client->setParameterPost((array) $data);
       
  1037         }
       
  1038         return $client->request($method);
       
  1039     }
       
  1040 
       
  1041 }