Passed
Push — metrics ( 091324...ec38a1 )
by Simon
03:57 queued 13s
created

PageUserManagement::suspend()   B

Complexity

Conditions 8
Paths 6

Size

Total Lines 58
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 35
dl 0
loc 58
rs 8.1155
c 0
b 0
f 0
cc 8
nc 6
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/******************************************************************************
3
 * Wikipedia Account Creation Assistance tool                                 *
4
 * ACC Development Team. Please see team.json for a list of contributors.     *
5
 *                                                                            *
6
 * This is free and unencumbered software released into the public domain.    *
7
 * Please see LICENSE.md for the full licencing statement.                    *
8
 ******************************************************************************/
9
10
namespace Waca\Pages;
11
12
use Exception;
13
use SmartyException;
14
use Waca\DataObjects\Domain;
15
use Waca\DataObjects\User;
16
use Waca\DataObjects\UserRole;
17
use Waca\Exceptions\ApplicationLogicException;
18
use Waca\Exceptions\OptimisticLockFailedException;
19
use Waca\Helpers\Logger;
20
use Waca\Helpers\OAuthUserHelper;
21
use Waca\Helpers\PreferenceManager;
22
use Waca\Helpers\SearchHelpers\UserSearchHelper;
23
use Waca\SessionAlert;
24
use Waca\Tasks\InternalPageBase;
25
use Waca\WebRequest;
26
27
/**
28
 * Class PageUserManagement
29
 * @package Waca\Pages
30
 */
31
class PageUserManagement extends InternalPageBase
32
{
33
    // FIXME: domains
34
    /** @var string */
35
    private $adminMailingList = '[email protected]';
36
37
    /**
38
     * Main function for this page, when no specific actions are called.
39
     */
40
    protected function main()
41
    {
42
        $this->setHtmlTitle('User Management');
43
44
        $database = $this->getDatabase();
45
        $currentUser = User::getCurrent($database);
46
47
        $userSearchRequest = WebRequest::getString('usersearch');
48
        if ($userSearchRequest !== null) {
49
            $searchedUser = User::getByUsername($userSearchRequest, $database);
50
            if ($searchedUser !== false) {
51
                $this->redirect('statistics/users', 'detail', ['user' => $searchedUser->getId()]);
52
                return;
53
            }
54
        }
55
56
        // A bit hacky, but it's better than my last solution of creating an object for each user and passing that to
57
        // the template. I still don't have a particularly good way of handling this.
58
        OAuthUserHelper::prepareTokenCountStatement($database);
59
60
        if (WebRequest::getBoolean("showAll")) {
61
            $this->assign("showAll", true);
62
63
            $suspendedUsers = UserSearchHelper::get($database)->byStatus(User::STATUS_SUSPENDED)->fetch();
64
            $this->assign("suspendedUsers", $suspendedUsers);
65
66
            $declinedUsers = UserSearchHelper::get($database)->byStatus(User::STATUS_DECLINED)->fetch();
67
            $this->assign("declinedUsers", $declinedUsers);
68
69
            UserSearchHelper::get($database)->getRoleMap($roleMap);
70
        }
71
        else {
72
            $this->assign("showAll", false);
73
            $this->assign("suspendedUsers", array());
74
            $this->assign("declinedUsers", array());
75
76
            UserSearchHelper::get($database)->statusIn(array('New', 'Active'))->getRoleMap($roleMap);
77
        }
78
79
        $newUsers = UserSearchHelper::get($database)->byStatus(User::STATUS_NEW)->fetch();
80
        $normalUsers = UserSearchHelper::get($database)->byStatus(User::STATUS_ACTIVE)->byRole('user')->fetch();
81
        $adminUsers = UserSearchHelper::get($database)->byStatus(User::STATUS_ACTIVE)->byRole('admin')->fetch();
82
        $checkUsers = UserSearchHelper::get($database)->byStatus(User::STATUS_ACTIVE)->byRole('checkuser')->fetch();
83
        $stewards = UserSearchHelper::get($database)->byStatus(User::STATUS_ACTIVE)->byRole('steward')->fetch();
84
        $toolRoots = UserSearchHelper::get($database)->byStatus(User::STATUS_ACTIVE)->byRole('toolRoot')->fetch();
85
        $this->assign('newUsers', $newUsers);
86
        $this->assign('normalUsers', $normalUsers);
87
        $this->assign('adminUsers', $adminUsers);
88
        $this->assign('checkUsers', $checkUsers);
89
        $this->assign('stewards', $stewards);
90
        $this->assign('toolRoots', $toolRoots);
91
92
        $this->assign('roles', $roleMap);
93
94
        $this->addJs("/api.php?action=users&all=true&targetVariable=typeaheaddata");
95
96
        $this->assign('canApprove', $this->barrierTest('approve', $currentUser));
97
        $this->assign('canDecline', $this->barrierTest('decline', $currentUser));
98
        $this->assign('canRename', $this->barrierTest('rename', $currentUser));
99
        $this->assign('canEditUser', $this->barrierTest('editUser', $currentUser));
100
        $this->assign('canSuspend', $this->barrierTest('suspend', $currentUser));
101
        $this->assign('canEditRoles', $this->barrierTest('editRoles', $currentUser));
102
103
        // FIXME: domains!
104
        /** @var Domain $domain */
105
        $domain = Domain::getById(1, $this->getDatabase());
106
        $this->assign('mediawikiScriptPath', $domain->getWikiArticlePath());
107
108
        $this->setTemplate("usermanagement/main.tpl");
109
    }
110
111
    #region Access control
112
113
    /**
114
     * Action target for editing the roles assigned to a user
115
     *
116
     * @throws ApplicationLogicException
117
     * @throws SmartyException
118
     * @throws OptimisticLockFailedException
119
     * @throws Exception
120
     */
121
    protected function editRoles(): void
122
    {
123
        $this->setHtmlTitle('User Management');
124
        $database = $this->getDatabase();
125
        $domain = Domain::getCurrent($database);
126
        $userId = WebRequest::getInt('user');
127
128
        /** @var User|false $user */
129
        $user = User::getById($userId, $database);
130
131
        if ($user === false || $user->isCommunityUser()) {
132
            throw new ApplicationLogicException('Sorry, the user you are trying to edit could not be found.');
133
        }
134
135
        $roleData = $this->getRoleData(UserRole::getForUser($user->getId(), $database, $domain->getId()));
136
137
        // Dual-mode action
138
        if (WebRequest::wasPosted()) {
139
            $this->validateCSRFToken();
140
141
            $reason = WebRequest::postString('reason');
142
            if ($reason === false || trim($reason) === '') {
143
                throw new ApplicationLogicException('No reason specified for roles change');
144
            }
145
146
            /** @var UserRole[] $delete */
147
            $delete = array();
148
            /** @var string[] $add */
149
            $add = array();
150
151
            /** @var UserRole[] $globalDelete */
152
            $globalDelete = array();
153
            /** @var string[] $globalAdd */
154
            $globalAdd = array();
155
156
            foreach ($roleData as $name => $r) {
157
                if ($r['allowEdit'] !== 1) {
158
                    // not allowed, to touch this, so ignore it
159
                    continue;
160
                }
161
162
                $newValue = WebRequest::postBoolean('role-' . $name) ? 1 : 0;
163
                if ($newValue !== $r['active']) {
164
                    if ($newValue === 0) {
165
                        if ($r['globalOnly']) {
166
                            $globalDelete[] = $r['object'];
167
                        }
168
                        else {
169
                            $delete[] = $r['object'];
170
                        }
171
                    }
172
173
                    if ($newValue === 1) {
174
                        if ($r['globalOnly']) {
175
                            $globalAdd[] = $name;
176
                        }
177
                        else {
178
                            $add[] = $name;
179
                        }
180
                    }
181
                }
182
            }
183
184
            // Check there's something to do
185
            if ((count($add) + count($delete) + count($globalAdd) + count($globalDelete)) === 0) {
186
                $this->redirect('statistics/users', 'detail', array('user' => $user->getId()));
187
                SessionAlert::warning('No changes made to roles.');
188
189
                return;
190
            }
191
192
            $removed = array();
193
            $globalRemoved = array();
194
195
            foreach ($delete as $d) {
196
                $removed[] = $d->getRole();
197
                $d->delete();
198
            }
199
200
            foreach ($globalDelete as $d) {
201
                $globalRemoved[] = $d->getRole();
202
                $d->delete();
203
            }
204
205
            foreach ($add as $x) {
206
                $a = new UserRole();
207
                $a->setUser($user->getId());
208
                $a->setRole($x);
209
                $a->setDomain($domain->getId());
210
                $a->setDatabase($database);
211
                $a->save();
212
            }
213
214
            foreach ($globalAdd as $x) {
215
                $a = new UserRole();
216
                $a->setUser($user->getId());
217
                $a->setRole($x);
218
                $a->setDomain(null);
219
                $a->setDatabase($database);
220
                $a->save();
221
            }
222
223
            if ((count($add) + count($delete)) > 0) {
224
                Logger::userRolesEdited($database, $user, $reason, $add, $removed, $domain->getId());
225
            }
226
227
            if ((count($globalAdd) + count($globalDelete)) > 0) {
228
                Logger::userGlobalRolesEdited($database, $user, $reason, $globalAdd, $globalRemoved);
229
            }
230
231
            // dummy save for optimistic locking. If this fails, the entire txn will roll back.
232
            $user->setUpdateVersion(WebRequest::postInt('updateversion'));
233
            $user->save();
234
235
            $this->getNotificationHelper()->userRolesEdited($user, $reason);
236
            SessionAlert::quick('Roles changed for user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
237
238
            $this->redirect('statistics/users', 'detail', array('user' => $user->getId()));
239
        }
240
        else {
241
            $this->assignCSRFToken();
242
            $this->setTemplate('usermanagement/roleedit.tpl');
243
            $this->assign('user', $user);
244
            $this->assign('roleData', $roleData);
245
        }
246
    }
247
248
    /**
249
     * Action target for suspending users
250
     *
251
     * @throws ApplicationLogicException
252
     */
253
    protected function suspend()
254
    {
255
        $this->setHtmlTitle('User Management');
256
257
        $database = $this->getDatabase();
258
259
        $userId = WebRequest::getInt('user');
260
261
        /** @var User $user */
262
        $user = User::getById($userId, $database);
263
264
        if ($user === false || $user->isCommunityUser()) {
265
            throw new ApplicationLogicException('Sorry, the user you are trying to suspend could not be found.');
266
        }
267
268
        if ($user->isSuspended()) {
269
            throw new ApplicationLogicException('Sorry, the user you are trying to suspend is already suspended.');
270
        }
271
272
        // Dual-mode action
273
        if (WebRequest::wasPosted()) {
274
            $this->validateCSRFToken();
275
            $reason = WebRequest::postString('reason');
276
277
            if ($reason === null || trim($reason) === "") {
278
                throw new ApplicationLogicException('No reason provided');
279
            }
280
281
            $user->setStatus(User::STATUS_SUSPENDED);
282
            $user->setUpdateVersion(WebRequest::postInt('updateversion'));
283
            $user->save();
284
            Logger::suspendedUser($database, $user, $reason);
285
286
            $this->getNotificationHelper()->userSuspended($user, $reason);
287
            SessionAlert::quick('Suspended user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
288
289
            // send email
290
            $this->sendStatusChangeEmail(
291
                'Your WP:ACC account has been suspended',
292
                'usermanagement/emails/suspended.tpl',
293
                $reason,
294
                $user,
295
                User::getCurrent($database)->getUsername()
296
            );
297
298
            $this->redirect('userManagement');
299
300
            return;
301
        }
302
        else {
303
            $this->assignCSRFToken();
304
            $this->setTemplate('usermanagement/changelevel-reason.tpl');
305
            $this->assign('user', $user);
306
            $this->assign('status', 'Suspended');
307
            $this->assign("showReason", true);
308
309
            if (WebRequest::getString('preload')) {
310
                $this->assign('preload', WebRequest::getString('preload'));
311
            }
312
        }
313
    }
314
315
    /**
316
     * Entry point for the decline action
317
     *
318
     * @throws ApplicationLogicException
319
     */
320
    protected function decline()
321
    {
322
        $this->setHtmlTitle('User Management');
323
324
        $database = $this->getDatabase();
325
326
        $userId = WebRequest::getInt('user');
327
        $user = User::getById($userId, $database);
328
329
        if ($user === false || $user->isCommunityUser()) {
330
            throw new ApplicationLogicException('Sorry, the user you are trying to decline could not be found.');
331
        }
332
333
        if (!$user->isNewUser()) {
334
            throw new ApplicationLogicException('Sorry, the user you are trying to decline is not new.');
335
        }
336
337
        // Dual-mode action
338
        if (WebRequest::wasPosted()) {
339
            $this->validateCSRFToken();
340
            $reason = WebRequest::postString('reason');
341
342
            if ($reason === null || trim($reason) === "") {
343
                throw new ApplicationLogicException('No reason provided');
344
            }
345
346
            $user->setStatus(User::STATUS_DECLINED);
347
            $user->setUpdateVersion(WebRequest::postInt('updateversion'));
348
            $user->save();
349
            Logger::declinedUser($database, $user, $reason);
350
351
            $this->getNotificationHelper()->userDeclined($user, $reason);
352
            SessionAlert::quick('Declined user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
353
354
            // send email
355
            $this->sendStatusChangeEmail(
356
                'Your WP:ACC account has been declined',
357
                'usermanagement/emails/declined.tpl',
358
                $reason,
359
                $user,
360
                User::getCurrent($database)->getUsername()
361
            );
362
363
            $this->redirect('userManagement');
364
365
            return;
366
        }
367
        else {
368
            $this->assignCSRFToken();
369
            $this->setTemplate('usermanagement/changelevel-reason.tpl');
370
            $this->assign('user', $user);
371
            $this->assign('status', 'Declined');
372
            $this->assign("showReason", true);
373
        }
374
    }
375
376
    /**
377
     * Entry point for the approve action
378
     *
379
     * @throws ApplicationLogicException
380
     */
381
    protected function approve()
382
    {
383
        $this->setHtmlTitle('User Management');
384
385
        $database = $this->getDatabase();
386
387
        $userId = WebRequest::getInt('user');
388
        $user = User::getById($userId, $database);
389
390
        if ($user === false || $user->isCommunityUser()) {
391
            throw new ApplicationLogicException('Sorry, the user you are trying to approve could not be found.');
392
        }
393
394
        if ($user->isActive()) {
395
            throw new ApplicationLogicException('Sorry, the user you are trying to approve is already an active user.');
396
        }
397
398
        // Dual-mode action
399
        if (WebRequest::wasPosted()) {
400
            $this->validateCSRFToken();
401
            $user->setStatus(User::STATUS_ACTIVE);
402
            $user->setUpdateVersion(WebRequest::postInt('updateversion'));
403
            $user->save();
404
            Logger::approvedUser($database, $user);
405
406
            $this->getNotificationHelper()->userApproved($user);
407
            SessionAlert::quick('Approved user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
408
409
            // send email
410
            $this->sendStatusChangeEmail(
411
                'Your WP:ACC account has been approved',
412
                'usermanagement/emails/approved.tpl',
413
                null,
414
                $user,
415
                User::getCurrent($database)->getUsername()
416
            );
417
418
            $this->redirect("userManagement");
419
420
            return;
421
        }
422
        else {
423
            $this->assignCSRFToken();
424
            $this->setTemplate("usermanagement/changelevel-reason.tpl");
425
            $this->assign("user", $user);
426
            $this->assign("status", "Active");
427
            $this->assign("showReason", false);
428
        }
429
    }
430
431
    #endregion
432
433
    #region Renaming / Editing
434
435
    /**
436
     * Entry point for the rename action
437
     *
438
     * @throws ApplicationLogicException
439
     */
440
    protected function rename()
441
    {
442
        $this->setHtmlTitle('User Management');
443
444
        $database = $this->getDatabase();
445
446
        $userId = WebRequest::getInt('user');
447
        $user = User::getById($userId, $database);
448
449
        if ($user === false || $user->isCommunityUser()) {
450
            throw new ApplicationLogicException('Sorry, the user you are trying to rename could not be found.');
451
        }
452
453
        // Dual-mode action
454
        if (WebRequest::wasPosted()) {
455
            $this->validateCSRFToken();
456
            $newUsername = WebRequest::postString('newname');
457
458
            if ($newUsername === null || trim($newUsername) === "") {
459
                throw new ApplicationLogicException('The new username cannot be empty');
460
            }
461
462
            if (User::getByUsername($newUsername, $database) != false) {
463
                throw new ApplicationLogicException('The new username already exists');
464
            }
465
466
            $oldUsername = $user->getUsername();
467
            $user->setUsername($newUsername);
468
            $user->setUpdateVersion(WebRequest::postInt('updateversion'));
469
470
            $user->save();
471
472
            $logEntryData = serialize(array(
473
                'old' => $oldUsername,
474
                'new' => $newUsername,
475
            ));
476
477
            Logger::renamedUser($database, $user, $logEntryData);
478
479
            SessionAlert::quick("Changed User "
480
                . htmlentities($oldUsername, ENT_COMPAT, 'UTF-8')
481
                . " name to "
482
                . htmlentities($newUsername, ENT_COMPAT, 'UTF-8'));
483
484
            $this->getNotificationHelper()->userRenamed($user, $oldUsername);
485
486
            // send an email to the user.
487
            $this->assign('targetUsername', $user->getUsername());
488
            $this->assign('toolAdmin', User::getCurrent($database)->getUsername());
489
            $this->assign('oldUsername', $oldUsername);
490
            $this->assign('mailingList', $this->adminMailingList);
491
492
            // FIXME: domains!
493
            /** @var Domain $domain */
494
            $domain = Domain::getById(1, $database);
0 ignored issues
show
Unused Code introduced by
The assignment to $domain is dead and can be removed.
Loading history...
495
            $this->getEmailHelper()->sendMail(
496
                $this->adminMailingList,
497
                $user->getEmail(),
498
                'Your username on WP:ACC has been changed',
499
                $this->fetchTemplate('usermanagement/emails/renamed.tpl')
500
            );
501
502
            $this->redirect("userManagement");
503
504
            return;
505
        }
506
        else {
507
            $this->assignCSRFToken();
508
            $this->setTemplate('usermanagement/renameuser.tpl');
509
            $this->assign('user', $user);
510
        }
511
    }
512
513
    /**
514
     * Entry point for the edit action
515
     *
516
     * @throws ApplicationLogicException
517
     */
518
    protected function editUser()
519
    {
520
        $this->setHtmlTitle('User Management');
521
522
        $database = $this->getDatabase();
523
524
        $userId = WebRequest::getInt('user');
525
        $user = User::getById($userId, $database);
526
        $oauth = new OAuthUserHelper($user, $database, $this->getOAuthProtocolHelper(), $this->getSiteConfiguration());
527
528
        if ($user === false || $user->isCommunityUser()) {
529
            throw new ApplicationLogicException('Sorry, the user you are trying to edit could not be found.');
530
        }
531
532
        // FIXME: domains
533
        $prefs = new PreferenceManager($database, $user->getId(), 1);
534
535
        // Dual-mode action
536
        if (WebRequest::wasPosted()) {
537
            $this->validateCSRFToken();
538
            $newEmail = WebRequest::postEmail('user_email');
539
            $newOnWikiName = WebRequest::postString('user_onwikiname');
540
541
            if ($newEmail === null) {
542
                throw new ApplicationLogicException('Invalid email address');
543
            }
544
545
            if ($this->validateUnusedEmail($newEmail, $userId)) {
0 ignored issues
show
Bug introduced by
It seems like $userId can also be of type null; however, parameter $userId of Waca\Pages\PageUserManag...::validateUnusedEmail() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

545
            if ($this->validateUnusedEmail($newEmail, /** @scrutinizer ignore-type */ $userId)) {
Loading history...
546
                throw new ApplicationLogicException('The specified email address is already in use.');
547
            }
548
549
            if (!($oauth->isFullyLinked() || $oauth->isPartiallyLinked())) {
550
                if (trim($newOnWikiName) == "") {
0 ignored issues
show
Bug introduced by
It seems like $newOnWikiName can also be of type null; however, parameter $string of trim() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

550
                if (trim(/** @scrutinizer ignore-type */ $newOnWikiName) == "") {
Loading history...
551
                    throw new ApplicationLogicException('New on-wiki username cannot be blank');
552
                }
553
554
                $user->setOnWikiName($newOnWikiName);
555
            }
556
557
            $user->setEmail($newEmail);
558
559
            $prefs->setLocalPreference(PreferenceManager::PREF_CREATION_MODE, WebRequest::postInt('creationmode'));
560
561
            $user->setUpdateVersion(WebRequest::postInt('updateversion'));
562
563
            $user->save();
564
565
            Logger::userPreferencesChange($database, $user);
566
            $this->getNotificationHelper()->userPrefChange($user);
567
            SessionAlert::quick('Changes to user\'s preferences have been saved');
568
569
            $this->redirect("userManagement");
570
571
            return;
572
        }
573
        else {
574
            $this->assignCSRFToken();
575
            $oauth = new OAuthUserHelper($user, $database, $this->getOAuthProtocolHelper(),
576
                $this->getSiteConfiguration());
577
            $this->setTemplate('usermanagement/edituser.tpl');
578
            $this->assign('user', $user);
579
            $this->assign('oauth', $oauth);
580
581
            $this->assign('preferredCreationMode', (int)$prefs->getPreference(PreferenceManager::PREF_CREATION_MODE));
582
            $this->assign('emailSignature', $prefs->getPreference(PreferenceManager::PREF_EMAIL_SIGNATURE));
583
584
            $this->assign('canManualCreate',
585
                $this->barrierTest(PreferenceManager::CREATION_MANUAL, $user, 'RequestCreation'));
586
            $this->assign('canOauthCreate',
587
                $this->barrierTest(PreferenceManager::CREATION_OAUTH, $user, 'RequestCreation'));
588
            $this->assign('canBotCreate',
589
                $this->barrierTest(PreferenceManager::CREATION_BOT, $user, 'RequestCreation'));
590
        }
591
    }
592
593
    #endregion
594
595
    private function validateUnusedEmail(string $email, int $userId) : bool {
596
        $query = 'SELECT COUNT(id) FROM user WHERE email = :email AND id <> :uid';
597
        $statement = $this->getDatabase()->prepare($query);
598
        $statement->execute(array(':email' => $email, ':uid' => $userId));
599
        $inUse = $statement->fetchColumn() > 0;
600
        $statement->closeCursor();
601
602
        return $inUse;
603
    }
604
605
    /**
606
     * Sends a status change email to the user.
607
     *
608
     * @param string      $subject           The subject of the email
609
     * @param string      $template          The smarty template to use
610
     * @param string|null $reason            The reason for performing the status change
611
     * @param User        $user              The user affected
612
     * @param string      $toolAdminUsername The tool admin's username who is making the edit
613
     */
614
    private function sendStatusChangeEmail($subject, $template, $reason, $user, $toolAdminUsername)
615
    {
616
        $this->assign('targetUsername', $user->getUsername());
617
        $this->assign('toolAdmin', $toolAdminUsername);
618
        $this->assign('actionReason', $reason);
619
        $this->assign('mailingList', $this->adminMailingList);
620
621
        // FIXME: domains!
622
        /** @var Domain $domain */
623
        $domain = Domain::getById(1, $this->getDatabase());
0 ignored issues
show
Unused Code introduced by
The assignment to $domain is dead and can be removed.
Loading history...
624
        $this->getEmailHelper()->sendMail(
625
            $this->adminMailingList,
626
            $user->getEmail(),
627
            $subject,
628
            $this->fetchTemplate($template)
629
        );
630
    }
631
632
    /**
633
     * @param UserRole[] $activeRoles
634
     *
635
     * @return array
636
     */
637
    private function getRoleData($activeRoles)
638
    {
639
        $availableRoles = $this->getSecurityManager()->getAvailableRoles();
640
641
        $currentUser = User::getCurrent($this->getDatabase());
642
        $this->getSecurityManager()->getActiveRoles($currentUser, $userRoles, $inactiveRoles);
643
644
        $initialValue = array('active' => 0, 'allowEdit' => 0, 'description' => '???', 'object' => null);
645
646
        $roleData = array();
647
        foreach ($availableRoles as $role => $data) {
648
            $intersection = array_intersect($data['editableBy'], $userRoles);
649
650
            $roleData[$role] = $initialValue;
651
            $roleData[$role]['allowEdit'] = count($intersection) > 0 ? 1 : 0;
652
            $roleData[$role]['description'] = $data['description'];
653
            $roleData[$role]['globalOnly'] = $data['globalOnly'];
654
        }
655
656
        foreach ($activeRoles as $role) {
657
            if (!isset($roleData[$role->getRole()])) {
658
                // This value is no longer available in the configuration, allow changing (aka removing) it.
659
                $roleData[$role->getRole()] = $initialValue;
660
                $roleData[$role->getRole()]['allowEdit'] = 1;
661
            }
662
663
            $roleData[$role->getRole()]['object'] = $role;
664
            $roleData[$role->getRole()]['active'] = 1;
665
        }
666
667
        return $roleData;
668
    }
669
}
670