apilists.php 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. <?php
  2. /**
  3. * StatusNet, the distributed open-source microblogging tool
  4. *
  5. * List existing lists or create a new list.
  6. *
  7. * PHP version 5
  8. *
  9. * LICENCE: This program is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU Affero General Public License as published by
  11. * the Free Software Foundation, either version 3 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU Affero General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Affero General Public License
  20. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. *
  22. * @category API
  23. * @package StatusNet
  24. * @author Shashi Gowda <connect2shashi@gmail.com>
  25. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
  26. * @link http://status.net/
  27. */
  28. if (!defined('STATUSNET')) {
  29. exit(1);
  30. }
  31. /**
  32. * Action handler for Twitter list_memeber methods
  33. *
  34. * @category API
  35. * @package StatusNet
  36. * @author Shashi Gowda <connect2shashi@gmail.com>
  37. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
  38. * @link http://status.net/
  39. * @see ApiBareAuthAction
  40. */
  41. class ApiListsAction extends ApiBareAuthAction
  42. {
  43. var $lists = null;
  44. var $cursor = 0;
  45. var $next_cursor = 0;
  46. var $prev_cursor = 0;
  47. var $create = false;
  48. /**
  49. * Set the flags for handling the request. List lists created by user if this
  50. * is a GET request, create a new list if it is a POST request.
  51. *
  52. * Takes parameters:
  53. * - user: the user id or nickname
  54. * Parameters for POST request
  55. * - name: name of the new list (the people tag itself)
  56. * - mode: (optional) mode for the new list private/public
  57. * - description: (optional) description for the list
  58. *
  59. * @return boolean success flag
  60. */
  61. protected function prepare(array $args=array())
  62. {
  63. parent::prepare($args);
  64. $this->create = ($_SERVER['REQUEST_METHOD'] == 'POST');
  65. if (!$this->create) {
  66. $this->user = $this->getTargetUser($this->arg('user'));
  67. if (!($user instanceof User)) {
  68. // TRANS: Client error displayed trying to perform an action related to a non-existing user.
  69. $this->clientError(_('No such user.'), 404);
  70. }
  71. $this->target = $user->getProfile();
  72. $this->getLists();
  73. }
  74. return true;
  75. }
  76. /**
  77. * require authentication if it is a write action or user is ambiguous
  78. *
  79. */
  80. function requiresAuth()
  81. {
  82. return parent::requiresAuth() ||
  83. $this->create || $this->delete;
  84. }
  85. /**
  86. * Handle request:
  87. * Show the lists the user has created if the request method is GET
  88. * Create a new list by diferring to handlePost() if it is POST.
  89. */
  90. protected function handle()
  91. {
  92. parent::handle();
  93. if($this->create) {
  94. return $this->handlePost();
  95. }
  96. switch($this->format) {
  97. case 'xml':
  98. $this->showXmlLists($this->lists, $this->next_cursor, $this->prev_cursor);
  99. break;
  100. case 'json':
  101. $this->showJsonLists($this->lists, $this->next_cursor, $this->prev_cursor);
  102. break;
  103. default:
  104. $this->clientError(
  105. // TRANS: Client error displayed when coming across a non-supported API method.
  106. _('API method not found.'),
  107. 404,
  108. $this->format
  109. );
  110. break;
  111. }
  112. }
  113. /**
  114. * Create a new list
  115. *
  116. * @return boolean success
  117. */
  118. function handlePost()
  119. {
  120. $name=$this->arg('name');
  121. if(empty($name)) {
  122. // mimick twitter
  123. // TRANS: Client error displayed when trying to create a list without a name.
  124. print _("A list must have a name.");
  125. exit(1);
  126. }
  127. // twitter creates a new list by appending a number to the end
  128. // if the list by the given name already exists
  129. // it makes more sense to return the existing list instead
  130. $private = null;
  131. if ($this->arg('mode') === 'public') {
  132. $private = false;
  133. } else if ($this->arg('mode') === 'private') {
  134. $private = true;
  135. }
  136. $list = Profile_list::ensureTag($this->auth_user->id,
  137. $this->arg('name'),
  138. $this->arg('description'),
  139. $private);
  140. if (empty($list)) {
  141. return false;
  142. }
  143. switch($this->format) {
  144. case 'xml':
  145. $this->showSingleXmlList($list);
  146. break;
  147. case 'json':
  148. $this->showSingleJsonList($list);
  149. break;
  150. default:
  151. // TRANS: Client error displayed when coming across a non-supported API method.
  152. $this->clientError(_('API method not found.'), 404);
  153. }
  154. return true;
  155. }
  156. /**
  157. * Get lists
  158. */
  159. function getLists()
  160. {
  161. $cursor = (int) $this->arg('cursor', -1);
  162. // twitter fixes count at 20
  163. // there is no argument named count
  164. $count = 20;
  165. $fn = array($this->target, 'getLists');
  166. list($this->lists,
  167. $this->next_cursor,
  168. $this->prev_cursor) = Profile_list::getAtCursor($fn, array($this->auth_user), $cursor, $count);
  169. }
  170. function isReadOnly($args)
  171. {
  172. return false;
  173. }
  174. function lastModified()
  175. {
  176. if (!$this->create && !empty($this->lists) && (count($this->lists) > 0)) {
  177. return strtotime($this->lists[0]->created);
  178. }
  179. return null;
  180. }
  181. /**
  182. * An entity tag for this list of lists
  183. *
  184. * Returns an Etag based on the action name, language, user ID and
  185. * timestamps of the first and last list the user has joined
  186. *
  187. * @return string etag
  188. */
  189. function etag()
  190. {
  191. if (!$this->create && !empty($this->lists) && (count($this->lists) > 0)) {
  192. $last = count($this->lists) - 1;
  193. return '"' . implode(
  194. ':',
  195. array($this->arg('action'),
  196. common_language(),
  197. $this->target->id,
  198. strtotime($this->lists[0]->created),
  199. strtotime($this->lists[$last]->created))
  200. )
  201. . '"';
  202. }
  203. return null;
  204. }
  205. }