]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - lib/jsonsearchresultslist.php
Opps, PEAR sucks. Need to call find() before fetch() ... :-(
[quix0rs-gnu-social.git] / lib / jsonsearchresultslist.php
1 <?php
2 /**
3  * StatusNet, the distributed open-source microblogging tool
4  *
5  * widget for displaying a list of notices
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  Search
23  * @package   StatusNet
24  * @author    Zach Copley <zach@status.net>
25  * @copyright 2009 StatusNet, Inc.
26  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
27  * @link      http://status.net/
28  */
29
30 if (!defined('STATUSNET') && !defined('LACONICA')) {
31     exit(1);
32 }
33
34 /**
35  * widget-like class for showing JSON search results
36  *
37  * @category Search
38  * @package  StatusNet
39  * @author   Zach Copley <zach@status.net>
40  * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
41  * @link     http://status.net/
42  *
43  */
44
45 class JSONSearchResultsList
46 {
47     protected $notice;  // protected attrs invisible to json_encode()
48     protected $rpp;
49
50     // The below attributes are carefully named so the JSON output from
51     // this obj matches the output from search.twitter.com
52
53     var $results;
54     var $since_id;
55     var $max_id;
56     var $refresh_url;
57     var $results_per_page;
58     var $completed_in;
59     var $page;
60     var $query;
61
62     /**
63      * constructor
64      *
65      * @param Notice $notice   stream of notices from DB_DataObject
66      * @param string $query    the original search query
67      * @param int    $rpp      the number of results to display per page
68      * @param int    $page     a page offset
69      * @param int    $since_id only display notices newer than this
70      */
71
72     function __construct($notice, $query, $rpp, $page, $since_id = 0)
73     {
74         $this->notice           = $notice;
75         $this->query            = urlencode($query);
76         $this->results_per_page = $rpp;
77         $this->rpp              = $rpp;
78         $this->page             = $page;
79         $this->since_id         = $since_id;
80         $this->results          = array();
81     }
82
83     /**
84      * show the list of search results
85      *
86      * @return int $count of the search results listed.
87      */
88
89     function show()
90     {
91         $cnt = 0;
92         $this->max_id = 0;
93
94         $time_start = microtime(true);
95
96         while ($this->notice->fetch() && $cnt <= $this->rpp) {
97             $cnt++;
98
99             // XXX: Hmmm. this depends on desc sort order
100             if (!$this->max_id) {
101                 $this->max_id = (int)$this->notice->id;
102             }
103
104             if ($this->since_id && $this->notice->id <= $this->since_id) {
105                 break;
106             }
107
108             if ($cnt > $this->rpp) {
109                 break;
110             }
111
112             $profile = $this->notice->getProfile();
113
114             // Don't show notices from deleted users
115
116             if (!empty($profile)) {
117                 $item = new ResultItem($this->notice);
118                 array_push($this->results, $item);
119             }
120         }
121
122         $time_end           = microtime(true);
123         $this->completed_in = $time_end - $time_start;
124
125         // Set other attrs
126
127         $this->refresh_url = '?since_id=' . $this->max_id .
128             '&q=' . $this->query;
129
130         // pagination stuff
131
132         if ($cnt > $this->rpp) {
133             $this->next_page = '?page=' . ($this->page + 1) .
134                 '&max_id=' . $this->max_id;
135             if ($this->rpp != 15) {
136                 $this->next_page .= '&rpp=' . $this->rpp;
137             }
138             $this->next_page .= '&q=' . $this->query;
139         }
140
141         if ($this->page > 1) {
142             $this->previous_page = '?page=' . ($this->page - 1) .
143                 '&max_id=' . $this->max_id;
144             if ($this->rpp != 15) {
145                 $this->previous_page .= '&rpp=' . $this->rpp;
146             }
147             $this->previous_page .= '&q=' . $this->query;
148         }
149
150         print json_encode($this);
151
152         return $cnt;
153     }
154 }
155
156 /**
157  * widget for displaying a single JSON search result
158  *
159  * @category UI
160  * @package  StatusNet
161  * @author   Zach Copley <zach@status.net>
162  * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
163  * @link     http://status.net/
164  * @see      JSONSearchResultsList
165  */
166
167 class ResultItem
168 {
169     /** The notice this item is based on. */
170
171     protected $notice;  // protected attrs invisible to json_encode()
172
173     /** The profile associated with the notice. */
174
175     protected $profile;
176
177     // The below attributes are carefully named so the JSON output from
178     // this obj matches the output from search.twitter.com
179
180     var $text;
181     var $to_user_id;
182     var $to_user;
183     var $from_user;
184     var $id;
185     var $from_user_id;
186     var $iso_language_code;
187     var $source;
188     var $profile_image_url;
189     var $created_at;
190
191     /**
192      * constructor
193      *
194      * Also initializes the profile attribute.
195      *
196      * @param Notice $notice The notice we'll display
197      */
198
199     function __construct($notice)
200     {
201         $this->notice  = $notice;
202         $this->profile = $notice->getProfile();
203         $this->buildResult();
204     }
205
206     /**
207      * Build a search result object
208      *
209      * This populates the the result in preparation for JSON encoding.
210      *
211      * @return void
212      */
213
214     function buildResult()
215     {
216         $this->text      = $this->notice->content;
217         $replier_profile = null;
218
219         if ($this->notice->reply_to) {
220             $reply = Notice::getKV(intval($this->notice->reply_to));
221             if ($reply) {
222                 $replier_profile = $reply->getProfile();
223             }
224         }
225
226         $this->to_user_id = ($replier_profile) ?
227             intval($replier_profile->id) : null;
228         $this->to_user    = ($replier_profile) ?
229             $replier_profile->nickname : null;
230
231         $this->from_user    = $this->profile->nickname;
232         $this->id           = $this->notice->id;
233         $this->from_user_id = $this->profile->id;
234
235         $this->iso_language_code = Profile_prefs::getConfigData($this->profile, 'site', 'language');
236         
237         $this->source = $this->getSourceLink($this->notice->source);
238
239         $this->profile_image_url = $this->profile->avatarUrl(AVATAR_STREAM_SIZE);
240
241         $this->created_at = common_date_rfc2822($this->notice->created);
242     }
243
244     /**
245      * Show the source of the notice
246      *
247      * Either the name (and link) of the API client that posted the notice,
248      * or one of other other channels.
249      *
250      * @param string $source the source of the Notice
251      *
252      * @return string a fully rendered source of the Notice
253      */
254     function getSourceLink($source)
255     {
256         // Gettext translations for the below source types are available.
257         $source_name = _($source);
258         switch ($source) {
259         case 'web':
260         case 'xmpp':
261         case 'mail':
262         case 'omb':
263         case 'api':
264             break;
265         default:
266             $ns = Notice_source::getKV($source);
267             if ($ns instanceof Notice_source) {
268                 $source_name = '<a href="' . $ns->url . '">' . $ns->name . '</a>';
269             }
270             break;
271         }
272
273         return $source_name;
274     }
275 }