jsonsearchresultslist.php 7.9 KB

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