]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - actions/conversation.php
Merge branch '0.8.x' into small-fixes
[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         $offset = ($this->page-1) * NOTICES_PER_PAGE;
111         $limit  = NOTICES_PER_PAGE + 1;
112
113         $notices = Notice::conversationStream($this->id, $offset, $limit);
114
115         $ct = new ConversationTree($notices, $this);
116
117         $cnt = $ct->show();
118
119         $this->pagination($this->page > 1, $cnt > NOTICES_PER_PAGE,
120                           $this->page, 'conversation', array('id' => $this->id));
121     }
122 }
123
124 /**
125  * Conversation tree
126  *
127  * The widget class for displaying a hierarchical list of notices.
128  *
129  * @category Widget
130  * @package  Laconica
131  * @author   Evan Prodromou <evan@controlyourself.ca>
132  * @license  http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
133  * @link     http://laconi.ca/
134  */
135
136 class ConversationTree extends NoticeList
137 {
138     var $tree  = null;
139     var $table = null;
140
141     /**
142      * Show the tree of notices
143      *
144      * @return void
145      */
146
147     function show()
148     {
149         $cnt = 0;
150
151         $this->tree  = array();
152         $this->table = array();
153
154         while ($this->notice->fetch()) {
155
156             $cnt++;
157
158             $id     = $this->notice->id;
159             $notice = clone($this->notice);
160
161             $this->table[$id] = $notice;
162
163             if (is_null($notice->reply_to)) {
164                 $this->tree['root'] = array($notice->id);
165             } else if (array_key_exists($notice->reply_to, $this->tree)) {
166                 $this->tree[$notice->reply_to][] = $notice->id;
167             } else {
168                 $this->tree[$notice->reply_to] = array($notice->id);
169             }
170         }
171
172         $this->out->elementStart('div', array('id' =>'notices_primary'));
173         $this->out->element('h2', null, _('Notices'));
174         $this->out->elementStart('ol', array('class' => 'notices xoxo'));
175
176         if (array_key_exists('root', $this->tree)) {
177             $rootid = $this->tree['root'][0];
178             $this->showNoticePlus($rootid);
179         }
180
181         $this->out->elementEnd('ol');
182         $this->out->elementEnd('div');
183
184         return $cnt;
185     }
186
187     /**
188      * Shows a notice plus its list of children.
189      *
190      * @param integer $id ID of the notice to show
191      *
192      * @return void
193      */
194
195     function showNoticePlus($id)
196     {
197         $notice = $this->table[$id];
198
199         // We take responsibility for doing the li
200
201         $this->out->elementStart('li', array('class' => 'hentry notice',
202                                              'id' => 'notice-' . $id));
203
204         $item = $this->newListItem($notice);
205         $item->show();
206
207         if (array_key_exists($id, $this->tree)) {
208             $children = $this->tree[$id];
209
210             $this->out->elementStart('ol', array('class' => 'notices'));
211
212             sort($children);
213
214             foreach ($children as $child) {
215                 $this->showNoticePlus($child);
216             }
217
218             $this->out->elementEnd('ol');
219         }
220
221         $this->out->elementEnd('li');
222     }
223
224     /**
225      * Override parent class to return our preferred item.
226      *
227      * @param Notice $notice Notice to display
228      *
229      * @return NoticeListItem a list item to show
230      */
231
232     function newListItem($notice)
233     {
234         return new ConversationTreeItem($notice, $this->out);
235     }
236 }
237
238 /**
239  * Conversation tree list item
240  *
241  * Special class of NoticeListItem for use inside conversation trees.
242  *
243  * @category Widget
244  * @package  Laconica
245  * @author   Evan Prodromou <evan@controlyourself.ca>
246  * @license  http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
247  * @link     http://laconi.ca/
248  */
249
250 class ConversationTreeItem extends NoticeListItem
251 {
252     /**
253      * start a single notice.
254      *
255      * The default creates the <li>; we skip, since the ConversationTree
256      * takes care of that.
257      *
258      * @return void
259      */
260
261     function showStart()
262     {
263         return;
264     }
265
266     /**
267      * finish the notice
268      *
269      * The default closes the <li>; we skip, since the ConversationTree
270      * takes care of that.
271      *
272      * @return void
273      */
274
275     function showEnd()
276     {
277         return;
278     }
279
280     /**
281      * show link to notice conversation page
282      *
283      * Since we're only used on the conversation page, we skip this
284      *
285      * @return void
286      */
287
288     function showContext()
289     {
290         return;
291     }
292 }