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