]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - plugins/Directory/actions/groupdirectory.php
053516b793e0edad371247a4350e142f0327ac96
[quix0rs-gnu-social.git] / plugins / Directory / actions / groupdirectory.php
1 <?php
2 /**
3  * StatusNet, the distributed open-source microblogging tool
4  *
5  * Output a group directory
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  Public
23  * @package   StatusNet
24  * @author    Zach Copley <zach@status.net>
25  * @copyright 2011 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('GNUSOCIAL')) { exit(1); }
31
32 /**
33  * Group directory
34  *
35  * @category Directory
36  * @package  StatusNet
37  * @author   Zach Copley <zach@status.net>
38  * @author   Mikael Nordfeldth <mmn@hethane.se>
39  * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
40  * @link     http://status.net/
41  */
42 class GroupdirectoryAction extends ManagedAction
43 {
44     /**
45      * The page we're on
46      *
47      * @var integer
48      */
49     public $page;
50
51     /**
52      * What to filter the search results by
53      *
54      * @var string
55      */
56     public $filter;
57
58     /**
59      * Column to sort by
60      *
61      * @var string
62      */
63     public $sort;
64
65     /**
66      * How to order search results, ascending or descending
67      *
68      * @var string
69      */
70     public $reverse;
71
72     /**
73      * Query
74      *
75      * @var string
76      */
77     public $q;
78
79     /**
80      * Title of the page
81      *
82      * @return string Title of the page
83      */
84     function title()
85     {
86         // @fixme: This looks kinda gross
87
88         if ($this->filter == 'all') {
89             if ($this->page != 1) {
90                 // TRANS: Title for group directory page. %d is a page number.
91                 return(sprintf(_m('Group Directory, page %d'), $this->page));
92             }
93             // TRANS: Title for group directory page.
94             return _m('Group directory');
95         } else if ($this->page == 1) {
96             return sprintf(
97                 // TRANS: Title for group directory page when it is filtered.
98                 // TRANS: %s is the filter string.
99                 _m('Group directory - %s'),
100                 strtoupper($this->filter)
101             );
102         } else {
103             return sprintf(
104                 // TRANS: Title for group directory page when it is filtered.
105                 // TRANS: %1$s is the filter string, %2$d is a page number.
106                 _m('Group directory - %1$s, page %2$d'),
107                 strtoupper($this->filter),
108                 $this->page
109             );
110         }
111     }
112
113     /**
114      * Instructions for use
115      *
116      * @return instructions for use
117      */
118     function getInstructions()
119     {
120         // TRANS: Page instructions.
121         return _m("After you join a group you can send messages to all other members\n".
122                  "using the syntax \"!groupname\".\n\n".
123                  "Browse groups, or search for groups by their name, location or topic.\n".
124                  "Separate the terms by spaces; they must be three characters or more.") . "\n";
125     }
126
127     /**
128      * Is this page read-only?
129      *
130      * @return boolean true
131      */
132     function isReadOnly($args)
133     {
134         return true;
135     }
136
137     protected function doPreparation()
138     {
139         $this->page    = ($this->arg('page')) ? ($this->arg('page') + 0) : 1;
140         $this->filter  = $this->arg('filter', 'all');
141         $this->reverse = $this->boolean('reverse');
142         $this->q       = $this->trimmed('q');
143         $this->sort    = $this->arg('sort', 'nickname');
144
145         common_set_returnto($this->selfUrl());
146
147         return true;
148     }
149
150     /**
151      * Show the page notice
152      *
153      * Shows instructions for the page
154      *
155      * @return void
156      */
157     function showPageNotice()
158     {
159         $instr  = $this->getInstructions();
160         $output = common_markup_to_html($instr);
161
162         $this->elementStart('div', 'instructions');
163         $this->raw($output);
164         $this->elementEnd('div');
165     }
166
167
168     /**
169      * Content area
170      *
171      * Shows the groups
172      *
173      * @return void
174      */
175     function showContent()
176     {
177         if (common_logged_in()) {
178             $this->elementStart(
179                 'p',
180                 array(
181                     'id' => 'new_group'
182                 )
183             );
184             $this->element(
185                 'a',
186                 array(
187                     'href'  => common_local_url('newgroup'),
188                     'class' => 'more'),
189                     // TRANS: Link to create a new group on the group list page.
190                     _m('Create a new group')
191             );
192             $this->elementEnd('p');
193         }
194
195         $this->showForm();
196
197         $this->elementStart('div', array('id' => 'profile_directory'));
198
199         // @todo FIXME: Does "All" need i18n here?
200         $alphaNav = new AlphaNav($this, false, false, array('0-9', 'All'));
201         $alphaNav->show();
202
203         $group   = null;
204         $group   = $this->getGroups();
205         $cnt     = 0;
206
207         if (!empty($group)) {
208             $groupList = new SortableGroupList(
209                 $group,
210                 common_current_user(),
211                 $this
212             );
213
214             $cnt = $groupList->show();
215             $group->free();
216
217             if (0 == $cnt) {
218                 $this->showEmptyListMessage();
219             }
220         }
221
222         $args = array();
223         if (isset($this->q)) {
224             $args['q'] = $this->q;
225         } else {
226             $args['filter'] = $this->filter;
227         }
228
229         $this->pagination(
230             $this->page > 1,
231             $cnt > PROFILES_PER_PAGE,
232             $this->page,
233             'groupdirectory',
234             $args
235         );
236
237         $this->elementEnd('div');
238     }
239
240     function showForm($error=null)
241     {
242         $this->elementStart(
243             'form',
244             array(
245                 'method' => 'get',
246                 'id'     => 'form_search',
247                 'class'  => 'form_settings',
248                 'action' => common_local_url('groupdirectory')
249             )
250         );
251
252         $this->elementStart('fieldset');
253
254         // TRANS: Fieldset legend.
255         $this->element('legend', null, _m('Search groups'));
256         $this->elementStart('ul', 'form_data');
257         $this->elementStart('li');
258
259         // TRANS: Field label for input of one or more keywords.
260         $this->input('q', _m('Keyword(s)'), $this->q);
261
262         // TRANS: Button text for searching group directory.
263         $this->submit('search', _m('BUTTON','Search'));
264         $this->elementEnd('li');
265         $this->elementEnd('ul');
266         $this->elementEnd('fieldset');
267         $this->elementEnd('form');
268     }
269
270     /*
271      * Get groups filtered by the current filter, sort key,
272      * sort order, and page
273      */
274     function getGroups()
275     {
276         $group = new User_group();
277
278         $offset = ($this->page-1) * PROFILES_PER_PAGE;
279         $limit  = PROFILES_PER_PAGE + 1;
280
281         if (!empty($this->q)) {
282
283             // Disable this to get global group searches
284             $group->joinAdd(array('id', 'local_group:group_id'));
285
286             $wheres = array('nickname', 'fullname', 'homepage', 'description', 'location');
287             foreach ($wheres as $where) {
288                 $group->whereAdd("LOWER({$group->__table}.{$where}) LIKE LOWER('%".$group->escape($this->q)."%')", 'OR');
289             }
290
291             $order = "{$group->__table}.created ASC";
292
293             if ($this->sort == 'nickname') {
294                 $order = $this->reverse
295                         ? "{$group->__table}.nickname DESC"
296                         : "{$group->__table}.nickname ASC";
297             } elseif ($this->reverse) {
298                 $order = "{$group->__table}.created DESC";
299             }
300
301             $group->orderBy($order);
302             $group->limit($offset, $limit);
303
304         } else {
305             // User is browsing via AlphaNav
306             $sort   = $this->getSortKey();
307
308             $sql = <<< GROUP_QUERY_END
309 SELECT user_group.*
310 FROM user_group
311 JOIN local_group ON user_group.id = local_group.group_id
312 GROUP_QUERY_END;
313
314             switch($this->filter)
315             {
316             case 'all':
317                 // NOOP
318                 break;
319             case '0-9':
320                 $sql .=
321                     '  AND LEFT(user_group.nickname, 1) BETWEEN \'0\' AND \'9\'';
322                 break;
323             default:
324                 $sql .= sprintf(
325                     ' AND LEFT(LOWER(user_group.nickname), 1) = \'%s\'',
326                     $this->filter
327                 );
328             }
329
330             $sql .= sprintf(
331                 ' ORDER BY user_group.%s %s, user_group.nickname ASC LIMIT %d, %d',
332                 $sort,
333                 $this->reverse ? 'DESC' : 'ASC',
334                 $offset,
335                 $limit
336             );
337
338             $group->query($sql);
339         }
340
341         $group->find();
342
343         return $group;
344     }
345
346     /**
347      * Filter the sort parameter
348      *
349      * @return string   a column name for sorting
350      */
351     function getSortKey()
352     {
353         switch ($this->sort) {
354         case 'nickname':
355             return $this->sort;
356             break;
357         case 'created':
358             return $this->sort;
359             break;
360         default:
361             return 'nickname';
362         }
363     }
364
365     /**
366      * Show a nice message when there's no search results
367      */
368     function showEmptyListMessage()
369     {
370         if (!empty($this->filter) && ($this->filter != 'all')) {
371             $this->element(
372                 'p',
373                 'error',
374                 sprintf(
375                     // TRANS: Empty list message for searching group directory.
376                     // TRANS: %s is the search string.
377                     _m('No groups starting with %s.'),
378                     $this->filter
379                 )
380             );
381         } else {
382             // TRANS: Empty list message for searching group directory.
383             $this->element('p', 'error', _m('No results.'));
384             // TRANS: Help text for searching group directory.
385             $message = _m("* Make sure all words are spelled correctly.\n".
386                           "* Try different keywords.\n".
387                           "* Try more general keywords.\n".
388                           "* Try fewer keywords.");
389             $this->elementStart('div', 'help instructions');
390             $this->raw(common_markup_to_html($message));
391             $this->elementEnd('div');
392         }
393     }
394
395     function showSections()
396     {
397         $gbp = new GroupsByPostsSection($this);
398         $gbp->show();
399         $gbm = new GroupsByMembersSection($this);
400         $gbm->show();
401     }
402 }