]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - actions/conversation.php
Merge commit 'jeff-themovie/notice-search-no-results' into 0.8.x
[quix0rs-gnu-social.git] / actions / conversation.php
1 <?php
2 /**
3  * Display a conversation in the browser
4  *
5  * PHP version 5
6  *
7  * @category Action
8  * @package  Laconica
9  * @author   Evan Prodromou <evan@controlyourself.ca>
10  * @license  http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
11  * @link     http://laconi.ca/
12  *
13  * Laconica - a distributed open-source microblogging tool
14  * Copyright (C) 2009, Control Yourself, Inc.
15  *
16  * This program is free software: you can redistribute it and/or modify
17  * it under the terms of the GNU Affero General Public License as published by
18  * the Free Software Foundation, either version 3 of the License, or
19  * (at your option) any later version.
20  *
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  * GNU Affero General Public License for more details.
25  *
26  * You should have received a copy of the GNU Affero General Public License
27  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
28  */
29
30 if (!defined('LACONICA')) {
31     exit(1);
32 }
33
34 require_once INSTALLDIR.'/lib/noticelist.php';
35
36 /**
37  * Conversation tree in the browser
38  *
39  * @category Action
40  * @package  Laconica
41  * @author   Evan Prodromou <evan@controlyourself.ca>
42  * @license  http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
43  * @link     http://laconi.ca/
44  */
45
46 class ConversationAction extends Action
47 {
48     var $id   = null;
49     var $page = null;
50
51     /**
52      * Initialization.
53      *
54      * @param array $args Web and URL arguments
55      *
56      * @return boolean false if id not passed in
57      */
58
59     function prepare($args)
60     {
61         parent::prepare($args);
62         $this->id = $this->trimmed('id');
63         if (empty($this->id)) {
64             return false;
65         }
66         $this->id = $this->id+0;
67         $this->page = $this->trimmed('page');
68         if (empty($this->page)) {
69             $this->page = 1;
70         }
71         return true;
72     }
73
74     /**
75      * Handle the action
76      *
77      * @param array $args Web and URL arguments
78      *
79      * @return void
80      */
81
82     function handle($args)
83     {
84         parent::handle($args);
85         $this->showPage();
86     }
87
88     /**
89      * Returns the page title
90      *
91      * @return string page title
92      */
93
94     function title()
95     {
96         return _("Conversation");
97     }
98
99     /**
100      * Show content.
101      *
102      * Display a hierarchical unordered list in the content area.
103      * Uses ConversationTree to do most of the heavy lifting.
104      *
105      * @return void
106      */
107
108     function showContent()
109     {
110         $notices = Notice::conversationStream($this->id);
111
112         $ct = new ConversationTree($notices, $this);
113
114         $cnt = $ct->show();
115     }
116 }
117
118 /**
119  * Conversation tree
120  *
121  * The widget class for displaying a hierarchical list of notices.
122  *
123  * @category Widget
124  * @package  Laconica
125  * @author   Evan Prodromou <evan@controlyourself.ca>
126  * @license  http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
127  * @link     http://laconi.ca/
128  */
129
130 class ConversationTree extends NoticeList
131 {
132     var $tree  = null;
133     var $table = null;
134
135     /**
136      * Show the tree of notices
137      *
138      * @return void
139      */
140
141     function show()
142     {
143         $cnt = 0;
144
145         $this->_buildTree();
146
147         $this->out->elementStart('div', array('id' =>'notices_primary'));
148         $this->out->element('h2', null, _('Notices'));
149         $this->out->elementStart('ol', array('class' => 'notices xoxo'));
150
151         if (array_key_exists('root', $this->tree)) {
152             $rootid = $this->tree['root'][0];
153             $this->showNoticePlus($rootid);
154         }
155
156         $this->out->elementEnd('ol');
157         $this->out->elementEnd('div');
158
159         return $cnt;
160     }
161
162     function _buildTree()
163     {
164         $this->tree  = array();
165         $this->table = array();
166
167         while ($this->notice->fetch()) {
168
169             $cnt++;
170
171             $id     = $this->notice->id;
172             $notice = clone($this->notice);
173
174             $this->table[$id] = $notice;
175
176             if (is_null($notice->reply_to)) {
177                 $this->tree['root'] = array($notice->id);
178             } else if (array_key_exists($notice->reply_to, $this->tree)) {
179                 $this->tree[$notice->reply_to][] = $notice->id;
180             } else {
181                 $this->tree[$notice->reply_to] = array($notice->id);
182             }
183         }
184     }
185
186     /**
187      * Shows a notice plus its list of children.
188      *
189      * @param integer $id ID of the notice to show
190      *
191      * @return void
192      */
193
194     function showNoticePlus($id)
195     {
196         $notice = $this->table[$id];
197
198         // We take responsibility for doing the li
199
200         $this->out->elementStart('li', array('class' => 'hentry notice',
201                                              'id' => 'notice-' . $id));
202
203         $item = $this->newListItem($notice);
204         $item->show();
205
206         if (array_key_exists($id, $this->tree)) {
207             $children = $this->tree[$id];
208
209             $this->out->elementStart('ol', array('class' => 'notices'));
210
211             sort($children);
212
213             foreach ($children as $child) {
214                 $this->showNoticePlus($child);
215             }
216
217             $this->out->elementEnd('ol');
218         }
219
220         $this->out->elementEnd('li');
221     }
222
223     /**
224      * Override parent class to return our preferred item.
225      *
226      * @param Notice $notice Notice to display
227      *
228      * @return NoticeListItem a list item to show
229      */
230
231     function newListItem($notice)
232     {
233         return new ConversationTreeItem($notice, $this->out);
234     }
235 }
236
237 /**
238  * Conversation tree list item
239  *
240  * Special class of NoticeListItem for use inside conversation trees.
241  *
242  * @category Widget
243  * @package  Laconica
244  * @author   Evan Prodromou <evan@controlyourself.ca>
245  * @license  http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
246  * @link     http://laconi.ca/
247  */
248
249 class ConversationTreeItem extends NoticeListItem
250 {
251     /**
252      * start a single notice.
253      *
254      * The default creates the <li>; we skip, since the ConversationTree
255      * takes care of that.
256      *
257      * @return void
258      */
259
260     function showStart()
261     {
262         return;
263     }
264
265     /**
266      * finish the notice
267      *
268      * The default closes the <li>; we skip, since the ConversationTree
269      * takes care of that.
270      *
271      * @return void
272      */
273
274     function showEnd()
275     {
276         return;
277     }
278
279     /**
280      * show link to notice conversation page
281      *
282      * Since we're only used on the conversation page, we skip this
283      *
284      * @return void
285      */
286
287     function showContext()
288     {
289         return;
290     }
291 }