Twitter.php 31 KB

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