]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - plugins/UserFlag/adminprofileflag.php
Merge remote-tracking branch 'mainline/1.0.x' into people_tags_rebase
[quix0rs-gnu-social.git] / plugins / UserFlag / adminprofileflag.php
1 <?php
2 /**
3  * Show latest and greatest profile flags
4  *
5  * PHP version 5
6  *
7  * @category Action
8  * @package  StatusNet
9  * @author   Evan Prodromou <evan@status.net>
10  * @license  http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
11  * @link     http://status.net/
12  *
13  * StatusNet - the distributed open-source microblogging tool
14  * Copyright (C) 2009, StatusNet, 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('STATUSNET')) {
31     exit(1);
32 }
33
34 /**
35  * Show the latest and greatest profile flags
36  *
37  * @category Action
38  * @package  StatusNet
39  * @author   Evan Prodromou <evan@status.net>
40  * @license  http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
41  * @link     http://status.net/
42  */
43 class AdminprofileflagAction extends Action
44 {
45     var $page     = null;
46     var $profiles = null;
47
48     /**
49      * Take arguments for running
50      *
51      * @param array $args $_REQUEST args
52      *
53      * @return boolean success flag
54      */
55     function prepare($args)
56     {
57         parent::prepare($args);
58
59         $user = common_current_user();
60
61         // User must be logged in.
62
63         if (!common_logged_in()) {
64             // TRANS: Error message displayed when trying to perform an action that requires a logged in user.
65             $this->clientError(_m('Not logged in.'));
66             return;
67         }
68
69         $user = common_current_user();
70
71         // ...because they're logged in
72
73         assert(!empty($user));
74
75         // It must be a "real" login, not saved cookie login
76
77         if (!common_is_real_login()) {
78             // Cookie theft is too easy; we require automatic
79             // logins to re-authenticate before admining the site
80             common_set_returnto($this->selfUrl());
81             if (Event::handle('RedirectToLogin', array($this, $user))) {
82                 common_redirect(common_local_url('login'), 303);
83             }
84         }
85
86         // User must have the right to review flags
87
88         if (!$user->hasRight(UserFlagPlugin::REVIEWFLAGS)) {
89             $this->clientError(_m('You cannot review profile flags.'));
90             return false;
91         }
92
93         $this->page = $this->trimmed('page');
94
95         if (empty($this->page)) {
96             $this->page = 1;
97         }
98
99         $this->profiles = $this->getProfiles();
100
101         return true;
102     }
103
104     /**
105      * Handle request
106      *
107      * @param array $args $_REQUEST args; handled in prepare()
108      *
109      * @return void
110      */
111     function handle($args)
112     {
113         parent::handle($args);
114
115         $this->showPage();
116     }
117
118     /**
119      * Title of this page
120      *
121      * @return string Title of the page
122      */
123     function title()
124     {
125         // TRANS: Title for page with a list of profiles that were flagged for review.
126         return _m('Flagged profiles');
127     }
128
129     /**
130      * save the profile flag
131      *
132      * @return void
133      */
134     function showContent()
135     {
136         $pl = new FlaggedProfileList($this->profiles, $this);
137
138         $cnt = $pl->show();
139
140         $this->pagination($this->page > 1, $cnt > PROFILES_PER_PAGE,
141                           $this->page, 'adminprofileflag');
142     }
143
144     /**
145      * Retrieve this action's profiles
146      *
147      * @return Profile $profile Profile query results
148      */
149     function getProfiles()
150     {
151         $ufp = new User_flag_profile();
152
153         $ufp->selectAdd();
154         $ufp->selectAdd('profile_id');
155         $ufp->selectAdd('count(*) as flag_count');
156
157         $ufp->whereAdd('cleared is NULL');
158
159         $ufp->groupBy('profile_id');
160         $ufp->orderBy('flag_count DESC, profile_id DESC');
161
162         $offset = ($this->page-1) * PROFILES_PER_PAGE;
163         $limit  = PROFILES_PER_PAGE + 1;
164
165         $ufp->limit($offset, $limit);
166
167         $profiles = array();
168
169         if ($ufp->find()) {
170             while ($ufp->fetch()) {
171                 $profile = Profile::staticGet('id', $ufp->profile_id);
172                 if (!empty($profile)) {
173                     $profiles[] = $profile;
174                 }
175             }
176         }
177
178         $ufp->free();
179
180         return new ArrayWrapper($profiles);
181     }
182 }
183
184 /**
185  * Specialization of ProfileList to show flagging information
186  *
187  * Most of the hard part is done in FlaggedProfileListItem.
188  *
189  * @category Widget
190  * @package  StatusNet
191  * @author   Evan Prodromou <evan@status.net>
192  * @license  http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
193  * @link     http://status.net/
194  */
195 class FlaggedProfileList extends ProfileList
196 {
197     /**
198      * Factory method for creating new list items
199      *
200      * @param Profile $profile Profile to create an item for
201      *
202      * @return ProfileListItem newly-created item
203      */
204     function newListItem($profile)
205     {
206         return new FlaggedProfileListItem($this->profile, $this->action);
207     }
208 }
209
210 /**
211  * Specialization of ProfileListItem to show flagging information
212  *
213  * @category Widget
214  * @package  StatusNet
215  * @author   Evan Prodromou <evan@status.net>
216  * @license  http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
217  * @link     http://status.net/
218  */
219 class FlaggedProfileListItem extends ProfileListItem
220 {
221     const MAX_FLAGGERS = 5;
222
223     var $user   = null;
224     var $r2args = null;
225
226     /**
227      * Overload parent's action list with our own moderation-oriented buttons
228      *
229      * @return void
230      */
231     function showActions()
232     {
233         $this->user = common_current_user();
234
235         list($action, $this->r2args) = $this->out->returnToArgs();
236
237         $this->r2args['action'] = $action;
238
239         $this->startActions();
240         if (Event::handle('StartProfileListItemActionElements', array($this))) {
241             $this->out->elementStart('li', 'entity_moderation');
242             // TRANS: Header for moderation menu with action buttons for flagged profiles (like 'sandbox', 'silence', ...).
243             $this->out->element('p', null, _m('Moderate'));
244             $this->out->elementStart('ul');
245             $this->showSandboxButton();
246             $this->showSilenceButton();
247             $this->showDeleteButton();
248             $this->showClearButton();
249             $this->out->elementEnd('ul');
250             $this->out->elementEnd('li');
251             Event::handle('EndProfileListItemActionElements', array($this));
252         }
253         $this->endActions();
254     }
255
256     /**
257      * Show a button to sandbox the profile
258      *
259      * @return void
260      */
261     function showSandboxButton()
262     {
263         if ($this->user->hasRight(Right::SANDBOXUSER)) {
264             $this->out->elementStart('li', 'entity_sandbox');
265             if ($this->profile->isSandboxed()) {
266                 $usf = new UnSandboxForm($this->out, $this->profile, $this->r2args);
267                 $usf->show();
268             } else {
269                 $sf = new SandboxForm($this->out, $this->profile, $this->r2args);
270                 $sf->show();
271             }
272             $this->out->elementEnd('li');
273         }
274     }
275
276     /**
277      * Show a button to silence the profile
278      *
279      * @return void
280      */
281     function showSilenceButton()
282     {
283         if ($this->user->hasRight(Right::SILENCEUSER)) {
284             $this->out->elementStart('li', 'entity_silence');
285             if ($this->profile->isSilenced()) {
286                 $usf = new UnSilenceForm($this->out, $this->profile, $this->r2args);
287                 $usf->show();
288             } else {
289                 $sf = new SilenceForm($this->out, $this->profile, $this->r2args);
290                 $sf->show();
291             }
292             $this->out->elementEnd('li');
293         }
294     }
295
296     /**
297      * Show a button to delete user and profile
298      *
299      * @return void
300      */
301     function showDeleteButton()
302     {
303
304         if ($this->user->hasRight(Right::DELETEUSER)) {
305             $this->out->elementStart('li', 'entity_delete');
306             $df = new DeleteUserForm($this->out, $this->profile, $this->r2args);
307             $df->show();
308             $this->out->elementEnd('li');
309         }
310     }
311
312     /**
313      * Show a button to clear flags
314      *
315      * @return void
316      */
317     function showClearButton()
318     {
319         if ($this->user->hasRight(UserFlagPlugin::CLEARFLAGS)) {
320             $this->out->elementStart('li', 'entity_clear');
321             $cf = new ClearFlagForm($this->out, $this->profile, $this->r2args);
322             $cf->show();
323             $this->out->elementEnd('li');
324         }
325     }
326
327     /**
328      * Overload parent function to add flaggers list
329      *
330      * @return void
331      */
332     function endProfile()
333     {
334         $this->showFlaggersList();
335         parent::endProfile();
336     }
337
338     /**
339      * Show a list of people who've flagged this profile
340      *
341      * @return void
342      */
343     function showFlaggersList()
344     {
345         $flaggers = array();
346
347         $ufp = new User_flag_profile();
348
349         $ufp->selectAdd();
350         $ufp->selectAdd('user_id');
351         $ufp->profile_id = $this->profile->id;
352         $ufp->orderBy('created');
353
354         if ($ufp->find()) { // XXX: this should always happen
355             while ($ufp->fetch()) {
356                 $user = User::staticGet('id', $ufp->user_id);
357                 if (!empty($user)) { // XXX: this would also be unusual
358                     $flaggers[] = clone($user);
359                 }
360             }
361         }
362
363         $cnt    = count($flaggers);
364         $others = 0;
365
366         if ($cnt > self::MAX_FLAGGERS) {
367             $flaggers = array_slice($flaggers, 0, self::MAX_FLAGGERS);
368             $others   = $cnt - self::MAX_FLAGGERS;
369         }
370
371         $lnks = array();
372
373         foreach ($flaggers as $flagger) {
374
375             $url = common_local_url('showstream',
376                                     array('nickname' => $flagger->nickname));
377
378             $lnks[] = XMLStringer::estring('a', array('href' => $url,
379                                                       'class' => 'flagger'),
380                                            $flagger->nickname);
381         }
382
383         if ($cnt > 0) {
384             if ($others > 0) {
385                 $flagging_users = implode(', ', $lnks);
386                 // TRANS: Message displayed on a profile if it has been flagged.
387                 // TRANS: %1$s is a comma separated list of at most 5 user nicknames that flagged.
388                 // TRANS: %2$d is a positive integer of additional flagging users. Also used for the plural.
389                 $text .= sprintf(_m('Flagged by %1$s and %2$d other', 'Flagged by %1$s and %2$d others', $others), $flagging_users, $others);
390             } else {
391                 // TRANS: Message displayed on a profile if it has been flagged.
392                 // TRANS: %s is a comma separated list of at most 5 user nicknames that flagged.
393                 $text .= sprintf(_m('Flagged by %s'), $flagging_users);
394             }
395
396             $this->out->elementStart('p', array('class' => 'flaggers'));
397             $this->out->raw($text);
398             $this->out->elementEnd('p');
399         }
400     }
401 }