]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - actions/apitimelinefriends.php
Give NoticeListItem its own class
[quix0rs-gnu-social.git] / actions / apitimelinefriends.php
1 <?php
2 /**
3  * StatusNet, the distributed open-source microblogging tool
4  *
5  * Show the friends timeline
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    Craig Andrews <candrews@integralblue.com>
25  * @author    Evan Prodromou <evan@status.net>
26  * @author    Jeffery To <jeffery.to@gmail.com>
27  * @author    mac65 <mac65@mac65.com>
28  * @author    Mike Cochrane <mikec@mikenz.geek.nz>
29  * @author    Robin Millette <robin@millette.info>
30  * @author    Zach Copley <zach@status.net>
31  * @copyright 2009-2010 StatusNet, Inc.
32  * @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
33  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
34  * @link      http://status.net/
35  */
36
37 /* External API usage documentation. Please update when you change how this method works. */
38
39 /*! @page friendstimeline statuses/friends_timeline
40
41     @section Description
42     Returns the 20 most recent statuses posted by the authenticating
43     user and that user's friends. This is the equivalent of "You and
44     friends" page in the web interface.
45
46     @par URL patterns
47     @li /api/statuses/friends_timeline.:format
48     @li /api/statuses/friends_timeline/:id.:format
49
50     @par Formats (:format)
51     xml, json, rss, atom
52
53     @par ID (:id)
54     username, user id
55
56     @par HTTP Method(s)
57     GET
58
59     @par Requires Authentication
60     Sometimes (see: @ref authentication)
61
62     @param user_id (Optional) Specifies a user by ID
63     @param screen_name (Optional) Specifies a user by screename (nickname)
64     @param since_id (Optional) Returns only statuses with an ID greater
65     than (that is, more recent than) the specified ID.
66     @param max_id (Optional) Returns only statuses with an ID less than
67     (that is, older than) or equal to the specified ID.
68     @param count (Optional) Specifies the number of statuses to retrieve.
69     @param page (Optional) Specifies the page of results to retrieve.
70
71     @sa @ref authentication
72     @sa @ref apiroot
73
74     @subsection usagenotes Usage notes
75     @li The URL pattern is relative to the @ref apiroot.
76     @li The XML response uses <a href="http://georss.org/Main_Page">GeoRSS</a>
77     to encode the latitude and longitude (see example response below <georss:point>).
78
79     @subsection exampleusage Example usage
80
81     @verbatim
82     curl http://identi.ca/api/statuses/friends_timeline/evan.xml?count=1&page=2
83     @endverbatim
84
85     @subsection exampleresponse Example response
86
87     @verbatim
88     <?xml version="1.0"?>
89     <statuses type="array">
90       <status>
91         <text>back from the !yul !drupal meet with Evolving Web folk, @anarcat, @webchick and others, and an interesting refresher on SQL indexing</text>
92         <truncated>false</truncated>
93         <created_at>Wed Mar 31 01:33:02 +0000 2010</created_at>
94         <in_reply_to_status_id/>
95         <source>&lt;a href="http://code.google.com/p/microblog-purple/"&gt;mbpidgin&lt;/a&gt;</source>
96         <id>26674201</id>
97         <in_reply_to_user_id/>
98         <in_reply_to_screen_name/>
99         <geo/>
100         <favorited>false</favorited>
101         <user>
102           <id>246</id>
103           <name>Mark</name>
104           <screen_name>lambic</screen_name>
105           <location>Montreal, Canada</location>
106           <description>Geek</description>
107           <profile_image_url>http://avatar.identi.ca/246-48-20080702141545.png</profile_image_url>
108           <url>http://lambic.co.uk</url>
109           <protected>false</protected>
110           <followers_count>73</followers_count>
111           <profile_background_color>#F0F2F5</profile_background_color>
112           <profile_text_color/>
113           <profile_link_color>#002E6E</profile_link_color>
114           <profile_sidebar_fill_color>#CEE1E9</profile_sidebar_fill_color>
115           <profile_sidebar_border_color/>
116           <friends_count>58</friends_count>
117           <created_at>Wed Jul 02 14:12:15 +0000 2008</created_at>
118           <favourites_count>2</favourites_count>
119           <utc_offset>-14400</utc_offset>
120           <time_zone>US/Eastern</time_zone>
121           <profile_background_image_url/>
122           <profile_background_tile>false</profile_background_tile>
123           <statuses_count>933</statuses_count>
124           <following>false</following>
125           <notifications>false</notifications>
126         </user>
127       </status>
128     </statuses>
129     @endverbatim
130 */
131
132 if (!defined('STATUSNET')) {
133     exit(1);
134 }
135
136 require_once INSTALLDIR . '/lib/apibareauth.php';
137
138 /**
139  * Returns the most recent notices (default 20) posted by the target user.
140  * This is the equivalent of 'You and friends' page accessed via Web.
141  *
142  * @category API
143  * @package  StatusNet
144  * @author   Craig Andrews <candrews@integralblue.com>
145  * @author   Evan Prodromou <evan@status.net>
146  * @author   Jeffery To <jeffery.to@gmail.com>
147  * @author   mac65 <mac65@mac65.com>
148  * @author   Mike Cochrane <mikec@mikenz.geek.nz>
149  * @author   Robin Millette <robin@millette.info>
150  * @author   Zach Copley <zach@status.net>
151  * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
152  * @link     http://status.net/
153  */
154 class ApiTimelineFriendsAction extends ApiBareAuthAction
155 {
156     var $notices  = null;
157
158     /**
159      * Take arguments for running
160      *
161      * @param array $args $_REQUEST args
162      *
163      * @return boolean success flag
164      *
165      */
166     function prepare($args)
167     {
168         parent::prepare($args);
169         $this->user = $this->getTargetUser($this->arg('id'));
170
171         if (empty($this->user)) {
172             // TRANS: Client error displayed when requesting dents of a user and friends for a user that does not exist.
173             $this->clientError(_('No such user.'), 404, $this->format);
174             return;
175         }
176
177         $this->notices = $this->getNotices();
178
179         return true;
180     }
181
182     /**
183      * Handle the request
184      *
185      * Just show the notices
186      *
187      * @param array $args $_REQUEST data (unused)
188      *
189      * @return void
190      */
191     function handle($args)
192     {
193         parent::handle($args);
194         $this->showTimeline();
195     }
196
197     /**
198      * Show the timeline of notices
199      *
200      * @return void
201      */
202     function showTimeline()
203     {
204         $profile    = $this->user->getProfile();
205         $avatar     = $profile->getAvatar(AVATAR_PROFILE_SIZE);
206         $sitename   = common_config('site', 'name');
207         $title      = sprintf(_("%s and friends"), $this->user->nickname);
208         $taguribase = TagURI::base();
209         $id         = "tag:$taguribase:FriendsTimeline:" . $this->user->id;
210
211         $subtitle = sprintf(
212             // TRANS: Message is used as a subtitle. %1$s is a user nickname, %2$s is a site name.
213             _('Updates from %1$s and friends on %2$s!'),
214             $this->user->nickname,
215             $sitename
216         );
217
218         $link = common_local_url(
219             'all',
220              array('nickname' => $this->user->nickname)
221         );
222
223         $self = $this->getSelfUri();
224
225         $logo = (!empty($avatar))
226             ? $avatar->displayUrl()
227             : Avatar::defaultImage(AVATAR_PROFILE_SIZE);
228
229         switch($this->format) {
230         case 'xml':
231             $this->showXmlTimeline($this->notices);
232             break;
233         case 'rss':
234
235             $this->showRssTimeline(
236                 $this->notices,
237                 $title,
238                 $link,
239                 $subtitle,
240                 null,
241                 $logo,
242                 $self
243             );
244             break;
245         case 'atom':
246             header('Content-Type: application/atom+xml; charset=utf-8');
247
248             $atom = new AtomNoticeFeed($this->auth_user);
249
250             $atom->setId($id);
251             $atom->setTitle($title);
252             $atom->setSubtitle($subtitle);
253             $atom->setLogo($logo);
254             $atom->setUpdated('now');
255             $atom->addLink($link);
256             $atom->setSelfLink($self);
257
258             $atom->addEntryFromNotices($this->notices);
259
260             $this->raw($atom->getString());
261
262             break;
263         case 'json':
264             $this->showJsonTimeline($this->notices);
265             break;
266         case 'as':
267             header('Content-Type: application/json; charset=utf-8');
268             $doc = new ActivityStreamJSONDocument($this->auth_user);
269             $doc->setTitle($title);
270             $doc->addLink($link,'alternate', 'text/html');
271             $doc->addItemsFromNotices($this->notices);
272             $this->raw($doc->asString());
273             break;
274         default:
275             // TRANS: Client error displayed when trying to handle an unknown API method.
276             $this->clientError(_('API method not found.'), $code = 404);
277             break;
278         }
279     }
280
281     /**
282      * Get notices
283      *
284      * @return array notices
285      */
286     function getNotices()
287     {
288         $notices = array();
289
290         if (!empty($this->auth_user) && $this->auth_user->id == $this->user->id) {
291             $notice = $this->user->ownFriendsTimeline(($this->page-1) * $this->count,
292                                                       $this->count, $this->since_id,
293                                                       $this->max_id);
294         } else {
295             $notice = $this->user->friendsTimeline(($this->page-1) * $this->count,
296                                                    $this->count, $this->since_id,
297                                                    $this->max_id);
298         }
299
300         while ($notice->fetch()) {
301             $notices[] = clone($notice);
302         }
303
304         return $notices;
305     }
306
307     /**
308      * Is this action read only?
309      *
310      * @param array $args other arguments
311      *
312      * @return boolean true
313      */
314     function isReadOnly($args)
315     {
316         return true;
317     }
318
319     /**
320      * When was this feed last modified?
321      *
322      * @return string datestamp of the latest notice in the stream
323      */
324     function lastModified()
325     {
326         if (!empty($this->notices) && (count($this->notices) > 0)) {
327             return strtotime($this->notices[0]->created);
328         }
329
330         return null;
331     }
332
333     /**
334      * An entity tag for this stream
335      *
336      * Returns an Etag based on the action name, language, user ID, and
337      * timestamps of the first and last notice in the timeline
338      *
339      * @return string etag
340      */
341     function etag()
342     {
343         if (!empty($this->notices) && (count($this->notices) > 0)) {
344             $last = count($this->notices) - 1;
345
346             return '"' . implode(
347                                  ':',
348                                  array($this->arg('action'),
349                                        common_user_cache_hash($this->auth_user),
350                                        common_language(),
351                                        $this->user->id,
352                                        strtotime($this->notices[0]->created),
353                                        strtotime($this->notices[$last]->created))
354                                  )
355               . '"';
356         }
357
358         return null;
359     }
360 }