]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - actions/conversation.php
Merge branch 'candrews-review' 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 // XXX: not sure how to do paging yet,
35 // so set a 60-notice limit
36
37 require_once INSTALLDIR.'/lib/noticelist.php';
38
39 /**
40  * Conversation tree in the browser
41  *
42  * @category Action
43  * @package  Laconica
44  * @author   Evan Prodromou <evan@controlyourself.ca>
45  * @license  http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
46  * @link     http://laconi.ca/
47  */
48
49 class ConversationAction extends Action
50 {
51     var $id   = null;
52     var $page = null;
53
54     /**
55      * Initialization.
56      *
57      * @param array $args Web and URL arguments
58      *
59      * @return boolean false if id not passed in
60      */
61
62     function prepare($args)
63     {
64         parent::prepare($args);
65         $this->id = $this->trimmed('id');
66         if (empty($this->id)) {
67             return false;
68         }
69         $this->id = $this->id+0;
70         $this->page = $this->trimmed('page');
71         if (empty($this->page)) {
72             $this->page = 1;
73         }
74         return true;
75     }
76
77     /**
78      * Handle the action
79      *
80      * @param array $args Web and URL arguments
81      *
82      * @return void
83      */
84
85     function handle($args)
86     {
87         parent::handle($args);
88         $this->showPage();
89     }
90
91     /**
92      * Returns the page title
93      *
94      * @return string page title
95      */
96
97     function title()
98     {
99         return _("Conversation");
100     }
101
102     /**
103      * Show content.
104      *
105      * Display a hierarchical unordered list in the content area.
106      * Uses ConversationTree to do most of the heavy lifting.
107      *
108      * @return void
109      */
110
111     function showContent()
112     {
113         $notices = Notice::conversationStream($this->id, null, null);
114
115         $ct = new ConversationTree($notices, $this);
116
117         $cnt = $ct->show();
118     }
119 }
120
121 /**
122  * Conversation tree
123  *
124  * The widget class for displaying a hierarchical list of notices.
125  *
126  * @category Widget
127  * @package  Laconica
128  * @author   Evan Prodromou <evan@controlyourself.ca>
129  * @license  http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
130  * @link     http://laconi.ca/
131  */
132
133 class ConversationTree extends NoticeList
134 {
135     var $tree  = null;
136     var $table = null;
137
138     /**
139      * Show the tree of notices
140      *
141      * @return void
142      */
143
144     function show()
145     {
146         $cnt = $this->_buildTree();
147
148         $this->out->elementStart('div', array('id' =>'notices_primary'));
149         $this->out->element('h2', null, _('Notices'));
150         $this->out->elementStart('ol', array('class' => 'notices xoxo'));
151
152         if (array_key_exists('root', $this->tree)) {
153             $rootid = $this->tree['root'][0];
154             $this->showNoticePlus($rootid);
155         }
156
157         $this->out->elementEnd('ol');
158         $this->out->elementEnd('div');
159
160         return $cnt;
161     }
162
163     function _buildTree()
164     {
165         $this->tree  = array();
166         $this->table = array();
167
168         while ($this->notice->fetch()) {
169
170             $cnt++;
171
172             $id     = $this->notice->id;
173             $notice = clone($this->notice);
174
175             $this->table[$id] = $notice;
176
177             if (is_null($notice->reply_to)) {
178                 $this->tree['root'] = array($notice->id);
179             } else if (array_key_exists($notice->reply_to, $this->tree)) {
180                 $this->tree[$notice->reply_to][] = $notice->id;
181             } else {
182                 $this->tree[$notice->reply_to] = array($notice->id);
183             }
184         }
185
186         return $cnt;
187     }
188
189     /**
190      * Shows a notice plus its list of children.
191      *
192      * @param integer $id ID of the notice to show
193      *
194      * @return void
195      */
196
197     function showNoticePlus($id)
198     {
199         $notice = $this->table[$id];
200
201         // We take responsibility for doing the li
202
203         $this->out->elementStart('li', array('class' => 'hentry notice',
204                                              'id' => 'notice-' . $id));
205
206         $item = $this->newListItem($notice);
207         $item->show();
208
209         if (array_key_exists($id, $this->tree)) {
210             $children = $this->tree[$id];
211
212             $this->out->elementStart('ol', array('class' => 'notices'));
213
214             sort($children);
215
216             foreach ($children as $child) {
217                 $this->showNoticePlus($child);
218             }
219
220             $this->out->elementEnd('ol');
221         }
222
223         $this->out->elementEnd('li');
224     }
225
226     /**
227      * Override parent class to return our preferred item.
228      *
229      * @param Notice $notice Notice to display
230      *
231      * @return NoticeListItem a list item to show
232      */
233
234     function newListItem($notice)
235     {
236         return new ConversationTreeItem($notice, $this->out);
237     }
238 }
239
240 /**
241  * Conversation tree list item
242  *
243  * Special class of NoticeListItem for use inside conversation trees.
244  *
245  * @category Widget
246  * @package  Laconica
247  * @author   Evan Prodromou <evan@controlyourself.ca>
248  * @license  http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
249  * @link     http://laconi.ca/
250  */
251
252 class ConversationTreeItem extends NoticeListItem
253 {
254     /**
255      * start a single notice.
256      *
257      * The default creates the <li>; we skip, since the ConversationTree
258      * takes care of that.
259      *
260      * @return void
261      */
262
263     function showStart()
264     {
265         return;
266     }
267
268     /**
269      * finish the notice
270      *
271      * The default closes the <li>; we skip, since the ConversationTree
272      * takes care of that.
273      *
274      * @return void
275      */
276
277     function showEnd()
278     {
279         return;
280     }
281
282     /**
283      * show link to notice conversation page
284      *
285      * Since we're only used on the conversation page, we skip this
286      *
287      * @return void
288      */
289
290     function showContext()
291     {
292         return;
293     }
294 }