Test Setup Failed
Push — master ( 2084e1...65ae38 )
by
unknown
03:39
created

PageUserManagement::editRoles()   F

Complexity

Conditions 21
Paths 1433

Size

Total Lines 124
Code Lines 72

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 462

Importance

Changes 0
Metric Value
eloc 72
dl 0
loc 124
ccs 0
cts 64
cp 0
rs 0
c 0
b 0
f 0
cc 21
nc 1433
nop 0
crap 462

How to fix   Long Method    Complexity   

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

542
            if ($this->validateUnusedEmail($newEmail, /** @scrutinizer ignore-type */ $userId)) {
Loading history...
543
                throw new ApplicationLogicException('The specified email address is already in use.');
544
            }
545
546
            if (!($oauth->isFullyLinked() || $oauth->isPartiallyLinked())) {
547
                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

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