PageRenderTime 53ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/MarkTweet/trunk/proxy/twitter.php

https://github.com/sharpmark/sharpmark
PHP | 1164 lines | 553 code | 177 blank | 434 comment | 39 complexity | 5a84912375bd37a7befb94dfda52de1b MD5 | raw file
  1. <?php
  2. /**
  3. * @package Arc90_Service
  4. * @subpackage Twitter
  5. * @author Matt Williams <matt@mattwilliamsnyc.com>
  6. * @copyright Copyright (c) 2008 {@link http://arc90.com Arc90 Inc.}
  7. * @license http://opensource.org/licenses/bsd-license.php
  8. */
  9. /**
  10. * Software License Agreement (BSD License)
  11. *
  12. * Copyright (c) 2008, Arc90 Inc.
  13. * All rights reserved.
  14. *
  15. * Redistribution and use of this software in source and binary forms, with or
  16. * without modification, are permitted provided that the following conditions
  17. * are met:
  18. *
  19. * - Redistributions of source code must retain the above copyright notice,
  20. * this list of conditions and the following disclaimer.
  21. *
  22. * - Redistributions in binary form must reproduce the above copyright notice,
  23. * this list of conditions and the following disclaimer in the documentation
  24. * and/or other materials provided with the distribution.
  25. *
  26. * - Neither the name of Arc90 Inc. nor the names of its contributors may be
  27. * used to endorse or promote products derived from this software without
  28. * specific prior written permission of Arc90 Inc.
  29. *
  30. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  31. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  32. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  33. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  34. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  35. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  36. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  37. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  38. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  39. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  40. * POSSIBILITY OF SUCH DAMAGE.
  41. */
  42. /**
  43. * @see Arc90_Service_Twitter_Exception
  44. */
  45. require_once('./Exception.php');
  46. /**
  47. * @see Arc90_Service_Twitter_Response
  48. */
  49. require_once('./Response.php');
  50. /**
  51. * Arc90_Service_Twitter provides methods for interacting with the {@link http://twitter.com Twitter} API.
  52. * Based on Twitter {@link http://groups.google.com/group/twitter-development-talk/web/api-documentation documentation}
  53. *
  54. * NOTE: Support for the $id parameter has been
  55. * {@link http://groups.google.com/group/twitter-development-talk/browse_thread/thread/89a7292e5a9eee6d disabled} by
  56. * Twitter for several documented API calls.
  57. *
  58. * @package Arc90_Service
  59. * @subpackage Twitter
  60. * @author Matt Williams <matt@mattwilliamsnyc.com>
  61. * @copyright Copyright (c) 2008 {@link http://arc90.com Arc90 Inc.}
  62. * @license http://opensource.org/licenses/bsd-license.php
  63. */
  64. class Arc90_Service_Twitter
  65. {
  66. /**
  67. * Base URL for the Twitter API.
  68. */
  69. const API_URL = 'http://twitter.com';
  70. // API URLs
  71. const PATH_STATUS_PUBLIC = '/statuses/public_timeline';
  72. const PATH_STATUS_FRIENDS = '/statuses/friends_timeline';
  73. const PATH_STATUS_USER = '/statuses/user_timeline';
  74. const PATH_STATUS_SHOW = '/statuses/show';
  75. const PATH_STATUS_UPDATE = '/statuses/update';
  76. const PATH_STATUS_REPLIES = '/statuses/replies';
  77. const PATH_STATUS_DESTROY = '/statuses/destroy';
  78. const PATH_USER_FRIENDS = '/statuses/friends';
  79. const PATH_USER_FOLLOWERS = '/statuses/followers';
  80. const PATH_USER_FEATURED = '/statuses/featured';
  81. const PATH_USER_SHOW = '/users/show';
  82. const PATH_DM_MESSAGES = '/direct_messages';
  83. const PATH_DM_SENT = '/direct_messages/sent';
  84. const PATH_DM_NEW = '/direct_messages/new';
  85. const PATH_DM_DESTROY = '/direct_messages/destroy';
  86. const PATH_FRIEND_CREATE = '/friendships/create';
  87. const PATH_FRIEND_DESTROY = '/friendships/destroy';
  88. const PATH_FRIEND_EXISTS = '/friendships/exists';
  89. const PATH_ACCT_VERIFY = '/account/verify_credentials';
  90. const PATH_ACCT_END_SESS = '/account/end_session';
  91. const PATH_ACCT_ARCHIVE = '/account/archive';
  92. const PATH_ACCT_LOCATION = '/account/update_location';
  93. const PATH_ACCT_DEVICE = '/account/update_delivery_device';
  94. const PATH_FAV_FAVORITES = '/favorites';
  95. const PATH_FAV_CREATE = '/favorites/create';
  96. const PATH_FAV_DESTROY = '/favorites/destroy';
  97. const PATH_NOTIF_FOLLOW = '/notifications/follow';
  98. const PATH_NOTIF_LEAVE = '/notifications/leave';
  99. const PATH_BLOCK_CREATE = '/blocks/create';
  100. const PATH_BLOCK_DESTROY = '/blocks/destroy';
  101. const PATH_HELP_TEST = '/help/test';
  102. const PATH_HELP_DOWNTIME = '/help/downtime_schedule';
  103. // END API URLs
  104. /**
  105. * Maximum 'count' parameter for timeline requests
  106. */
  107. const MAX_COUNT = 20;
  108. /**
  109. * Maximum length (in number of characters) of status updates
  110. */
  111. const STATUS_MAXLENGTH = 140;
  112. /**
  113. * Twitter account username.
  114. * @var string
  115. */
  116. protected $_authUsername ='';
  117. /**
  118. * Twitter account password.
  119. * @var string
  120. */
  121. protected $_authPassword ='';
  122. /**
  123. * Unix time of the most recent API call.
  124. * @var integer
  125. */
  126. protected $_lastRequestTime =0;
  127. /**
  128. * Response to the most recent API call.
  129. * @var string
  130. */
  131. protected $_lastResponse =null;
  132. /**
  133. * Constructs a new Twitter Web Service Client.
  134. *
  135. * @param string $username Twitter account username
  136. * @param string $password Twitter account password
  137. */
  138. public function __construct($username =null, $password =null)
  139. {
  140. $this->setAuth($username, $password);
  141. }
  142. /**
  143. * Set client username and password.
  144. *
  145. * @param string $username Twitter account username
  146. * @param string $password Twitter account password
  147. * @return Arc90_Service_Twitter Provides a fluent interface.
  148. */
  149. public function setAuth($username, $password)
  150. {
  151. $this->_authUsername = $username;
  152. $this->_authPassword = $password;
  153. return $this;
  154. }
  155. /**
  156. * Returns the 20 most recent statuses from non-protected users who have set a custom user icon.
  157. * Does not require authentication.
  158. *
  159. * @param string $format Response format (JSON,XML,RSS,ATOM); Defaults to JSON
  160. * @param integer $since_id Returns only statuses more recent than the specified ID
  161. * @return Arc90_Service_Twitter_Response
  162. * @throws Arc90_Service_Twitter_Exception
  163. */
  164. public function getPublicTimeline($format ='json', $since_id =0)
  165. {
  166. $requestedFormat = strtolower($format);
  167. $validFormats = array('json', 'xml', 'rss', 'atom');
  168. $this->_validateOption($requestedFormat, $validFormats);
  169. $url = self::PATH_STATUS_PUBLIC . ".{$requestedFormat}";
  170. if(0 !== $since_id)
  171. {
  172. $this->_validateNonNegativeInteger('since_id', $since_id);
  173. $url .= "?since_id={$since_id}";
  174. }
  175. return $this->_makeRequest($url, $requestedFormat);
  176. }
  177. /**
  178. * Returns the 20 most recent statuses posted from the authenticating user and that user's friends.
  179. *
  180. * @param string $format Response format (JSON,XML,RSS,ATOM); Defaults to JSON
  181. * @param string $since Narrows returned results to those statuses created after the specified date
  182. * @param integer $page Gets the specified page of results (20 results per page)
  183. * @return Arc90_Service_Twitter_Response
  184. * @throws Arc90_Service_Twitter_Exception
  185. */
  186. public function getFriendsTimeline($format ='json', $since ='', $page =0)
  187. {
  188. $requestedFormat = strtolower($format);
  189. $validFormats = array('json', 'xml', 'rss', 'atom');
  190. $this->_validateOption($requestedFormat, $validFormats);
  191. $url = self::PATH_STATUS_FRIENDS . ".{$requestedFormat}";
  192. $args = array();
  193. if('' !== $since)
  194. {
  195. $this->_validateDateString('since', $since);
  196. $args []= 'since=' . urlencode(date('D j M Y G:i:s T', strtotime($since)));
  197. }
  198. if(0 !== $page)
  199. {
  200. $this->_validateNonNegativeInteger('page', $page);
  201. $args []= "page={$page}";
  202. }
  203. if(count($args))
  204. {
  205. $url .= '?' . implode('&', $args);
  206. }
  207. return $this->_makeRequest($url, $requestedFormat, true);
  208. }
  209. /**
  210. * Returns the 20 most recent statuses posted from the authenticating user.
  211. *
  212. * @param string $format Response format (JSON,XML,RSS,ATOM); Defaults to JSON
  213. * @param string $since Narrows returned results to those statuses created after the specified date
  214. * @param integer $count Specifies the number of statuses to retrieve (Must be <= 20)
  215. * @param integer $page Gets the specified page of results (20 results per page)
  216. * @return Arc90_Service_Twitter_Response
  217. * @throws Arc90_Service_Twitter_Exception
  218. */
  219. public function getUserTimeline($format ='json', $since ='', $count =0, $page =0)
  220. {
  221. $requestedFormat = strtolower($format);
  222. $validFormats = array('json', 'xml', 'rss', 'atom');
  223. $this->_validateOption($requestedFormat, $validFormats);
  224. $url = self::PATH_STATUS_USER . ".{$requestedFormat}";
  225. $args = array();
  226. if('' !== $since)
  227. {
  228. $this->_validateDateString('since', $since);
  229. $args []= 'since=' . urlencode(date('D j M Y G:i:s T', strtotime($since)));
  230. }
  231. if(0 !== $count)
  232. {
  233. $this->_validateNonNegativeInteger('count', $count);
  234. $max = self::MAX_COUNT;
  235. if($max < $count)
  236. {
  237. throw new Arc90_Service_Twitter_Exception(
  238. "Invalid parameter (count): '{$count}'. Must be <= {$max}."
  239. );
  240. }
  241. $args []= "count={$count}";
  242. }
  243. if(0 !== $page)
  244. {
  245. $this->_validateNonNegativeInteger('page', $page);
  246. $args []= "page={$page}";
  247. }
  248. if(count($args))
  249. {
  250. $url .= '?' . implode('&', $args);
  251. }
  252. return $this->_makeRequest($url, $requestedFormat, true);
  253. }
  254. /**
  255. * Returns a single status, specified by the id parameter below.
  256. * The status's author will be returned inline.
  257. *
  258. * @param integer $id Numerical ID of the status to be retrieved
  259. * @param string $format Response format (JSON,XML); Defaults to JSON
  260. * @return Arc90_Service_Twitter_Response
  261. * @throws Arc90_Service_Twitter_Exception
  262. */
  263. public function showStatus($id, $format ='json')
  264. {
  265. $requestedFormat = strtolower($format);
  266. $validFormats = array('json', 'xml');
  267. $this->_validateOption($requestedFormat, $validFormats);
  268. $this->_validateNonNegativeInteger('id', $id);
  269. $url = self::PATH_STATUS_SHOW . "/{$id}.{$requestedFormat}";
  270. return $this->_makeRequest($url, $requestedFormat, true);
  271. }
  272. /**
  273. * Updates the authenticating user's status. Requires the status parameter specified below.
  274. *
  275. * @param string $status The text of your status update. Must not exceed 140 characters
  276. * @param string $format Response format (JSON,XML); Defaults to JSON
  277. * @return Arc90_Service_Twitter_Response
  278. * @throws Arc90_Service_Twitter_Exception
  279. */
  280. public function updateStatus($status, $format ='json')
  281. {
  282. $requestedFormat = strtolower($format);
  283. $validFormats = array('json', 'xml');
  284. $this->_validateOption($requestedFormat, $validFormats);
  285. $max = self::STATUS_MAXLENGTH;
  286. if($max < strlen($status))
  287. {
  288. throw new Arc90_Service_Twitter_Exception(
  289. "Status updates may not exceed {$max} characters!"
  290. );
  291. }
  292. $url = self::PATH_STATUS_UPDATE . ".{$requestedFormat}";
  293. $url .= '?status=' . urlencode(stripslashes(urldecode($status)));
  294. return $this->_makeRequest($url, $requestedFormat, true, true);
  295. }
  296. /**
  297. * Returns the 20 most recent replies (updates prefixed with @username posted by friends of authenticating user).
  298. *
  299. * @param string $format Response format (JSON,XML,RSS,ATOM); Defaults to JSON
  300. * @param integer $page Gets the specified page of results (20 results per page)
  301. * @return Arc90_Service_Twitter_Response
  302. * @throws Arc90_Service_Twitter_Exception
  303. */
  304. public function getReplies($format ='json', $page =0)
  305. {
  306. $requestedFormat = strtolower($format);
  307. $validFormats = array('json', 'xml', 'rss', 'atom');
  308. $this->_validateOption($requestedFormat, $validFormats);
  309. $url = self::PATH_STATUS_REPLIES . ".{$requestedFormat}";
  310. if(0 !== $page)
  311. {
  312. $this->_validateNonNegativeInteger('page', $page);
  313. $url .= "?page={$page}";
  314. }
  315. return $this->_makeRequest($url, $requestedFormat, true);
  316. }
  317. /**
  318. * Destroys the status specified by the required ID parameter.
  319. * The authenticating user must be the author of the specified status.
  320. *
  321. * @param integer $id The ID of the status to destroy
  322. * @param string $format Response format (JSON,XML); Defaults to JSON
  323. * @return Arc90_Service_Twitter_Response
  324. * @throws Arc90_Service_Twitter_Exception
  325. */
  326. public function destroyStatus($id, $format ='json')
  327. {
  328. $requestedFormat = strtolower($format);
  329. $validFormats = array('json', 'xml');
  330. $this->_validateOption($requestedFormat, $validFormats);
  331. $this->_validateNonNegativeInteger('id', $id);
  332. $url = self::PATH_STATUS_DESTROY . "/{$id}.{$requestedFormat}";
  333. return $this->_makeRequest($url, $requestedFormat, true);
  334. }
  335. /**
  336. * Returns up to 100 of the authenticating user's friends who have recently updated, with current status inline.
  337. *
  338. * @param string $format Response format (JSON,XML); Defaults to JSON
  339. * @param integer $page Gets the specified page of results (100 results per page)
  340. * @param boolean $lite Prevents the inline inclusion of current status
  341. * @return Arc90_Service_Twitter_Response
  342. * @throws Arc90_Service_Twitter_Exception
  343. */
  344. public function getFriends($format ='json', $page =0, $lite =false)
  345. {
  346. $requestedFormat = strtolower($format);
  347. $validFormats = array('json', 'xml');
  348. $this->_validateOption($requestedFormat, $validFormats);
  349. $url = self::PATH_USER_FRIENDS . ".{$requestedFormat}";
  350. $args = array();
  351. if(0 !== $page)
  352. {
  353. $this->_validateNonNegativeInteger('page', $page);
  354. $args []= "page={$page}";
  355. }
  356. if($lite)
  357. {
  358. $args []= 'lite=true';
  359. }
  360. if(count($args))
  361. {
  362. $url .= '?' . implode('&', $args);
  363. }
  364. return $this->_makeRequest($url, $requestedFormat, true);
  365. }
  366. /**
  367. * Returns up to 100 of the authenticating user's followers, each with current status inline.
  368. *
  369. * @param string $format Response format (JSON,XML); Defaults to JSON
  370. * @param integer $page Gets the specified page of results (100 results per page)
  371. * @param integer $lite Prevents the inline inclusion of current status.
  372. * @return Arc90_Service_Twitter_Response
  373. * @throws Arc90_Service_Twitter_Exception
  374. */
  375. public function getFollowers($format ='json', $page =0, $lite =false)
  376. {
  377. $requestedFormat = strtolower($format);
  378. $validFormats = array('json', 'xml');
  379. $this->_validateOption($requestedFormat, $validFormats);
  380. $url = self::PATH_USER_FOLLOWERS . ".{$requestedFormat}";
  381. $args = array();
  382. if(0 !== $page)
  383. {
  384. $this->_validateNonNegativeInteger('page', $page);
  385. $args []= "page={$page}";
  386. }
  387. if($lite)
  388. {
  389. $args []= 'lite=true';
  390. }
  391. if(count($args))
  392. {
  393. $url .= '?' . implode('&', $args);
  394. }
  395. return $this->_makeRequest($url, $requestedFormat, true);
  396. }
  397. /**
  398. * Returns a list of the users currently featured on Twitter with their current statuses inline.
  399. * Does not require authentication.
  400. *
  401. * @param string $format Response format (JSON,XML); Defaults to JSON
  402. * @return Arc90_Service_Twitter_Response
  403. * @throws Arc90_Service_Twitter_Exception
  404. */
  405. public function getFeatured($format ='json')
  406. {
  407. $requestedFormat = strtolower($format);
  408. $validFormats = array('json', 'xml');
  409. $this->_validateOption($requestedFormat, $validFormats);
  410. $url = self::PATH_USER_FEATURED . ".{$requestedFormat}";
  411. return $this->_makeRequest($url, $requestedFormat);
  412. }
  413. /**
  414. * Returns extended information of a given user, specified by ID or screen name via the required user parameter.
  415. * This includes design settings, so third party developers can theme widgets according to a user's preferences.
  416. *
  417. * @param mixed $user The ID or screen name of a user.
  418. * @param string $format Response format (JSON,XML); Defaults to JSON
  419. * @return Arc90_Service_Twitter_Response
  420. * @throws Arc90_Service_Twitter_Exception
  421. */
  422. public function showUser($user, $format ='json')
  423. {
  424. $requestedFormat = strtolower($format);
  425. $validFormats = array('json', 'xml');
  426. $this->_validateOption($requestedFormat, $validFormats);
  427. $user = urlencode($user);
  428. $url = self::PATH_USER_SHOW . "/{$user}.{$requestedFormat}";
  429. return $this->_makeRequest($url, $requestedFormat, true);
  430. }
  431. /**
  432. * Returns a list of the 20 most recent direct messages sent to the authenticating user.
  433. * The XML and JSON versions include detailed information about the sending and recipient users.
  434. *
  435. * @param string $format Response format (JSON,XML,RSS,ATOM); Defaults to JSON
  436. * @param string $since Narrows returned results to those statuses created after the specified date
  437. * @param integer $since_id Returns only messages more recent than the specified ID
  438. * @param integer $page Gets the specified page of results (20 results per page)
  439. * @return Arc90_Service_Twitter_Response
  440. * @throws Arc90_Service_Twitter_Exception
  441. */
  442. public function getMessages($format ='json', $since ='', $since_id =0, $page =0)
  443. {
  444. $requestedFormat = strtolower($format);
  445. $validFormats = array('json', 'xml', 'rss', 'atom');
  446. $this->_validateOption($requestedFormat, $validFormats);
  447. $url = self::PATH_DM_MESSAGES . ".{$requestedFormat}";
  448. if('' !== $since)
  449. {
  450. $this->_validateDateString('since', $since);
  451. $args []= 'since=' . urlencode(date('D j M Y G:i:s T', strtotime($since)));
  452. }
  453. if(0 !== $since_id)
  454. {
  455. $this->_validateNonNegativeInteger('since_id', $since_id);
  456. $args []= "since_id={$since_id}";
  457. }
  458. if(0 !== $page)
  459. {
  460. $this->_validateNonNegativeInteger('page', $page);
  461. $args []= "page={$page}";
  462. }
  463. if(count($args))
  464. {
  465. $url .= '?' . implode('&', $args);
  466. }
  467. return $this->_makeRequest($url, $requestedFormat, true);
  468. }
  469. /**
  470. * Returns a list of the 20 most recent direct messages sent by the authenticating user.
  471. * The XML and JSON versions include detailed information about the sending and recipient users.
  472. *
  473. * @param string $format Response format (JSON,XML); Defaults to JSON
  474. * @param string $since Narrows returned results to those statuses created after the specified date
  475. * @param integer $since_id Returns only messages more recent than the specified ID
  476. * @param integer $page Gets the specified page of results (20 results per page)
  477. * @return Arc90_Service_Twitter_Response
  478. * @throws Arc90_Service_Twitter_Exception
  479. */
  480. public function getSentMessages($format ='json', $since ='', $since_id =0, $page =0)
  481. {
  482. $requestedFormat = strtolower($format);
  483. $validFormats = array('json', 'xml');
  484. $this->_validateOption($requestedFormat, $validFormats);
  485. $url = self::PATH_DM_SENT . ".{$requestedFormat}";
  486. $args = array();
  487. if('' !== $since)
  488. {
  489. $this->_validateDateString('since', $since);
  490. $args []= 'since=' . urlencode(date('D j M Y G:i:s T', strtotime($since)));
  491. }
  492. if(0 !== $since_id)
  493. {
  494. $this->_validateNonNegativeInteger('since_id', $since_id);
  495. $args []= "since_id={$since_id}";
  496. }
  497. if(0 !== $page)
  498. {
  499. $this->_validateNonNegativeInteger('page', $page);
  500. $args []= "page={$page}";
  501. }
  502. if(count($args))
  503. {
  504. $url .= '?' . implode('&', $args);
  505. }
  506. return $this->_makeRequest($url, $requestedFormat, true);
  507. }
  508. /**
  509. * Sends a new direct message to the specified user from the authenticating user.
  510. * Returns the sent message in the requested format when successful.
  511. *
  512. * @param mixed $user The ID or screen name of the recipient user.
  513. * @param string $text The text of your direct message. Must not exceed 140 characters
  514. * @param string $format Response format (JSON,XML); Defaults to JSON
  515. * @return Arc90_Service_Twitter_Response
  516. * @throws Arc90_Service_Twitter_Exception
  517. */
  518. public function sendMessage($user, $text, $format ='json')
  519. {
  520. $requestedFormat = strtolower($format);
  521. $validFormats = array('json', 'xml');
  522. $this->_validateOption($requestedFormat, $validFormats);
  523. $url = self::PATH_DM_NEW . ".{$requestedFormat}";
  524. $max = self::STATUS_MAXLENGTH;
  525. if($max < strlen($text))
  526. {
  527. throw new Arc90_Service_Twitter_Exception(
  528. "Message length may not exceed {$max} characters!"
  529. );
  530. }
  531. $user = urlencode($user);
  532. $text = urlencode(stripslashes(urldecode($text)));
  533. $data = "user={$user}&text={$text}";
  534. return $this->_makeRequest($url, $requestedFormat, true, true, $data);
  535. }
  536. /**
  537. * Destroys the direct message specified by the required ID parameter.
  538. * The authenticating user must be the recipient of the specified direct message.
  539. *
  540. * @param integer $id The ID of the direct message to destroy
  541. * @param string $format Response format (JSON,XML); Defaults to JSON
  542. * @return Arc90_Service_Twitter_Response
  543. * @throws Arc90_Service_Twitter_Exception
  544. */
  545. public function destroyMessage($id, $format ='json')
  546. {
  547. $requestedFormat = strtolower($format);
  548. $validFormats = array('json', 'xml');
  549. $this->_validateOption($requestedFormat, $validFormats);
  550. $this->_validateNonNegativeInteger('id', $id);
  551. $url = self::PATH_DM_DESTROY . "/{$id}.{$requestedFormat}";
  552. return $this->_makeRequest($url, $requestedFormat, true);
  553. }
  554. /**
  555. * Befriends the user specified in the ID parameter as the authenticating user.
  556. * Returns the befriended user in the requested format when successful.
  557. * Returns a string describing the failure condition when unsuccessful.
  558. *
  559. * @param mixed $user The ID or screen name of the user to befriend
  560. * @param string $format Response format (JSON,XML); Defaults to JSON
  561. * @return Arc90_Service_Twitter_Response
  562. * @throws Arc90_Service_Twitter_Exception
  563. */
  564. public function createFriendship($user, $format ='json')
  565. {
  566. $requestedFormat = strtolower($format);
  567. $validFormats = array('json', 'xml');
  568. $this->_validateOption($requestedFormat, $validFormats);
  569. $user = urlencode($user);
  570. $url = self::PATH_FRIEND_CREATE . "/{$user}.{$requestedFormat}";
  571. return $this->_makeRequest($url, $requestedFormat, true);
  572. }
  573. /**
  574. * Discontinues friendship with the user specified in the ID parameter as the authenticating user.
  575. * Returns the un-friended user in the requested format when successful.
  576. * Returns a string describing the failure condition when unsuccessful.
  577. *
  578. * @param mixed $user The ID or screen name of the user with whom to discontinue friendship
  579. * @param string $format Response format (JSON,XML); Defaults to JSON
  580. * @return Arc90_Service_Twitter_Response
  581. * @throws Arc90_Service_Twitter_Exception
  582. */
  583. public function destroyFriendship($user, $format ='json')
  584. {
  585. $requestedFormat = strtolower($format);
  586. $validFormats = array('json', 'xml');
  587. $this->_validateOption($requestedFormat, $validFormats);
  588. $user = urlencode($user);
  589. $url = self::PATH_FRIEND_DESTROY . "/{$user}.{$requestedFormat}";
  590. return $this->_makeRequest($url, $requestedFormat, true);
  591. }
  592. /**
  593. * Tests if friendship exists between the two users specified in the parameters below.
  594. *
  595. * @param mixed $userA The ID or screen name of the first user to test friendship for.
  596. * @param mixed $userB The ID or screen name of the second user to test friendship for.
  597. * @param string $format Response format (JSON,XML,none); Defaults to JSON
  598. * @return Arc90_Service_Twitter_Response
  599. * @throws Arc90_Service_Twitter_Exception
  600. */
  601. public function friendshipExists($userA, $userB, $format ='json')
  602. {
  603. $requestedFormat = strtolower($format);
  604. $validFormats = array('json', 'xml', 'none');
  605. $this->_validateOption($requestedFormat, $validFormats);
  606. $url = self::PATH_FRIEND_EXISTS;
  607. if('none' !== $requestedFormat)
  608. {
  609. $url .= ".{$requestedFormat}";
  610. }
  611. $userA = urlencode($userA);
  612. $userB = urlencode($userB);
  613. $url .= "?user_a={$userA}&user_b={$userB}";
  614. return $this->_makeRequest($url, $requestedFormat, true);
  615. }
  616. /**
  617. * Returns an HTTP 200 OK response code and a format-specific response if authentication was successful.
  618. * Use this method to test if supplied user credentials are valid with minimal overhead.
  619. *
  620. * @param string $format Response format (JSON,XML,none); Defaults to JSON
  621. * @return Arc90_Service_Twitter_Response
  622. * @throws Arc90_Service_Twitter_Exception
  623. */
  624. public function verifyCredentials($format ='json')
  625. {
  626. $requestedFormat = strtolower($format);
  627. $validFormats = array('json', 'xml','none');
  628. $this->_validateOption($requestedFormat, $validFormats);
  629. $url = self::PATH_ACCT_VERIFY;
  630. if('none' !== $requestedFormat)
  631. {
  632. $url .= ".{$requestedFormat}";
  633. }
  634. return $this->_makeRequest($url, $requestedFormat, true);
  635. }
  636. /**
  637. * Ends the session of the authenticating user, returning a null cookie.
  638. * Use this method to sign users out of client-facing applications like widgets.
  639. *
  640. * @return Arc90_Service_Twitter_Response
  641. * @throws Arc90_Service_Twitter_Exception
  642. */
  643. public function endSession()
  644. {
  645. $url = self::PATH_ACCT_END_SESS;
  646. return $this->_makeRequest($url, 'none', true);
  647. }
  648. /**
  649. * Returns 80 statuses per page for the authenticating user, ordered by descending date of posting.
  650. * Use this method to rapidly export your archive of statuses.
  651. *
  652. * @param string $format Response format (JSON,XML); Defaults to JSON
  653. * @param string $since Narrows returned results to those statuses created after the specified date
  654. * @param integer $since_id Returns only messages more recent than the specified ID
  655. * @param integer $page Gets the specified page of results (80 results per page)
  656. * @return Arc90_Service_Twitter_Response
  657. * @throws Arc90_Service_Twitter_Exception
  658. */
  659. public function getArchive($format ='json', $since =0, $since_id =0, $page =0)
  660. {
  661. $requestedFormat = strtolower($format);
  662. $validFormats = array('json', 'xml');
  663. $this->_validateOption($requestedFormat, $validFormats);
  664. $url = self::PATH_ACCT_ARCHIVE . ".{$requestedFormat}";
  665. $args = array();
  666. if('' !== $since)
  667. {
  668. $this->_validateDateString('since', $since);
  669. $args []= 'since=' . urlencode(date('D j M Y G:i:s T', strtotime($since)));
  670. }
  671. if(0 !== $since_id)
  672. {
  673. $this->_validateNonNegativeInteger('since_id', $since_id);
  674. $args []= "since_id={$since_id}";
  675. }
  676. if(0 !== $page)
  677. {
  678. $this->_validateNonNegativeInteger('page', $page);
  679. $args []= "page={$page}";
  680. }
  681. if(count($args))
  682. {
  683. $url .= '?' . implode('&', $args);
  684. }
  685. return $this->_makeRequest($url, $requestedFormat, true);
  686. }
  687. /**
  688. * Updates the location of the authenticating user, as displayed in their profile and returned in API calls.
  689. *
  690. * @param string $location The location of the user. Please note that this is not normalized or translated.
  691. * @param string $format Response format (JSON,XML); Defaults to JSON
  692. * @return Arc90_Service_Twitter_Response
  693. * @throws Arc90_Service_Twitter_Exception
  694. */
  695. public function updateLocation($location, $format ='json')
  696. {
  697. $requestedFormat = strtolower($format);
  698. $validFormats = array('json', 'xml');
  699. $this->_validateOption($requestedFormat, $validFormats);
  700. $location = urlencode($location);
  701. $data = "location={$location}";
  702. return $this->_makeRequest($url, $requestedFormat, true, true, $data);
  703. }
  704. /**
  705. * Sets which device Twitter delivers updates to for the authenticating user.
  706. * Sending none as the device parameter will disable IM or SMS updates.
  707. *
  708. * @param string $device Must be one of: sms, im, none.
  709. * @param string $format Response format (JSON,XML); Defaults to JSON
  710. * @return Arc90_Service_Twitter_Response
  711. * @throws Arc90_Service_Twitter_Exception
  712. */
  713. public function updateDeliveryDevice($device, $format ='json')
  714. {
  715. $requestedFormat = strtolower($format);
  716. $validFormats = array('json', 'xml');
  717. $this->_validateOption($requestedFormat, $validFormats);
  718. $requestedDevice = strtolower($device);
  719. $validDevices = array('sms', 'im', 'none');
  720. $this->_validateOption($requestedDevice, $validDevices);
  721. $device = urlencode($device);
  722. $data = "device={$device}";
  723. return $this->_makeRequest($url, $requestedFormat, true, true, $data);
  724. }
  725. /**
  726. * Returns 20 most recent favorite statuses for the authenticating user.
  727. *
  728. * @param string $format Response format (JSON,XML,RSS,ATOM); Defaults to JSON
  729. * @param integer $page Gets the specified page of results (20 results per page)
  730. * @return Arc90_Service_Twitter_Response
  731. * @throws Arc90_Service_Twitter_Exception
  732. */
  733. public function getFavorites($format ='json', $page =0)
  734. {
  735. $requestedFormat = strtolower($format);
  736. $validFormats = array('json', 'xml', 'rss', 'atom');
  737. $this->_validateOption($requestedFormat, $validFormats);
  738. $url = self::PATH_FAV_FAVORITES . ".{$requestedFormat}";
  739. if(0 !== $page)
  740. {
  741. $this->_validateNonNegativeInteger('page', $page);
  742. $url .= "?page={$page}";
  743. }
  744. return $this->_makeRequest($url, $requestedFormat, true);
  745. }
  746. /**
  747. * Favorites the status specified in the ID parameter as the authenticating user.
  748. * Returns the favorite status when successful.
  749. *
  750. * @param integer $id The ID of the status to favorite.
  751. * @param string $format Response format (JSON,XML); Defaults to JSON
  752. * @return Arc90_Service_Twitter_Response
  753. * @throws Arc90_Service_Twitter_Exception
  754. */
  755. public function createFavorite($id, $format ='json')
  756. {
  757. $requestedFormat = strtolower($format);
  758. $validFormats = array('json', 'xml');
  759. $this->_validateOption($requestedFormat, $validFormats);
  760. $this->_validateNonNegativeInteger('id', $id);
  761. $url = self::PATH_FAV_CREATE . "/{$id}.{$requestedFormat}";
  762. return $this->_makeRequest($url, $requestedFormat, true);
  763. }
  764. /**
  765. * Un-favorites the status specified in the ID parameter as the authenticating user.
  766. * Returns the un-favorited status in the requested format when successful.
  767. *
  768. * @param integer $id The ID of the status to un-favorite.
  769. * @param string $format Response format (JSON,XML); Defaults to JSON
  770. * @return Arc90_Service_Twitter_Response
  771. * @throws Arc90_Service_Twitter_Exception
  772. */
  773. public function destroyFavorite($id, $format ='json')
  774. {
  775. $requestedFormat = strtolower($format);
  776. $validFormats = array('json', 'xml');
  777. $this->_validateOption($requestedFormat, $validFormats);
  778. $this->_validateNonNegativeInteger('id', $id);
  779. $url = self::PATH_FAV_DESTROY . "/{$id}.{$requestedFormat}";
  780. return $this->_makeRequest($url, $requestedFormat, true);
  781. }
  782. /**
  783. * Enables notifications for updates from the specified user to the authenticating user.
  784. * Returns the specified user when successful.
  785. *
  786. * @param mixed $user The ID or screenname of the user to follow.
  787. * @param string $format Response format (JSON,XML); Defaults to JSON
  788. * @return Arc90_Service_Twitter_Response
  789. * @throws Arc90_Service_Twitter_Exception
  790. */
  791. public function follow($user, $format ='json')
  792. {
  793. $requestedFormat = strtolower($format);
  794. $validFormats = array('json', 'xml');
  795. $this->_validateOption($requestedFormat, $validFormats);
  796. $url = self::PATH_NOTIF_FOLLOW . "/{$user}.{$requestedFormat}";
  797. return $this->_makeRequest($url, $requestedFormat, true);
  798. }
  799. /**
  800. * Disables notifications for updates from the specified user to the authenticating user.
  801. * Returns the specified user when successful.
  802. *
  803. * @param mixed $user The ID or screenname of the user to stop following.
  804. * @param string $format Response format (JSON,XML); Defaults to JSON
  805. * @return Arc90_Service_Twitter_Response
  806. * @throws Arc90_Service_Twitter_Exception
  807. */
  808. public function leave($user, $format ='json')
  809. {
  810. $requestedFormat = strtolower($format);
  811. $validFormats = array('json', 'xml');
  812. $this->_validateOption($requestedFormat, $validFormats);
  813. $url = self::PATH_NOTIF_LEAVE . "/{$user}.{$requestedFormat}";
  814. return $this->_makeRequest($url, $requestedFormat, true);
  815. }
  816. /**
  817. * Blocks the user specified in the ID parameter as the authenticating user.
  818. * Returns the blocked user in the requested format when successful.
  819. *
  820. * @param mixed $user The ID or screen_name of the user to block
  821. * @param string $format Response format (JSON,XML); Defaults to JSON
  822. * @return Arc90_Service_Twitter_Response
  823. * @throws Arc90_Service_Twitter_Exception
  824. * @link http://help.twitter.com/index.php?pg=kb.page&id=69
  825. */
  826. public function block($user, $format ='json')
  827. {
  828. $requestedFormat = strtolower($format);
  829. $validFormats = array('json', 'xml');
  830. $this->_validateOption($requestedFormat, $validFormats);
  831. $url = self::PATH_BLOCK_CREATE . "/{$user}.{$requestedFormat}";
  832. return $this->_makeRequest($url, $requestedFormat, true);
  833. }
  834. /**
  835. * Un-blocks the user specified in the ID parameter as the authenticating user.
  836. * Returns the un-blocked user in the requested format when successful.
  837. *
  838. * @param mixed $user The ID or screen_name of the user to unblock
  839. * @param string $format Response format (JSON,XML); Defaults to JSON
  840. * @return Arc90_Service_Twitter_Response
  841. * @throws Arc90_Service_Twitter_Exception
  842. * @link http://help.twitter.com/index.php?pg=kb.page&id=69
  843. */
  844. public function unblock($user, $format ='json')
  845. {
  846. $requestedFormat = strtolower($format);
  847. $validFormats = array('json', 'xml');
  848. $this->_validateOption($requestedFormat, $validFormats);
  849. $url = self::PATH_BLOCK_DESTROY . "/{$user}.{$requestedFormat}";
  850. return $this->_makeRequest($url, $requestedFormat, true);
  851. }
  852. /**
  853. * Returns the string "ok" in the requested format with a 200 OK HTTP status code.
  854. *
  855. * @param string $format Response format (JSON,XML); Defaults to JSON
  856. * @return Arc90_Service_Twitter_Response
  857. * @throws Arc90_Service_Twitter_Exception
  858. */
  859. public function test($format ='json')
  860. {
  861. $requestedFormat = strtolower($format);
  862. $validFormats = array('json', 'xml');
  863. $this->_validateOption($requestedFormat, $validFormats);
  864. $url = self::PATH_HELP_TEST . ".{$requestedFormat}";
  865. return $this->_makeRequest($url, $requestedFormat, true);
  866. }
  867. /**
  868. * Returns the same text displayed on {@link http://twitter.com/home} when a maintenance window is scheduled.
  869. *
  870. * @param string $format Response format (JSON,XML); Defaults to JSON
  871. * @return Arc90_Service_Twitter_Response
  872. * @throws Arc90_Service_Twitter_Exception
  873. */
  874. public function downtimeSchedule($format ='json')
  875. {
  876. $requestedFormat = strtolower($format);
  877. $validFormats = array('json', 'xml');
  878. $this->_validateOption($requestedFormat, $validFormats);
  879. $url = self::PATH_HELP_DOWNTIME . ".{$requestedFormat}";
  880. return $this->_makeRequest($url, $requestedFormat, true);
  881. }
  882. /**
  883. * Returns the UNIX time of the most recent request made by this client.
  884. *
  885. * @return integer
  886. */
  887. public function getLastRequestTime()
  888. {
  889. return $this->_lastRequestTime;
  890. }
  891. /**
  892. * Returns the response to the most recent successful API call.
  893. *
  894. * @return Arc90_Service_Twitter_Response
  895. */
  896. public function getLastResponse()
  897. {
  898. return $this->_lastResponse;
  899. }
  900. /**
  901. * Validates that a parameter is a valid date string (recognized by strtotime()).
  902. *
  903. * @param string $name Name of the parameter to be validated (for use in error messages)
  904. * @param mixed $value Value of the parameter to be validated
  905. * @return boolean Validation of option
  906. * @throws Arc90_Service_Twitter_Exception
  907. */
  908. protected function _validateDateString($name, $value)
  909. {
  910. if(0 >= strtotime($value)) // PHP 5.1+ returns false on failure. Prior to PHP 5.1, -1 was returned.
  911. {
  912. throw new Arc90_Service_Twitter_Exception(
  913. "Invalid parameter ({$name}): '{$value}'; must be a valid date string."
  914. );
  915. }
  916. return true;
  917. }
  918. /**
  919. * Validates that a parameter is an integer greater than or equal to zero.
  920. *
  921. * @param string $name Name of the parameter to be validated (for use in error messages).
  922. * @param mixed $value Value of the parameter to be validated.
  923. * @return bool Validation of option
  924. * @throws Arc90_Service_Twitter_Exception
  925. */
  926. protected function _validateNonNegativeInteger($name, $value)
  927. {
  928. if(!is_numeric($value) || 0 > $value)
  929. {
  930. throw new Arc90_Service_Twitter_Exception(
  931. "Invalid parameter ({$name}): '{$value}'; must be a positive integer (or zero)."
  932. );
  933. }
  934. return true;
  935. }
  936. /**
  937. * Validates an option against a set of allowed options.
  938. *
  939. * @param mixed $option Option to validate
  940. * @param array $options Array of allowed option values
  941. * @return bool Validation of option
  942. * @throws Arc90_Service_Twitter_Exception
  943. */
  944. protected function _validateOption($option, array $options)
  945. {
  946. if(!in_array($option, $options))
  947. {
  948. throw new Arc90_Service_Twitter_Exception(
  949. "Invalid option: '{$option}'. Valid options include: " . implode(', ', $options)
  950. );
  951. }
  952. return true;
  953. }
  954. /**
  955. * Sends an HTTP GET or POST request to the Twitter API with optional Basic authentication.
  956. *
  957. * @param string $url Target URL for this request (relative to the API root URL)
  958. * @param string $format Response format (JSON,XML, RSS, ATOM, none); Defaults to JSON
  959. * @param bool $auth Specifies whether authentication is required
  960. * @param bool $post Specifies whether HTTP POST should be used (versus GET)
  961. * @param array $data x-www-form-urlencoded data to be sent in a POST request body
  962. * @return Arc90_Service_Twitter_Response
  963. * @throws Arc90_Service_Twitter_Exception
  964. */
  965. protected function _makeRequest($url, $format ='json', $auth =false, $post =false, $data ='')
  966. {
  967. $ch = curl_init();
  968. curl_setopt($ch, CURLOPT_URL, self::API_URL . $url);
  969. curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  970. if($auth)
  971. {
  972. curl_setopt($ch, CURLOPT_USERPWD, "{$this->_authUsername}:{$this->_authPassword}");
  973. }
  974. if($post)
  975. {
  976. curl_setopt($ch, CURLOPT_POST, true);
  977. curl_setopt($ch, CURLOPT_POSTFIELDS, $data.'&source=marktweet');
  978. }
  979. $this->_lastRequestTime = time();
  980. $data = curl_exec($ch);
  981. $metadata = curl_getinfo($ch);
  982. curl_close($ch);
  983. // Create, store and return a response object
  984. return $this->_lastResponse = new Arc90_Service_Twitter_Response($data, $metadata, $format);
  985. }
  986. }
  987. ?>