PageRenderTime 56ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/zend/Zend/Service/Twitter.php

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