web/lib/Zend/Service/Twitter.php
changeset 886 1e110b03ae96
parent 807 877f952ae2bd
child 1230 68c69c656a2c
equal deleted inserted replaced
885:2251fb41dbc7 886:1e110b03ae96
    13  * to license@zend.com so we can send you a copy immediately.
    13  * to license@zend.com so we can send you a copy immediately.
    14  *
    14  *
    15  * @category   Zend
    15  * @category   Zend
    16  * @package    Zend_Service
    16  * @package    Zend_Service
    17  * @subpackage Twitter
    17  * @subpackage Twitter
    18  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
    18  * @copyright  Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
    19  * @license    http://framework.zend.com/license/new-bsd     New BSD License
    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 $
    20  * @version    $Id: Twitter.php 25288 2013-03-13 13:36:39Z matthew $
    21  */
    21  */
    22 
    22 
    23 /**
    23 /**
    24  * @see Zend_Rest_Client
    24  * @see Zend_Http_Client
    25  */
    25  */
    26 require_once 'Zend/Rest/Client.php';
    26 require_once 'Zend/Http/Client.php';
    27 
    27 
    28 /**
    28 /**
    29  * @see Zend_Rest_Client_Result
    29  * @see Zend_Http_CookieJar
    30  */
    30  */
    31 require_once 'Zend/Rest/Client/Result.php';
    31 require_once 'Zend/Http/CookieJar.php';
    32 
    32 
    33 /**
    33 /**
    34  * @see Zend_Oauth_Consumer
    34  * @see Zend_Oauth_Consumer
    35  */
    35  */
    36 require_once 'Zend/Oauth/Consumer.php';
    36 require_once 'Zend/Oauth/Consumer.php';
    37 
    37 
    38 /**
    38 /**
       
    39  * @see Zend_Oauth_Token_Access
       
    40  */
       
    41 require_once 'Zend/Oauth/Token/Access.php';
       
    42 
       
    43 /**
       
    44  * @see Zend_Service_Twitter_Response
       
    45  */
       
    46 require_once 'Zend/Service/Twitter/Response.php';
       
    47 
       
    48 /**
    39  * @category   Zend
    49  * @category   Zend
    40  * @package    Zend_Service
    50  * @package    Zend_Service
    41  * @subpackage Twitter
    51  * @subpackage Twitter
    42  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
    52  * @copyright  Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
    43  * @license    http://framework.zend.com/license/new-bsd     New BSD License
    53  * @license    http://framework.zend.com/license/new-bsd     New BSD License
    44  */
    54  */
    45 class Zend_Service_Twitter extends Zend_Rest_Client
    55 class Zend_Service_Twitter
    46 {
    56 {
       
    57     /**
       
    58      * Base URI for all API calls
       
    59      */
       
    60     const API_BASE_URI = 'https://api.twitter.com/1.1/';
       
    61 
       
    62     /**
       
    63      * OAuth Endpoint
       
    64      */
       
    65     const OAUTH_BASE_URI = 'https://api.twitter.com/oauth';
    47 
    66 
    48     /**
    67     /**
    49      * 246 is the current limit for a status message, 140 characters are displayed
    68      * 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
    69      * 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
    70      * 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).
    71      * which may appear unusual but is a security measure).
    53      *
    72      *
    54      * This should be reviewed in the future...
    73      * This should be reviewed in the future...
    55      */
    74      */
    56     const STATUS_MAX_CHARACTERS = 246;
    75     const STATUS_MAX_CHARACTERS = 246;
    57     
    76 
    58     /**
    77     /**
    59      * OAuth Endpoint
    78      * @var array
    60      */
    79      */
    61     const OAUTH_BASE_URI = 'http://twitter.com/oauth';
    80     protected $cookieJar;
    62     
    81 
    63     /**
       
    64      * @var Zend_Http_CookieJar
       
    65      */
       
    66     protected $_cookieJar;
       
    67     
       
    68     /**
    82     /**
    69      * Date format for 'since' strings
    83      * Date format for 'since' strings
    70      *
    84      *
    71      * @var string
    85      * @var string
    72      */
    86      */
    73     protected $_dateFormat = 'D, d M Y H:i:s T';
    87     protected $dateFormat = 'D, d M Y H:i:s T';
    74     
    88 
       
    89     /**
       
    90      * @var Zend_Http_Client
       
    91      */
       
    92     protected $httpClient = null;
       
    93 
       
    94     /**
       
    95      * Current method type (for method proxying)
       
    96      *
       
    97      * @var string
       
    98      */
       
    99     protected $methodType;
       
   100 
       
   101     /**
       
   102      * Oauth Consumer
       
   103      *
       
   104      * @var Zend_Oauth_Consumer
       
   105      */
       
   106     protected $oauthConsumer = null;
       
   107 
       
   108     /**
       
   109      * Types of API methods
       
   110      *
       
   111      * @var array
       
   112      */
       
   113     protected $methodTypes = array(
       
   114         'account',
       
   115         'application',
       
   116         'blocks',
       
   117         'directmessages',
       
   118         'favorites',
       
   119         'friendships',
       
   120         'search',
       
   121         'statuses',
       
   122         'users',
       
   123     );
       
   124 
       
   125     /**
       
   126      * Options passed to constructor
       
   127      *
       
   128      * @var array
       
   129      */
       
   130     protected $options = array();
       
   131 
    75     /**
   132     /**
    76      * Username
   133      * Username
    77      *
   134      *
    78      * @var string
   135      * @var string
    79      */
   136      */
    80     protected $_username;
   137     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 
   138 
   125     /**
   139     /**
   126      * Constructor
   140      * Constructor
   127      *
   141      *
   128      * @param  array $options Optional options array
   142      * @param  null|array|Zend_Config $options
   129      * @return void
   143      * @param  null|Zend_Oauth_Consumer $consumer
   130      */
   144      * @param  null|Zend_Http_Client $httpClient
   131     public function __construct($options = null, Zend_Oauth_Consumer $consumer = null)
   145      */
   132     {
   146     public function __construct($options = null, Zend_Oauth_Consumer $consumer = null, Zend_Http_Client $httpClient = null)
   133         $this->setUri('http://api.twitter.com');
   147     {
   134         if (!is_array($options)) $options = array();
       
   135         $options['siteUrl'] = self::OAUTH_BASE_URI;
       
   136         if ($options instanceof Zend_Config) {
   148         if ($options instanceof Zend_Config) {
   137             $options = $options->toArray();
   149             $options = $options->toArray();
   138         }
   150         }
   139         $this->_options = $options;
   151         if (!is_array($options)) {
       
   152             $options = array();
       
   153         }
       
   154 
       
   155         $this->options = $options;
       
   156 
   140         if (isset($options['username'])) {
   157         if (isset($options['username'])) {
   141             $this->setUsername($options['username']);
   158             $this->setUsername($options['username']);
   142         }
   159         }
   143         if (isset($options['accessToken'])
   160 
   144         && $options['accessToken'] instanceof Zend_Oauth_Token_Access) {
   161         $accessToken = false;
   145             $this->setLocalHttpClient($options['accessToken']->getHttpClient($options));
   162         if (isset($options['accessToken'])) {
       
   163             $accessToken = $options['accessToken'];
       
   164         } elseif (isset($options['access_token'])) {
       
   165             $accessToken = $options['access_token'];
       
   166         }
       
   167 
       
   168         $oauthOptions = array();
       
   169         if (isset($options['oauthOptions'])) {
       
   170             $oauthOptions = $options['oauthOptions'];
       
   171         } elseif (isset($options['oauth_options'])) {
       
   172             $oauthOptions = $options['oauth_options'];
       
   173         }
       
   174         $oauthOptions['siteUrl'] = self::OAUTH_BASE_URI;
       
   175 
       
   176         $httpClientOptions = array();
       
   177         if (isset($options['httpClientOptions'])) {
       
   178             $httpClientOptions = $options['httpClientOptions'];
       
   179         } elseif (isset($options['http_client_options'])) {
       
   180             $httpClientOptions = $options['http_client_options'];
       
   181         }
       
   182 
       
   183         // If we have an OAuth access token, use the HTTP client it provides
       
   184         if ($accessToken && is_array($accessToken)
       
   185             && (isset($accessToken['token']) && isset($accessToken['secret']))
       
   186         ) {
       
   187             $token = new Zend_Oauth_Token_Access();
       
   188             $token->setToken($accessToken['token']);
       
   189             $token->setTokenSecret($accessToken['secret']);
       
   190             $accessToken = $token;
       
   191         }
       
   192         if ($accessToken && $accessToken instanceof Zend_Oauth_Token_Access) {
       
   193             $oauthOptions['token'] = $accessToken;
       
   194             $this->setHttpClient($accessToken->getHttpClient($oauthOptions, self::OAUTH_BASE_URI, $httpClientOptions));
       
   195             return;
       
   196         }
       
   197 
       
   198         // See if we were passed an http client
       
   199         if (isset($options['httpClient']) && null === $httpClient) {
       
   200             $httpClient = $options['httpClient'];
       
   201         } elseif (isset($options['http_client']) && null === $httpClient) {
       
   202             $httpClient = $options['http_client'];
       
   203         }
       
   204         if ($httpClient instanceof Zend_Http_Client) {
       
   205             $this->httpClient = $httpClient;
   146         } else {
   206         } else {
   147             $this->setLocalHttpClient(clone self::getHttpClient());
   207             $this->setHttpClient(new Zend_Http_Client(null, $httpClientOptions));
   148             if ($consumer === null) {
   208         }
   149                 $this->_oauthConsumer = new Zend_Oauth_Consumer($options);
   209 
   150             } else {
   210         // Set the OAuth consumer
   151                 $this->_oauthConsumer = $consumer;
   211         if ($consumer === null) {
   152             }
   212             $consumer = new Zend_Oauth_Consumer($oauthOptions);
   153         }
   213         }
   154     }
   214         $this->oauthConsumer = $consumer;
   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     }
   215 
   216 
   216     /**
   217     /**
   217      * Proxy service methods
   218      * Proxy service methods
   218      *
   219      *
   219      * @param  string $type
   220      * @param  string $type
   220      * @return Zend_Service_Twitter
   221      * @return Twitter
   221      * @throws Zend_Service_Twitter_Exception If method not in method types list
   222      * @throws Exception\DomainException If method not in method types list
   222      */
   223      */
   223     public function __get($type)
   224     public function __get($type)
   224     {
   225     {
   225         if (!in_array($type, $this->_methodTypes)) {
   226         $type = strtolower($type);
   226             include_once 'Zend/Service/Twitter/Exception.php';
   227         $type = str_replace('_', '', $type);
       
   228         if (!in_array($type, $this->methodTypes)) {
       
   229             require_once 'Zend/Service/Twitter/Exception.php';
   227             throw new Zend_Service_Twitter_Exception(
   230             throw new Zend_Service_Twitter_Exception(
   228                 'Invalid method type "' . $type . '"'
   231                 'Invalid method type "' . $type . '"'
   229             );
   232             );
   230         }
   233         }
   231         $this->_methodType = $type;
   234         $this->methodType = $type;
   232         return $this;
   235         return $this;
   233     }
   236     }
   234 
   237 
   235     /**
   238     /**
   236      * Method overloading
   239      * Method overloading
   237      *
   240      *
   238      * @param  string $method
   241      * @param  string $method
   239      * @param  array $params
   242      * @param  array $params
   240      * @return mixed
   243      * @return mixed
   241      * @throws Zend_Service_Twitter_Exception if unable to find method
   244      * @throws Exception\BadMethodCallException if unable to find method
   242      */
   245      */
   243     public function __call($method, $params)
   246     public function __call($method, $params)
   244     {
   247     {
   245         if (method_exists($this->_oauthConsumer, $method)) {
   248         if (method_exists($this->oauthConsumer, $method)) {
   246             $return = call_user_func_array(array($this->_oauthConsumer, $method), $params);
   249             $return = call_user_func_array(array($this->oauthConsumer, $method), $params);
   247             if ($return instanceof Zend_Oauth_Token_Access) {
   250             if ($return instanceof Zend_Oauth_Token_Access) {
   248                 $this->setLocalHttpClient($return->getHttpClient($this->_options));
   251                 $this->setHttpClient($return->getHttpClient($this->options));
   249             }
   252             }
   250             return $return;
   253             return $return;
   251         }
   254         }
   252         if (empty($this->_methodType)) {
   255         if (empty($this->methodType)) {
   253             include_once 'Zend/Service/Twitter/Exception.php';
   256             require_once 'Zend/Service/Twitter/Exception.php';
   254             throw new Zend_Service_Twitter_Exception(
   257             throw new Zend_Service_Twitter_Exception(
   255                 'Invalid method "' . $method . '"'
   258                 'Invalid method "' . $method . '"'
   256             );
   259             );
   257         }
   260         }
   258         $test = $this->_methodType . ucfirst($method);
   261 
       
   262         $test = str_replace('_', '', strtolower($method));
       
   263         $test = $this->methodType . $test;
   259         if (!method_exists($this, $test)) {
   264         if (!method_exists($this, $test)) {
   260             include_once 'Zend/Service/Twitter/Exception.php';
   265             require_once 'Zend/Service/Twitter/Exception.php';
   261             throw new Zend_Service_Twitter_Exception(
   266             throw new Zend_Service_Twitter_Exception(
   262                 'Invalid method "' . $test . '"'
   267                 'Invalid method "' . $test . '"'
   263             );
   268             );
   264         }
   269         }
   265 
   270 
   266         return call_user_func_array(array($this, $test), $params);
   271         return call_user_func_array(array($this, $test), $params);
   267     }
   272     }
   268 
   273 
   269     /**
   274     /**
   270      * Initialize HTTP authentication
   275      * Set HTTP client
   271      *
   276      *
   272      * @return void
   277      * @param Zend_Http_Client $client
   273      */
   278      * @return self
   274     protected function _init()
   279      */
   275     {
   280     public function setHttpClient(Zend_Http_Client $client)
   276         if (!$this->isAuthorised() && $this->getUsername() !== null) {
   281     {
       
   282         $this->httpClient = $client;
       
   283         $this->httpClient->setHeaders(array('Accept-Charset' => 'ISO-8859-1,utf-8'));
       
   284         return $this;
       
   285     }
       
   286 
       
   287     /**
       
   288      * Get the HTTP client
       
   289      *
       
   290      * Lazy loads one if none present
       
   291      *
       
   292      * @return Zend_Http_Client
       
   293      */
       
   294     public function getHttpClient()
       
   295     {
       
   296         if (null === $this->httpClient) {
       
   297             $this->setHttpClient(new Zend_Http_Client());
       
   298         }
       
   299         return $this->httpClient;
       
   300     }
       
   301 
       
   302     /**
       
   303      * Retrieve username
       
   304      *
       
   305      * @return string
       
   306      */
       
   307     public function getUsername()
       
   308     {
       
   309         return $this->username;
       
   310     }
       
   311 
       
   312     /**
       
   313      * Set username
       
   314      *
       
   315      * @param  string $value
       
   316      * @return self
       
   317      */
       
   318     public function setUsername($value)
       
   319     {
       
   320         $this->username = $value;
       
   321         return $this;
       
   322     }
       
   323 
       
   324     /**
       
   325      * Checks for an authorised state
       
   326      *
       
   327      * @return bool
       
   328      */
       
   329     public function isAuthorised()
       
   330     {
       
   331         if ($this->getHttpClient() instanceof Zend_Oauth_Client) {
       
   332             return true;
       
   333         }
       
   334         return false;
       
   335     }
       
   336 
       
   337     /**
       
   338      * Verify Account Credentials
       
   339      *
       
   340      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   341      * @throws Exception\DomainException if unable to decode JSON payload
       
   342      * @return Zend_Service_Twitter_Response
       
   343      */
       
   344     public function accountVerifyCredentials()
       
   345     {
       
   346         $this->init();
       
   347         $response = $this->get('account/verify_credentials');
       
   348         return new Zend_Service_Twitter_Response($response);
       
   349     }
       
   350 
       
   351     /**
       
   352      * Returns the number of api requests you have left per hour.
       
   353      *
       
   354      * @todo   Have a separate payload object to represent rate limits
       
   355      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   356      * @throws Exception\DomainException if unable to decode JSON payload
       
   357      * @return Zend_Service_Twitter_Response
       
   358      */
       
   359     public function applicationRateLimitStatus()
       
   360     {
       
   361         $this->init();
       
   362         $response = $this->get('application/rate_limit_status');
       
   363         return new Zend_Service_Twitter_Response($response);
       
   364     }
       
   365 
       
   366     /**
       
   367      * Blocks the user specified in the ID parameter as the authenticating user.
       
   368      * Destroys a friendship to the blocked user if it exists.
       
   369      *
       
   370      * @param  integer|string $id       The ID or screen name of a user to block.
       
   371      * @throws Exception\DomainException if unable to decode JSON payload
       
   372      * @return Zend_Service_Twitter_Response
       
   373      */
       
   374     public function blocksCreate($id)
       
   375     {
       
   376         $this->init();
       
   377         $path     = 'blocks/create';
       
   378         $params   = $this->createUserParameter($id, array());
       
   379         $response = $this->post($path, $params);
       
   380         return new Zend_Service_Twitter_Response($response);
       
   381     }
       
   382 
       
   383     /**
       
   384      * Un-blocks the user specified in the ID parameter for the authenticating user
       
   385      *
       
   386      * @param  integer|string $id       The ID or screen_name of the user to un-block.
       
   387      * @throws Exception\DomainException if unable to decode JSON payload
       
   388      * @return Zend_Service_Twitter_Response
       
   389      */
       
   390     public function blocksDestroy($id)
       
   391     {
       
   392         $this->init();
       
   393         $path   = 'blocks/destroy';
       
   394         $params = $this->createUserParameter($id, array());
       
   395         $response = $this->post($path, $params);
       
   396         return new Zend_Service_Twitter_Response($response);
       
   397     }
       
   398 
       
   399     /**
       
   400      * Returns an array of user ids that the authenticating user is blocking
       
   401      *
       
   402      * @param  integer $cursor  Optional. Specifies the cursor position at which to begin listing ids; defaults to first "page" of results.
       
   403      * @throws Exception\DomainException if unable to decode JSON payload
       
   404      * @return Zend_Service_Twitter_Response
       
   405      */
       
   406     public function blocksIds($cursor = -1)
       
   407     {
       
   408         $this->init();
       
   409         $path = 'blocks/ids';
       
   410         $response = $this->get($path, array('cursor' => $cursor));
       
   411         return new Zend_Service_Twitter_Response($response);
       
   412     }
       
   413 
       
   414     /**
       
   415      * Returns an array of user objects that the authenticating user is blocking
       
   416      *
       
   417      * @param  integer $cursor  Optional. Specifies the cursor position at which to begin listing ids; defaults to first "page" of results.
       
   418      * @throws Exception\DomainException if unable to decode JSON payload
       
   419      * @return Zend_Service_Twitter_Response
       
   420      */
       
   421     public function blocksList($cursor = -1)
       
   422     {
       
   423         $this->init();
       
   424         $path = 'blocks/list';
       
   425         $response = $this->get($path, array('cursor' => $cursor));
       
   426         return new Zend_Service_Twitter_Response($response);
       
   427     }
       
   428 
       
   429     /**
       
   430      * Destroy a direct message
       
   431      *
       
   432      * @param  int $id ID of message to destroy
       
   433      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   434      * @throws Exception\DomainException if unable to decode JSON payload
       
   435      * @return Zend_Service_Twitter_Response
       
   436      */
       
   437     public function directMessagesDestroy($id)
       
   438     {
       
   439         $this->init();
       
   440         $path     = 'direct_messages/destroy';
       
   441         $params   = array('id' => $this->validInteger($id));
       
   442         $response = $this->post($path, $params);
       
   443         return new Zend_Service_Twitter_Response($response);
       
   444     }
       
   445 
       
   446     /**
       
   447      * Retrieve direct messages for the current user
       
   448      *
       
   449      * $options may include one or more of the following keys
       
   450      * - count: return page X of results
       
   451      * - since_id: return statuses only greater than the one specified
       
   452      * - max_id: return statuses with an ID less than (older than) or equal to that specified
       
   453      * - include_entities: setting to false will disable embedded entities
       
   454      * - skip_status:setting to true, "t", or 1 will omit the status in returned users
       
   455      *
       
   456      * @param  array $options
       
   457      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   458      * @throws Exception\DomainException if unable to decode JSON payload
       
   459      * @return Zend_Service_Twitter_Response
       
   460      */
       
   461     public function directMessagesMessages(array $options = array())
       
   462     {
       
   463         $this->init();
       
   464         $path   = 'direct_messages';
       
   465         $params = array();
       
   466         foreach ($options as $key => $value) {
       
   467             switch (strtolower($key)) {
       
   468                 case 'count':
       
   469                     $params['count'] = (int) $value;
       
   470                     break;
       
   471                 case 'since_id':
       
   472                     $params['since_id'] = $this->validInteger($value);
       
   473                     break;
       
   474                 case 'max_id':
       
   475                     $params['max_id'] = $this->validInteger($value);
       
   476                     break;
       
   477                 case 'include_entities':
       
   478                     $params['include_entities'] = (bool) $value;
       
   479                     break;
       
   480                 case 'skip_status':
       
   481                     $params['skip_status'] = (bool) $value;
       
   482                     break;
       
   483                 default:
       
   484                     break;
       
   485             }
       
   486         }
       
   487         $response = $this->get($path, $params);
       
   488         return new Zend_Service_Twitter_Response($response);
       
   489     }
       
   490 
       
   491     /**
       
   492      * Send a direct message to a user
       
   493      *
       
   494      * @param  int|string $user User to whom to send message
       
   495      * @param  string $text Message to send to user
       
   496      * @throws Exception\InvalidArgumentException if message is empty
       
   497      * @throws Exception\OutOfRangeException if message is too long
       
   498      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   499      * @throws Exception\DomainException if unable to decode JSON payload
       
   500      * @return Zend_Service_Twitter_Response
       
   501      */
       
   502     public function directMessagesNew($user, $text)
       
   503     {
       
   504         $this->init();
       
   505         $path = 'direct_messages/new';
       
   506 
       
   507         $len = iconv_strlen($text, 'UTF-8');
       
   508         if (0 == $len) {
   277             require_once 'Zend/Service/Twitter/Exception.php';
   509             require_once 'Zend/Service/Twitter/Exception.php';
   278             throw new Zend_Service_Twitter_Exception(
   510             throw new Zend_Service_Twitter_Exception(
   279                 'Twitter session is unauthorised. You need to initialize '
   511                 'Direct message must contain at least one character'
   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             );
   512             );
   284         }
   513         } elseif (140 < $len) {
   285         $client = $this->_localHttpClient;
   514             require_once 'Zend/Service/Twitter/Exception.php';
   286         $client->resetParameters();
   515             throw new Zend_Service_Twitter_Exception(
   287         if (null == $this->_cookieJar) {
   516                 'Direct message must contain no more than 140 characters'
   288             $client->setCookieJar();
   517             );
   289             $this->_cookieJar = $client->getCookieJar();
   518         }
   290         } else {
   519 
   291             $client->setCookieJar($this->_cookieJar);
   520         $params         = $this->createUserParameter($user, array());
   292         }
   521         $params['text'] = $text;
   293     }
   522         $response       = $this->post($path, $params);
   294 
   523         return new Zend_Service_Twitter_Response($response);
   295     /**
   524     }
   296      * Set date header
   525 
   297      *
   526     /**
   298      * @param  int|string $value
   527      * Retrieve list of direct messages sent by current user
   299      * @deprecated Not supported by Twitter since April 08, 2009
   528      *
   300      * @return void
   529      * $options may include one or more of the following keys
   301      */
   530      * - count: return page X of results
   302     protected function _setDate($value)
   531      * - page: return starting at page
   303     {
   532      * - since_id: return statuses only greater than the one specified
   304         if (is_int($value)) {
   533      * - max_id: return statuses with an ID less than (older than) or equal to that specified
   305             $date = date($this->_dateFormat, $value);
   534      * - include_entities: setting to false will disable embedded entities
   306         } else {
   535      *
   307             $date = date($this->_dateFormat, strtotime($value));
   536      * @param  array $options
   308         }
   537      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
   309         $this->_localHttpClient->setHeaders('If-Modified-Since', $date);
   538      * @throws Exception\DomainException if unable to decode JSON payload
   310     }
   539      * @return Zend_Service_Twitter_Response
   311 
   540      */
   312     /**
   541     public function directMessagesSent(array $options = array())
   313      * Public Timeline status
   542     {
   314      *
   543         $this->init();
   315      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
   544         $path   = 'direct_messages/sent';
   316      * @return Zend_Rest_Client_Result
   545         $params = array();
   317      */
   546         foreach ($options as $key => $value) {
   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)) {
   547             switch (strtolower($key)) {
   346                 case 'count':
   548                 case 'count':
   347                     $count = (int) $value;
   549                     $params['count'] = (int) $value;
   348                     if (0 >= $count) {
   550                     break;
   349                         $count = 1;
   551                 case 'page':
   350                     } elseif (200 < $count) {
   552                     $params['page'] = (int) $value;
   351                         $count = 200;
   553                     break;
       
   554                 case 'since_id':
       
   555                     $params['since_id'] = $this->validInteger($value);
       
   556                     break;
       
   557                 case 'max_id':
       
   558                     $params['max_id'] = $this->validInteger($value);
       
   559                     break;
       
   560                 case 'include_entities':
       
   561                     $params['include_entities'] = (bool) $value;
       
   562                     break;
       
   563                 default:
       
   564                     break;
       
   565             }
       
   566         }
       
   567         $response = $this->get($path, $params);
       
   568         return new Zend_Service_Twitter_Response($response);
       
   569     }
       
   570 
       
   571     /**
       
   572      * Mark a status as a favorite
       
   573      *
       
   574      * @param  int $id Status ID you want to mark as a favorite
       
   575      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   576      * @throws Exception\DomainException if unable to decode JSON payload
       
   577      * @return Zend_Service_Twitter_Response
       
   578      */
       
   579     public function favoritesCreate($id)
       
   580     {
       
   581         $this->init();
       
   582         $path     = 'favorites/create';
       
   583         $params   = array('id' => $this->validInteger($id));
       
   584         $response = $this->post($path, $params);
       
   585         return new Zend_Service_Twitter_Response($response);
       
   586     }
       
   587 
       
   588     /**
       
   589      * Remove a favorite
       
   590      *
       
   591      * @param  int $id Status ID you want to de-list as a favorite
       
   592      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   593      * @throws Exception\DomainException if unable to decode JSON payload
       
   594      * @return Zend_Service_Twitter_Response
       
   595      */
       
   596     public function favoritesDestroy($id)
       
   597     {
       
   598         $this->init();
       
   599         $path     = 'favorites/destroy';
       
   600         $params   = array('id' => $this->validInteger($id));
       
   601         $response = $this->post($path, $params);
       
   602         return new Zend_Service_Twitter_Response($response);
       
   603     }
       
   604 
       
   605     /**
       
   606      * Fetch favorites
       
   607      *
       
   608      * $options may contain one or more of the following:
       
   609      * - user_id: Id of a user for whom to fetch favorites
       
   610      * - screen_name: Screen name of a user for whom to fetch favorites
       
   611      * - count: number of tweets to attempt to retrieve, up to 200
       
   612      * - since_id: return results only after the specified tweet id
       
   613      * - max_id: return results with an ID less than (older than) or equal to the specified ID
       
   614      * - include_entities: when set to false, entities member will be omitted
       
   615      *
       
   616      * @param  array $params
       
   617      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   618      * @throws Exception\DomainException if unable to decode JSON payload
       
   619      * @return Zend_Service_Twitter_Response
       
   620      */
       
   621     public function favoritesList(array $options = array())
       
   622     {
       
   623         $this->init();
       
   624         $path = 'favorites/list';
       
   625         $params = array();
       
   626         foreach ($options as $key => $value) {
       
   627             switch (strtolower($key)) {
       
   628                 case 'user_id':
       
   629                     $params['user_id'] = $this->validInteger($value);
       
   630                     break;
       
   631                 case 'screen_name':
       
   632                     $params['screen_name'] = $value;
       
   633                     break;
       
   634                 case 'count':
       
   635                     $params['count'] = (int) $value;
       
   636                     break;
       
   637                 case 'since_id':
       
   638                     $params['since_id'] = $this->validInteger($value);
       
   639                     break;
       
   640                 case 'max_id':
       
   641                     $params['max_id'] = $this->validInteger($value);
       
   642                     break;
       
   643                 case 'include_entities':
       
   644                     $params['include_entities'] = (bool) $value;
       
   645                     break;
       
   646                 default:
       
   647                     break;
       
   648             }
       
   649         }
       
   650         $response = $this->get($path, $params);
       
   651         return new Zend_Service_Twitter_Response($response);
       
   652     }
       
   653 
       
   654     /**
       
   655      * Create friendship
       
   656      *
       
   657      * @param  int|string $id User ID or name of new friend
       
   658      * @param  array $params Additional parameters to pass
       
   659      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   660      * @throws Exception\DomainException if unable to decode JSON payload
       
   661      * @return Zend_Service_Twitter_Response
       
   662      */
       
   663     public function friendshipsCreate($id, array $params = array())
       
   664     {
       
   665         $this->init();
       
   666         $path    = 'friendships/create';
       
   667         $params  = $this->createUserParameter($id, $params);
       
   668         $allowed = array(
       
   669             'user_id'     => null,
       
   670             'screen_name' => null,
       
   671             'follow'      => null,
       
   672         );
       
   673         $params = array_intersect_key($params, $allowed);
       
   674         $response = $this->post($path, $params);
       
   675         return new Zend_Service_Twitter_Response($response);
       
   676     }
       
   677 
       
   678     /**
       
   679      * Destroy friendship
       
   680      *
       
   681      * @param  int|string $id User ID or name of friend to remove
       
   682      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   683      * @throws Exception\DomainException if unable to decode JSON payload
       
   684      * @return Zend_Service_Twitter_Response
       
   685      */
       
   686     public function friendshipsDestroy($id)
       
   687     {
       
   688         $this->init();
       
   689         $path     = 'friendships/destroy';
       
   690         $params   = $this->createUserParameter($id, array());
       
   691         $response = $this->post($path, $params);
       
   692         return new Zend_Service_Twitter_Response($response);
       
   693     }
       
   694 
       
   695     /**
       
   696      * Search tweets
       
   697      *
       
   698      * $options may include any of the following:
       
   699      * - geocode: a string of the form "latitude, longitude, radius"
       
   700      * - lang: restrict tweets to the two-letter language code
       
   701      * - locale: query is in the given two-letter language code
       
   702      * - result_type: what type of results to receive: mixed, recent, or popular
       
   703      * - count: number of tweets to return per page; up to 100
       
   704      * - until: return tweets generated before the given date
       
   705      * - since_id: return resutls with an ID greater than (more recent than) the given ID
       
   706      * - max_id: return results with an ID less than (older than) the given ID
       
   707      * - include_entities: whether or not to include embedded entities
       
   708      *
       
   709      * @param  string $query
       
   710      * @param  array $options
       
   711      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   712      * @throws Exception\DomainException if unable to decode JSON payload
       
   713      * @return Zend_Service_Twitter_Response
       
   714      */
       
   715     public function searchTweets($query, array $options = array())
       
   716     {
       
   717         $this->init();
       
   718         $path = 'search/tweets';
       
   719 
       
   720         $len = iconv_strlen($query, 'UTF-8');
       
   721         if (0 == $len) {
       
   722             require_once 'Zend/Service/Twitter/Exception.php';
       
   723             throw new Zend_Service_Twitter_Exception(
       
   724                 'Query must contain at least one character'
       
   725             );
       
   726         }
       
   727 
       
   728         $params = array('q' => $query);
       
   729         foreach ($options as $key => $value) {
       
   730             switch (strtolower($key)) {
       
   731                 case 'geocode':
       
   732                     if (!substr_count($value, ',') !== 2) {
       
   733                         require_once 'Zend/Service/Twitter/Exception.php';
       
   734                         throw new Zend_Service_Twitter_Exception(
       
   735                             '"geocode" must be of the format "latitude,longitude,radius"'
       
   736                         );
   352                     }
   737                     }
   353                     $_params['count'] = (int) $count;
   738                     list($latitude, $longitude, $radius) = explode(',', $value);
       
   739                     $radius = trim($radius);
       
   740                     if (!preg_match('/^\d+(mi|km)$/', $radius)) {
       
   741                         require_once 'Zend/Service/Twitter/Exception.php';
       
   742                         throw new Zend_Service_Twitter_Exception(
       
   743                             'Radius segment of "geocode" must be of the format "[unit](mi|km)"'
       
   744                         );
       
   745                     }
       
   746                     $latitude  = (float) $latitude;
       
   747                     $longitude = (float) $longitude;
       
   748                     $params['geocode'] = $latitude . ',' . $longitude . ',' . $radius;
       
   749                     break;
       
   750                 case 'lang':
       
   751                     if (strlen($value) > 2) {
       
   752                         require_once 'Zend/Service/Twitter/Exception.php';
       
   753                         throw new Zend_Service_Twitter_Exception(
       
   754                             'Query language must be a 2 character string'
       
   755                         );
       
   756                     }
       
   757                     $params['lang'] = strtolower($value);
       
   758                     break;
       
   759                 case 'locale':
       
   760                     if (strlen($value) > 2) {
       
   761                         require_once 'Zend/Service/Twitter/Exception.php';
       
   762                         throw new Zend_Service_Twitter_Exception(
       
   763                             'Query locale must be a 2 character string'
       
   764                         );
       
   765                     }
       
   766                     $params['locale'] = strtolower($value);
       
   767                     break;
       
   768                 case 'result_type':
       
   769                     $value = strtolower($value);
       
   770                     if (!in_array($value, array('mixed', 'recent', 'popular'))) {
       
   771                         require_once 'Zend/Service/Twitter/Exception.php';
       
   772                         throw new Zend_Service_Twitter_Exception(
       
   773                             'result_type must be one of "mixed", "recent", or "popular"'
       
   774                         );
       
   775                     }
       
   776                     $params['result_type'] = $value;
       
   777                     break;
       
   778                 case 'count':
       
   779                     $value = (int) $value;
       
   780                     if (1 > $value || 100 < $value) {
       
   781                         require_once 'Zend/Service/Twitter/Exception.php';
       
   782                         throw new Zend_Service_Twitter_Exception(
       
   783                             'count must be between 1 and 100'
       
   784                         );
       
   785                     }
       
   786                     $params['count'] = $value;
       
   787                     break;
       
   788                 case 'until':
       
   789                     if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $value)) {
       
   790                         require_once 'Zend/Service/Twitter/Exception.php';
       
   791                         throw new Zend_Service_Twitter_Exception(
       
   792                             '"until" must be a date in the format YYYY-MM-DD'
       
   793                         );
       
   794                     }
       
   795                     $params['until'] = $value;
   354                     break;
   796                     break;
   355                 case 'since_id':
   797                 case 'since_id':
   356                     $_params['since_id'] = $this->_validInteger($value);
   798                     $params['since_id'] = $this->validInteger($value);
   357                     break;
   799                     break;
   358                 case 'page':
   800                 case 'max_id':
   359                     $_params['page'] = (int) $value;
   801                     $params['max_id'] = $this->validInteger($value);
       
   802                     break;
       
   803                 case 'include_entities':
       
   804                     $params['include_entities'] = (bool) $value;
   360                     break;
   805                     break;
   361                 default:
   806                 default:
   362                     break;
   807                     break;
   363             }
   808             }
   364         }
   809         }
   365         $path .= '.xml';
   810         $response = $this->get($path, $params);
   366         $response = $this->_get($path, $_params);
   811         return new Zend_Service_Twitter_Response($response);
   367         return new Zend_Rest_Client_Result($response->getBody());
   812     }
   368     }
   813 
   369 
   814     /**
   370     /**
   815      * Destroy a status message
   371      * User Timeline status
   816      *
   372      *
   817      * @param  int $id ID of status to destroy
   373      * $params may include one or more of the following keys
   818      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
   374      * - id: ID of a friend whose timeline you wish to receive
   819      * @throws Exception\DomainException if unable to decode JSON payload
   375      * - since_id: return results only after the tweet id specified
   820      * @return Zend_Service_Twitter_Response
   376      * - page: return page X of results
   821      */
   377      * - count: how many statuses to return
   822     public function statusesDestroy($id)
   378      * - max_id: returns only statuses with an ID less than or equal to the specified ID
   823     {
   379      * - user_id: specifies the ID of the user for whom to return the user_timeline
   824         $this->init();
   380      * - screen_name: specfies the screen name of the user for whom to return the user_timeline
   825         $path = 'statuses/destroy/' . $this->validInteger($id);
   381      * - include_rts: whether or not to return retweets
   826         $response = $this->post($path);
   382      * - trim_user: whether to return just the user ID or a full user object; omit to return full object
   827         return new Zend_Service_Twitter_Response($response);
   383      * - include_entities: whether or not to return entities nodes with tweet metadata
   828     }
   384      *
   829 
   385      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
   830     /**
   386      * @return Zend_Rest_Client_Result
   831      * Friend Timeline Status
   387      */
   832      *
   388     public function statusUserTimeline(array $params = array())
   833      * $options may include one or more of the following keys
   389     {
   834      * - count: number of tweets to attempt to retrieve, up to 200
   390         $this->_init();
   835      * - since_id: return results only after the specified tweet id
   391         $path = '/1/statuses/user_timeline';
   836      * - max_id: return results with an ID less than (older than) or equal to the specified ID
   392         $_params = array();
   837      * - trim_user: when set to true, "t", or 1, user object in tweets will include only author's ID.
   393         foreach ($params as $key => $value) {
   838      * - contributor_details: when set to true, includes screen_name of each contributor
       
   839      * - include_entities: when set to false, entities member will be omitted
       
   840      * - exclude_replies: when set to true, will strip replies appearing in the timeline
       
   841      *
       
   842      * @param  array $params
       
   843      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   844      * @throws Exception\DomainException if unable to decode JSON payload
       
   845      * @return Zend_Service_Twitter_Response
       
   846      */
       
   847     public function statusesHomeTimeline(array $options = array())
       
   848     {
       
   849         $this->init();
       
   850         $path = 'statuses/home_timeline';
       
   851         $params = array();
       
   852         foreach ($options as $key => $value) {
   394             switch (strtolower($key)) {
   853             switch (strtolower($key)) {
   395                 case 'id':
       
   396                     $path .= '/' . $value;
       
   397                     break;
       
   398                 case 'page':
       
   399                     $_params['page'] = (int) $value;
       
   400                     break;
       
   401                 case 'count':
   854                 case 'count':
   402                     $count = (int) $value;
   855                     $params['count'] = (int) $value;
   403                     if (0 >= $count) {
   856                     break;
   404                         $count = 1;
   857                 case 'since_id':
   405                     } elseif (200 < $count) {
   858                     $params['since_id'] = $this->validInteger($value);
   406                         $count = 200;
   859                     break;
       
   860                 case 'max_id':
       
   861                     $params['max_id'] = $this->validInteger($value);
       
   862                     break;
       
   863                 case 'trim_user':
       
   864                     if (in_array($value, array(true, 'true', 't', 1, '1'))) {
       
   865                         $value = true;
       
   866                     } else {
       
   867                         $value = false;
   407                     }
   868                     }
   408                     $_params['count'] = $count;
   869                     $params['trim_user'] = $value;
   409                     break;
   870                     break;
   410                 case 'user_id':
   871                 case 'contributor_details:':
   411                     $_params['user_id'] = $this->_validInteger($value);
   872                     $params['contributor_details:'] = (bool) $value;
   412                     break;
   873                     break;
   413                 case 'screen_name':
   874                 case 'include_entities':
   414                     $_params['screen_name'] = $this->_validateScreenName($value);
   875                     $params['include_entities'] = (bool) $value;
       
   876                     break;
       
   877                 case 'exclude_replies':
       
   878                     $params['exclude_replies'] = (bool) $value;
       
   879                     break;
       
   880                 default:
       
   881                     break;
       
   882             }
       
   883         }
       
   884         $response = $this->get($path, $params);
       
   885         return new Zend_Service_Twitter_Response($response);
       
   886     }
       
   887 
       
   888     /**
       
   889      * Get status replies
       
   890      *
       
   891      * $options may include one or more of the following keys
       
   892      * - count: number of tweets to attempt to retrieve, up to 200
       
   893      * - since_id: return results only after the specified tweet id
       
   894      * - max_id: return results with an ID less than (older than) or equal to the specified ID
       
   895      * - trim_user: when set to true, "t", or 1, user object in tweets will include only author's ID.
       
   896      * - contributor_details: when set to true, includes screen_name of each contributor
       
   897      * - include_entities: when set to false, entities member will be omitted
       
   898      *
       
   899      * @param  array $options
       
   900      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   901      * @throws Exception\DomainException if unable to decode JSON payload
       
   902      * @return Zend_Service_Twitter_Response
       
   903      */
       
   904     public function statusesMentionsTimeline(array $options = array())
       
   905     {
       
   906         $this->init();
       
   907         $path   = 'statuses/mentions_timeline';
       
   908         $params = array();
       
   909         foreach ($options as $key => $value) {
       
   910             switch (strtolower($key)) {
       
   911                 case 'count':
       
   912                     $params['count'] = (int) $value;
   415                     break;
   913                     break;
   416                 case 'since_id':
   914                 case 'since_id':
   417                     $_params['since_id'] = $this->_validInteger($value);
   915                     $params['since_id'] = $this->validInteger($value);
   418                     break;
   916                     break;
   419                 case 'max_id':
   917                 case 'max_id':
   420                     $_params['max_id'] = $this->_validInteger($value);
   918                     $params['max_id'] = $this->validInteger($value);
   421                     break;
   919                     break;
   422                 case 'include_rts':
       
   423                 case 'trim_user':
   920                 case 'trim_user':
       
   921                     if (in_array($value, array(true, 'true', 't', 1, '1'))) {
       
   922                         $value = true;
       
   923                     } else {
       
   924                         $value = false;
       
   925                     }
       
   926                     $params['trim_user'] = $value;
       
   927                     break;
       
   928                 case 'contributor_details:':
       
   929                     $params['contributor_details:'] = (bool) $value;
       
   930                     break;
   424                 case 'include_entities':
   931                 case 'include_entities':
   425                     $_params[strtolower($key)] = $value ? '1' : '0';
   932                     $params['include_entities'] = (bool) $value;
   426                     break;
   933                     break;
   427                 default:
   934                 default:
   428                     break;
   935                     break;
   429             }
   936             }
   430         }
   937         }
   431         $path .= '.xml';
   938         $response = $this->get($path, $params);
   432         $response = $this->_get($path, $_params);
   939         return new Zend_Service_Twitter_Response($response);
   433         return new Zend_Rest_Client_Result($response->getBody());
   940     }
       
   941 
       
   942     /**
       
   943      * Public Timeline status
       
   944      *
       
   945      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
   946      * @throws Exception\DomainException if unable to decode JSON payload
       
   947      * @return Zend_Service_Twitter_Response
       
   948      */
       
   949     public function statusesSample()
       
   950     {
       
   951         $this->init();
       
   952         $path = 'statuses/sample';
       
   953         $response = $this->get($path);
       
   954         return new Zend_Service_Twitter_Response($response);
   434     }
   955     }
   435 
   956 
   436     /**
   957     /**
   437      * Show a single status
   958      * Show a single status
   438      *
   959      *
   439      * @param  int $id Id of status to show
   960      * @param  int $id Id of status to show
   440      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
   961      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
   441      * @return Zend_Rest_Client_Result
   962      * @throws Exception\DomainException if unable to decode JSON payload
   442      */
   963      * @return Zend_Service_Twitter_Response
   443     public function statusShow($id)
   964      */
   444     {
   965     public function statusesShow($id)
   445         $this->_init();
   966     {
   446         $path = '/1/statuses/show/' . $this->_validInteger($id) . '.xml';
   967         $this->init();
   447         $response = $this->_get($path);
   968         $path = 'statuses/show/' . $this->validInteger($id);
   448         return new Zend_Rest_Client_Result($response->getBody());
   969         $response = $this->get($path);
       
   970         return new Zend_Service_Twitter_Response($response);
   449     }
   971     }
   450 
   972 
   451     /**
   973     /**
   452      * Update user's current status
   974      * Update user's current status
   453      *
   975      *
       
   976      * @todo   Support additional parameters supported by statuses/update endpoint
   454      * @param  string $status
   977      * @param  string $status
   455      * @param  int $in_reply_to_status_id
   978      * @param  null|int $inReplyToStatusId
   456      * @return Zend_Rest_Client_Result
   979      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
   457      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
   980      * @throws Exception\OutOfRangeException if message is too long
   458      * @throws Zend_Service_Twitter_Exception if message is too short or too long
   981      * @throws Exception\InvalidArgumentException if message is empty
   459      */
   982      * @throws Exception\DomainException if unable to decode JSON payload
   460     public function statusUpdate($status, $inReplyToStatusId = null)
   983      * @return Zend_Service_Twitter_Response
   461     {
   984      */
   462         $this->_init();
   985     public function statusesUpdate($status, $inReplyToStatusId = null)
   463         $path = '/1/statuses/update.xml';
   986     {
       
   987         $this->init();
       
   988         $path = 'statuses/update';
   464         $len = iconv_strlen(htmlspecialchars($status, ENT_QUOTES, 'UTF-8'), 'UTF-8');
   989         $len = iconv_strlen(htmlspecialchars($status, ENT_QUOTES, 'UTF-8'), 'UTF-8');
   465         if ($len > self::STATUS_MAX_CHARACTERS) {
   990         if ($len > self::STATUS_MAX_CHARACTERS) {
   466             include_once 'Zend/Service/Twitter/Exception.php';
   991             require_once 'Zend/Service/Twitter/Exception.php';
   467             throw new Zend_Service_Twitter_Exception(
   992             throw new Zend_Service_Twitter_Exception(
   468                 'Status must be no more than '
   993                 'Status must be no more than '
   469                 . self::STATUS_MAX_CHARACTERS
   994                 . self::STATUS_MAX_CHARACTERS
   470                 . ' characters in length'
   995                 . ' characters in length'
   471             );
   996             );
   472         } elseif (0 == $len) {
   997         } elseif (0 == $len) {
   473             include_once 'Zend/Service/Twitter/Exception.php';
   998             require_once 'Zend/Service/Twitter/Exception.php';
   474             throw new Zend_Service_Twitter_Exception(
   999             throw new Zend_Service_Twitter_Exception(
   475                 'Status must contain at least one character'
  1000                 'Status must contain at least one character'
   476             );
  1001             );
   477         }
  1002         }
   478         $data = array('status' => $status);
  1003 
   479         if (is_numeric($inReplyToStatusId) && !empty($inReplyToStatusId)) {
  1004         $params = array('status' => $status);
   480             $data['in_reply_to_status_id'] = $inReplyToStatusId;
  1005         $inReplyToStatusId = $this->validInteger($inReplyToStatusId);
   481         }
  1006         if ($inReplyToStatusId) {
   482         $response = $this->_post($path, $data);
  1007             $params['in_reply_to_status_id'] = $inReplyToStatusId;
   483         return new Zend_Rest_Client_Result($response->getBody());
  1008         }
   484     }
  1009         $response = $this->post($path, $params);
   485 
  1010         return new Zend_Service_Twitter_Response($response);
   486     /**
  1011     }
   487      * Get status replies
  1012 
   488      *
  1013     /**
   489      * $params may include one or more of the following keys
  1014      * User Timeline status
       
  1015      *
       
  1016      * $options may include one or more of the following keys
       
  1017      * - user_id: Id of a user for whom to fetch favorites
       
  1018      * - screen_name: Screen name of a user for whom to fetch favorites
       
  1019      * - count: number of tweets to attempt to retrieve, up to 200
   490      * - since_id: return results only after the specified tweet id
  1020      * - since_id: return results only after the specified tweet id
   491      * - page: return page X of results
  1021      * - max_id: return results with an ID less than (older than) or equal to the specified ID
   492      *
  1022      * - trim_user: when set to true, "t", or 1, user object in tweets will include only author's ID.
   493      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
  1023      * - exclude_replies: when set to true, will strip replies appearing in the timeline
   494      * @return Zend_Rest_Client_Result
  1024      * - contributor_details: when set to true, includes screen_name of each contributor
   495      */
  1025      * - include_rts: when set to false, will strip native retweets
   496     public function statusReplies(array $params = array())
  1026      *
   497     {
  1027      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
   498         $this->_init();
  1028      * @throws Exception\DomainException if unable to decode JSON payload
   499         $path = '/1/statuses/mentions.xml';
  1029      * @return Zend_Service_Twitter_Response
   500         $_params = array();
  1030      */
   501         foreach ($params as $key => $value) {
  1031     public function statusesUserTimeline(array $options = array())
       
  1032     {
       
  1033         $this->init();
       
  1034         $path = 'statuses/user_timeline';
       
  1035         $params = array();
       
  1036         foreach ($options as $key => $value) {
   502             switch (strtolower($key)) {
  1037             switch (strtolower($key)) {
       
  1038                 case 'user_id':
       
  1039                     $params['user_id'] = $this->validInteger($value);
       
  1040                     break;
       
  1041                 case 'screen_name':
       
  1042                     $params['screen_name'] = $this->validateScreenName($value);
       
  1043                     break;
       
  1044                 case 'count':
       
  1045                     $params['count'] = (int) $value;
       
  1046                     break;
   503                 case 'since_id':
  1047                 case 'since_id':
   504                     $_params['since_id'] = $this->_validInteger($value);
  1048                     $params['since_id'] = $this->validInteger($value);
       
  1049                     break;
       
  1050                 case 'max_id':
       
  1051                     $params['max_id'] = $this->validInteger($value);
       
  1052                     break;
       
  1053                 case 'trim_user':
       
  1054                     if (in_array($value, array(true, 'true', 't', 1, '1'))) {
       
  1055                         $value = true;
       
  1056                     } else {
       
  1057                         $value = false;
       
  1058                     }
       
  1059                     $params['trim_user'] = $value;
       
  1060                     break;
       
  1061                 case 'contributor_details:':
       
  1062                     $params['contributor_details:'] = (bool) $value;
       
  1063                     break;
       
  1064                 case 'exclude_replies':
       
  1065                     $params['exclude_replies'] = (bool) $value;
       
  1066                     break;
       
  1067                 case 'include_rts':
       
  1068                     $params['include_rts'] = (bool) $value;
       
  1069                     break;
       
  1070                 default:
       
  1071                     break;
       
  1072             }
       
  1073         }
       
  1074         $response = $this->get($path, $params);
       
  1075         return new Zend_Service_Twitter_Response($response);
       
  1076     }
       
  1077 
       
  1078     /**
       
  1079      * Search users
       
  1080      *
       
  1081      * $options may include any of the following:
       
  1082      * - page: the page of results to retrieve
       
  1083      * - count: the number of users to retrieve per page; max is 20
       
  1084      * - include_entities: if set to boolean true, include embedded entities
       
  1085      *
       
  1086      * @param  string $query
       
  1087      * @param  array $options
       
  1088      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
       
  1089      * @throws Exception\DomainException if unable to decode JSON payload
       
  1090      * @return Zend_Service_Twitter_Response
       
  1091      */
       
  1092     public function usersSearch($query, array $options = array())
       
  1093     {
       
  1094         $this->init();
       
  1095         $path = 'users/search';
       
  1096 
       
  1097         $len = iconv_strlen($query, 'UTF-8');
       
  1098         if (0 == $len) {
       
  1099             require_once 'Zend/Service/Twitter/Exception.php';
       
  1100             throw new Zend_Service_Twitter_Exception(
       
  1101                 'Query must contain at least one character'
       
  1102             );
       
  1103         }
       
  1104 
       
  1105         $params = array('q' => $query);
       
  1106         foreach ($options as $key => $value) {
       
  1107             switch (strtolower($key)) {
       
  1108                 case 'count':
       
  1109                     $value = (int) $value;
       
  1110                     if (1 > $value || 20 < $value) {
       
  1111                         require_once 'Zend/Service/Twitter/Exception.php';
       
  1112                         throw new Zend_Service_Twitter_Exception(
       
  1113                             'count must be between 1 and 20'
       
  1114                         );
       
  1115                     }
       
  1116                     $params['count'] = $value;
   505                     break;
  1117                     break;
   506                 case 'page':
  1118                 case 'page':
   507                     $_params['page'] = (int) $value;
  1119                     $params['page'] = (int) $value;
       
  1120                     break;
       
  1121                 case 'include_entities':
       
  1122                     $params['include_entities'] = (bool) $value;
   508                     break;
  1123                     break;
   509                 default:
  1124                 default:
   510                     break;
  1125                     break;
   511             }
  1126             }
   512         }
  1127         }
   513         $response = $this->_get($path, $_params);
  1128         $response = $this->get($path, $params);
   514         return new Zend_Rest_Client_Result($response->getBody());
  1129         return new Zend_Service_Twitter_Response($response);
   515     }
  1130     }
   516 
  1131 
   517     /**
  1132 
   518      * Destroy a status message
  1133     /**
   519      *
  1134      * Show extended information on a user
   520      * @param  int $id ID of status to destroy
  1135      *
   521      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
  1136      * @param  int|string $id User ID or name
   522      * @return Zend_Rest_Client_Result
  1137      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
   523      */
  1138      * @throws Exception\DomainException if unable to decode JSON payload
   524     public function statusDestroy($id)
  1139      * @return Zend_Service_Twitter_Response
   525     {
  1140      */
   526         $this->_init();
  1141     public function usersShow($id)
   527         $path = '/1/statuses/destroy/' . $this->_validInteger($id) . '.xml';
  1142     {
   528         $response = $this->_post($path);
  1143         $this->init();
   529         return new Zend_Rest_Client_Result($response->getBody());
  1144         $path     = 'users/show';
   530     }
  1145         $params   = $this->createUserParameter($id, array());
   531 
  1146         $response = $this->get($path, $params);
   532     /**
  1147         return new Zend_Service_Twitter_Response($response);
   533      * User friends
  1148     }
   534      *
  1149 
   535      * @param  int|string $id Id or username of user for whom to fetch friends
  1150     /**
   536      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
  1151      * Initialize HTTP authentication
   537      * @return Zend_Rest_Client_Result
  1152      *
   538      */
  1153      * @return void
   539     public function userFriends(array $params = array())
  1154      * @throws Exception\DomainException if unauthorised
   540     {
  1155      */
   541         $this->_init();
  1156     protected function init()
   542         $path = '/1/statuses/friends';
  1157     {
   543         $_params = array();
  1158         if (!$this->isAuthorised() && $this->getUsername() !== null) {
   544 
  1159             require_once 'Zend/Service/Twitter/Exception.php';
   545         foreach ($params as $key => $value) {
  1160             throw new Zend_Service_Twitter_Exception(
   546             switch (strtolower($key)) {
  1161                 'Twitter session is unauthorised. You need to initialize '
   547                 case 'id':
  1162                 . __CLASS__ . ' with an OAuth Access Token or use '
   548                     $path .= '/' . $value;
  1163                 . 'its OAuth functionality to obtain an Access Token before '
   549                     break;
  1164                 . 'attempting any API actions that require authorisation'
   550                 case 'page':
  1165             );
   551                     $_params['page'] = (int) $value;
  1166         }
   552                     break;
  1167         $client = $this->getHttpClient();
   553                 default:
  1168         $client->resetParameters();
   554                     break;
  1169         if (null === $this->cookieJar) {
       
  1170             $cookieJar = $client->getCookieJar();
       
  1171             if (null === $cookieJar) {
       
  1172                 $cookieJar = new Zend_Http_CookieJar();
   555             }
  1173             }
   556         }
  1174             $this->cookieJar = $cookieJar;
   557         $path .= '.xml';
  1175             $this->cookieJar->reset();
   558 
  1176         } else {
   559         $response = $this->_get($path, $_params);
  1177             $client->setCookieJar($this->cookieJar);
   560         return new Zend_Rest_Client_Result($response->getBody());
  1178         }
   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     }
  1179     }
   923 
  1180 
   924     /**
  1181     /**
   925      * Protected function to validate that the integer is valid or return a 0
  1182      * Protected function to validate that the integer is valid or return a 0
   926      * @param $int
  1183      *
       
  1184      * @param  $int
   927      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
  1185      * @throws Zend_Http_Client_Exception if HTTP request fails or times out
   928      * @return integer
  1186      * @return integer
   929      */
  1187      */
   930     protected function _validInteger($int)
  1188     protected function validInteger($int)
   931     {
  1189     {
   932         if (preg_match("/(\d+)/", $int)) {
  1190         if (preg_match("/(\d+)/", $int)) {
   933             return $int;
  1191             return $int;
   934         }
  1192         }
   935         return 0;
  1193         return 0;
   937 
  1195 
   938     /**
  1196     /**
   939      * Validate a screen name using Twitter rules
  1197      * Validate a screen name using Twitter rules
   940      *
  1198      *
   941      * @param string $name
  1199      * @param string $name
   942      * @throws Zend_Service_Twitter_Exception
       
   943      * @return string
  1200      * @return string
   944      */
  1201      * @throws Exception\InvalidArgumentException
   945     protected function _validateScreenName($name)
  1202      */
   946     {
  1203     protected function validateScreenName($name)
   947         if (!preg_match('/^[a-zA-Z0-9_]{0,15}$/', $name)) {
  1204     {
       
  1205         if (!preg_match('/^[a-zA-Z0-9_]{0,20}$/', $name)) {
   948             require_once 'Zend/Service/Twitter/Exception.php';
  1206             require_once 'Zend/Service/Twitter/Exception.php';
   949             throw new Zend_Service_Twitter_Exception(
  1207             throw new Zend_Service_Twitter_Exception(
   950                 'Screen name, "' . $name
  1208                 'Screen name, "' . $name
   951                 . '" should only contain alphanumeric characters and'
  1209                 . '" should only contain alphanumeric characters and'
   952                 . ' underscores, and not exceed 15 characters.');
  1210                 . ' underscores, and not exceed 15 characters.');
   953         }
  1211         }
   954         return $name;
  1212         return $name;
   955     }
  1213     }
   956 
  1214 
   957     /**
  1215     /**
   958      * Call a remote REST web service URI and return the Zend_Http_Response object
  1216      * Call a remote REST web service URI
   959      *
  1217      *
   960      * @param  string $path            The path to append to the URI
  1218      * @param  string $path The path to append to the URI
   961      * @throws Zend_Rest_Client_Exception
  1219      * @param  Zend_Http_Client $client
       
  1220      * @throws Zend_Http_Client_Exception
   962      * @return void
  1221      * @return void
   963      */
  1222      */
   964     protected function _prepare($path)
  1223     protected function prepare($path, Zend_Http_Client $client)
   965     {
  1224     {
   966         // Get the URI object and configure it
  1225         $client->setUri(self::API_BASE_URI . $path . '.json');
   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 
  1226 
   982         /**
  1227         /**
   983          * Get the HTTP client and configure it for the endpoint URI.
  1228          * Do this each time to ensure oauth calls do not inject new params
   984          * Do this each time because the Zend_Http_Client instance is shared
       
   985          * among all Zend_Service_Abstract subclasses.
       
   986          */
  1229          */
   987         $this->_localHttpClient->resetParameters()->setUri((string) $this->_uri);
  1230         $client->resetParameters();
   988     }
  1231     }
   989 
  1232 
   990     /**
  1233     /**
   991      * Performs an HTTP GET request to the $path.
  1234      * Performs an HTTP GET request to the $path.
   992      *
  1235      *
   993      * @param string $path
  1236      * @param string $path
   994      * @param array  $query Array of GET parameters
  1237      * @param array  $query Array of GET parameters
   995      * @throws Zend_Http_Client_Exception
  1238      * @throws Zend_Http_Client_Exception
   996      * @return Zend_Http_Response
  1239      * @return Zend_Http_Response
   997      */
  1240      */
   998     protected function _get($path, array $query = null)
  1241     protected function get($path, array $query = array())
   999     {
  1242     {
  1000         $this->_prepare($path);
  1243         $client = $this->getHttpClient();
  1001         $this->_localHttpClient->setParameterGet($query);
  1244         $this->prepare($path, $client);
  1002         return $this->_localHttpClient->request(Zend_Http_Client::GET);
  1245         $client->setParameterGet($query);
       
  1246         $response = $client->request(Zend_Http_Client::GET);
       
  1247         return $response;
  1003     }
  1248     }
  1004 
  1249 
  1005     /**
  1250     /**
  1006      * Performs an HTTP POST request to $path.
  1251      * Performs an HTTP POST request to $path.
  1007      *
  1252      *
  1008      * @param string $path
  1253      * @param string $path
  1009      * @param mixed $data Raw data to send
  1254      * @param mixed $data Raw data to send
  1010      * @throws Zend_Http_Client_Exception
  1255      * @throws Zend_Http_Client_Exception
  1011      * @return Zend_Http_Response
  1256      * @return Zend_Http_Response
  1012      */
  1257      */
  1013     protected function _post($path, $data = null)
  1258     protected function post($path, $data = null)
  1014     {
  1259     {
  1015         $this->_prepare($path);
  1260         $client = $this->getHttpClient();
  1016         return $this->_performPost(Zend_Http_Client::POST, $data);
  1261         $this->prepare($path, $client);
       
  1262         $response = $this->performPost(Zend_Http_Client::POST, $data, $client);
       
  1263         return $response;
  1017     }
  1264     }
  1018 
  1265 
  1019     /**
  1266     /**
  1020      * Perform a POST or PUT
  1267      * Perform a POST or PUT
  1021      *
  1268      *
  1025      *
  1272      *
  1026      * @param mixed $method
  1273      * @param mixed $method
  1027      * @param mixed $data
  1274      * @param mixed $data
  1028      * @return Zend_Http_Response
  1275      * @return Zend_Http_Response
  1029      */
  1276      */
  1030     protected function _performPost($method, $data = null)
  1277     protected function performPost($method, $data, Zend_Http_Client $client)
  1031     {
  1278     {
  1032         $client = $this->_localHttpClient;
       
  1033         if (is_string($data)) {
  1279         if (is_string($data)) {
  1034             $client->setRawData($data);
  1280             $client->setRawData($data);
  1035         } elseif (is_array($data) || is_object($data)) {
  1281         } elseif (is_array($data) || is_object($data)) {
  1036             $client->setParameterPost((array) $data);
  1282             $client->setParameterPost((array) $data);
  1037         }
  1283         }
  1038         return $client->request($method);
  1284         return $client->request($method);
  1039     }
  1285     }
  1040 
  1286 
       
  1287     /**
       
  1288      * Create a parameter representing the user
       
  1289      *
       
  1290      * Determines if $id is an integer, and, if so, sets the "user_id" parameter.
       
  1291      * If not, assumes the $id is the "screen_name".
       
  1292      *
       
  1293      * @param  int|string $id
       
  1294      * @param  array $params
       
  1295      * @return array
       
  1296      */
       
  1297     protected function createUserParameter($id, array $params)
       
  1298     {
       
  1299         if ($this->validInteger($id)) {
       
  1300             $params['user_id'] = $id;
       
  1301             return $params;
       
  1302         }
       
  1303 
       
  1304         $params['screen_name'] = $this->validateScreenName($id);
       
  1305         return $params;
       
  1306     }
  1041 }
  1307 }