Passed
Push — master ( da9c6d...70f855 )
by
unknown
17:46
created

BackendUserController   B

Complexity

Total Complexity 51

Size/Duplication

Total Lines 564
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 51
eloc 298
dl 0
loc 564
rs 7.92
c 0
b 0
f 0

22 Methods

Rating   Name   Duplication   Size   Complexity  
A compareGroupsAction() 0 31 4
A addMainMenu() 0 48 4
A getRequest() 0 3 1
A indexAction() 0 53 4
A initializeAction() 0 5 1
A initiatePasswordResetAction() 0 25 4
A removeFromCompareListAction() 0 8 2
A __construct() 0 18 1
B processRequest() 0 17 9
A compareAction() 0 34 4
A terminateBackendUserSessionAction() 0 8 2
A onlineAction() 0 28 2
A removeAllFromCompareListAction() 0 5 1
A getBackendUser() 0 3 1
A removeAllGroupsFromCompareListAction() 0 6 1
A addGroupToCompareListAction() 0 8 1
A addToCompareListAction() 0 5 1
A groupsAction() 0 37 2
A initializeView() 0 11 1
A getOnlineBackendUsers() 0 8 2
A removeGroupFromCompareListAction() 0 12 2
A showAction() 0 36 1

How to fix   Complexity   

Complex Class

Complex classes like BackendUserController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use BackendUserController, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/*
4
 * This file is part of the TYPO3 CMS project.
5
 *
6
 * It is free software; you can redistribute it and/or modify it under
7
 * the terms of the GNU General Public License, either version 2
8
 * of the License, or any later version.
9
 *
10
 * For the full copyright and license information, please read the
11
 * LICENSE.txt file that was distributed with this source code.
12
 *
13
 * The TYPO3 project - inspiring people to share!
14
 */
15
16
namespace TYPO3\CMS\Beuser\Controller;
17
18
use Psr\Http\Message\ResponseInterface;
19
use Psr\Http\Message\ServerRequestInterface;
20
use TYPO3\CMS\Backend\Authentication\PasswordReset;
21
use TYPO3\CMS\Backend\Routing\UriBuilder as BackendUriBuilder;
22
use TYPO3\CMS\Backend\Template\Components\ButtonBar;
23
use TYPO3\CMS\Backend\Template\ModuleTemplate;
24
use TYPO3\CMS\Backend\Template\ModuleTemplateFactory;
25
use TYPO3\CMS\Beuser\Domain\Model\BackendUser;
26
use TYPO3\CMS\Beuser\Domain\Model\Demand;
27
use TYPO3\CMS\Beuser\Domain\Model\ModuleData;
28
use TYPO3\CMS\Beuser\Domain\Repository\BackendUserGroupRepository;
29
use TYPO3\CMS\Beuser\Domain\Repository\BackendUserRepository;
30
use TYPO3\CMS\Beuser\Domain\Repository\BackendUserSessionRepository;
31
use TYPO3\CMS\Beuser\Service\UserInformationService;
32
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
33
use TYPO3\CMS\Core\Context\Context;
34
use TYPO3\CMS\Core\Imaging\Icon;
35
use TYPO3\CMS\Core\Imaging\IconFactory;
36
use TYPO3\CMS\Core\Messaging\FlashMessage;
37
use TYPO3\CMS\Core\Page\PageRenderer;
38
use TYPO3\CMS\Core\Pagination\SimplePagination;
39
use TYPO3\CMS\Core\Utility\GeneralUtility;
40
use TYPO3\CMS\Extbase\Http\ForwardResponse;
41
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
42
use TYPO3\CMS\Extbase\Mvc\Exception\StopActionException;
43
use TYPO3\CMS\Extbase\Mvc\Request;
44
use TYPO3\CMS\Extbase\Mvc\RequestInterface;
45
use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
46
use TYPO3\CMS\Extbase\Pagination\QueryResultPaginator;
47
use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
48
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
49
50
/**
51
 * Backend module user and user group administration controller
52
 * @internal This class is a TYPO3 Backend implementation and is not considered part of the Public TYPO3 API.
53
 */
54
class BackendUserController extends ActionController
55
{
56
    protected ?ModuleData $moduleData = null;
57
    protected ?ModuleTemplate $moduleTemplate = null;
58
    protected BackendUserRepository $backendUserRepository;
59
    protected BackendUserGroupRepository $backendUserGroupRepository;
60
    protected BackendUserSessionRepository $backendUserSessionRepository;
61
    protected UserInformationService $userInformationService;
62
    protected ModuleTemplateFactory $moduleTemplateFactory;
63
    protected BackendUriBuilder $backendUriBuilder;
64
    protected IconFactory $iconFactory;
65
    protected PageRenderer $pageRenderer;
66
67
    public function __construct(
68
        BackendUserRepository $backendUserRepository,
69
        BackendUserGroupRepository $backendUserGroupRepository,
70
        BackendUserSessionRepository $backendUserSessionRepository,
71
        UserInformationService $userInformationService,
72
        ModuleTemplateFactory $moduleTemplateFactory,
73
        BackendUriBuilder $backendUriBuilder,
74
        IconFactory $iconFactory,
75
        PageRenderer $pageRenderer
76
    ) {
77
        $this->backendUserRepository = $backendUserRepository;
78
        $this->backendUserGroupRepository = $backendUserGroupRepository;
79
        $this->backendUserSessionRepository = $backendUserSessionRepository;
80
        $this->userInformationService = $userInformationService;
81
        $this->moduleTemplateFactory = $moduleTemplateFactory;
82
        $this->backendUriBuilder = $backendUriBuilder;
83
        $this->iconFactory = $iconFactory;
84
        $this->pageRenderer = $pageRenderer;
85
    }
86
87
    /**
88
     * Override the default action if found in user uc
89
     *
90
     * @param RequestInterface $request
91
     * @return ResponseInterface
92
     */
93
    public function processRequest(RequestInterface $request): ResponseInterface
94
    {
95
        $arguments = $request->getArguments();
96
        $backendUser = $this->getBackendUser();
97
        if (is_array($arguments) && isset($arguments['action']) && in_array((string)$arguments['action'], ['index', 'groups', 'online'])
98
            && (string)($backendUser->uc['beuser']['defaultAction'] ?? '') !== (string)$arguments['action']
99
        ) {
100
            $backendUser->uc['beuser']['defaultAction'] = (string)$arguments['action'];
101
            $backendUser->writeUC();
102
        } elseif (!isset($arguments['action']) && isset($backendUser->uc['beuser']['defaultAction'])
103
            && in_array((string)$backendUser->uc['beuser']['defaultAction'], ['index', 'groups', 'online'])
104
        ) {
105
            if ($request instanceof Request) {
106
                $request->setControllerActionName((string)$backendUser->uc['beuser']['defaultAction']);
107
            }
108
        }
109
        return parent::processRequest($request);
110
    }
111
112
    /**
113
     * Init module state.
114
     * This isn't done within __construct() since the controller
115
     * object is only created once in extbase when multiple actions are called in
116
     * one call. When those change module state, the second action would see old state.
117
     */
118
    public function initializeAction(): void
119
    {
120
        $this->moduleData = ModuleData::fromUc((array)($this->getBackendUser()->getModuleData('tx_beuser')));
121
        $this->moduleTemplate = $this->moduleTemplateFactory->create($this->getRequest());
122
        $this->moduleTemplate->setTitle(LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod.xlf:mlang_tabs_tab'));
123
    }
124
125
    /**
126
     * Assign default variables to view
127
     * @param ViewInterface $view
128
     */
129
    protected function initializeView(ViewInterface $view): void
130
    {
131
        $view->assignMultiple([
132
            'dateFormat' => $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'],
133
            'timeFormat' => $GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'],
134
        ]);
135
136
        // Load requireJS modules
137
        $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/ContextMenu');
138
        $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Modal');
139
        $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Beuser/BackendUserListing');
140
    }
141
142
    /**
143
     * Displays all BackendUsers
144
     *
145
     * @param Demand|null $demand
146
     * @param int $currentPage
147
     * @param string $operation
148
     * @return ResponseInterface
149
     */
150
    public function indexAction(Demand $demand = null, int $currentPage = 1, string $operation = ''): ResponseInterface
151
    {
152
        $backendUser = $this->getBackendUser();
153
154
        if ($operation === 'reset-filters') {
155
            // Reset the module data demand object
156
            $this->moduleData->setDemand(new Demand());
0 ignored issues
show
Bug introduced by
The method setDemand() does not exist on null. ( Ignorable by Annotation )

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

156
            $this->moduleData->/** @scrutinizer ignore-call */ 
157
                               setDemand(new Demand());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
157
            $demand = null;
158
        }
159
        if ($demand === null) {
160
            $demand = $this->moduleData->getDemand();
161
        } else {
162
            $this->moduleData->setDemand($demand);
163
        }
164
        $backendUser->pushModuleData('tx_beuser', $this->moduleData->forUc());
165
166
        $compareUserList = $this->moduleData->getCompareUserList();
167
        $backendUsers = $this->backendUserRepository->findDemanded($demand);
168
        $paginator = new QueryResultPaginator($backendUsers, $currentPage, 50);
169
        $pagination = new SimplePagination($paginator);
170
171
        $this->view->assignMultiple([
172
            'onlineBackendUsers' => $this->getOnlineBackendUsers(),
173
            'demand' => $demand,
174
            'paginator' => $paginator,
175
            'pagination' => $pagination,
176
            'totalAmountOfBackendUsers' => $backendUsers->count(),
177
            'backendUserGroups' => array_merge([''], $this->backendUserGroupRepository->findAll()->toArray()),
178
            'compareUserUidList' => array_combine($compareUserList, $compareUserList),
179
            'currentUserUid' => $backendUser->user['uid'],
180
            'compareUserList' => !empty($compareUserList) ? $this->backendUserRepository->findByUidList($compareUserList) : '',
181
        ]);
182
183
        $this->addMainMenu('index');
184
        $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
0 ignored issues
show
Bug introduced by
The method getDocHeaderComponent() does not exist on null. ( Ignorable by Annotation )

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

184
        $buttonBar = $this->moduleTemplate->/** @scrutinizer ignore-call */ getDocHeaderComponent()->getButtonBar();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
185
        $addUserButton = $buttonBar->makeLinkButton()
186
            ->setIcon($this->iconFactory->getIcon('actions-add', Icon::SIZE_SMALL))
187
            ->setTitle(LocalizationUtility::translate('LLL:EXT:backend/Resources/Private/Language/locallang_layout.xlf:newRecordGeneral'))
188
            ->setHref($this->backendUriBuilder->buildUriFromRoute('record_edit', [
189
                'edit' => ['be_users' => [0 => 'new']],
190
                'returnUrl' => $this->getRequest()->getAttribute('normalizedParams')->getRequestUri()
191
            ]));
192
        $buttonBar->addButton($addUserButton);
193
        $shortcutButton = $buttonBar->makeShortcutButton()
194
            ->setRouteIdentifier('system_BeuserTxBeuser')
195
            ->setArguments(['tx_beuser_system_beusertxbeuser' => ['action' => 'index']])
196
            ->setDisplayName(LocalizationUtility::translate('backendUsers', 'beuser'));
197
        $buttonBar->addButton($shortcutButton, ButtonBar::BUTTON_POSITION_RIGHT);
198
199
        $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/SwitchUser');
200
201
        $this->moduleTemplate->setContent($this->view->render());
202
        return $this->htmlResponse($this->moduleTemplate->renderContent());
203
    }
204
205
    /**
206
     * Views all currently logged in BackendUsers and their sessions
207
     */
208
    public function onlineAction(): ResponseInterface
209
    {
210
        $onlineUsersAndSessions = [];
211
        $onlineUsers = $this->backendUserRepository->findOnline();
212
        foreach ($onlineUsers as $onlineUser) {
213
            $onlineUsersAndSessions[] = [
214
                'backendUser' => $onlineUser,
215
                'sessions' => $this->backendUserSessionRepository->findByBackendUser($onlineUser)
216
            ];
217
        }
218
219
        $currentSessionId = $this->backendUserSessionRepository->getPersistedSessionIdentifier($this->getBackendUser());
220
221
        $this->view->assignMultiple([
222
            'onlineUsersAndSessions' => $onlineUsersAndSessions,
223
            'currentSessionId' => $currentSessionId,
224
        ]);
225
226
        $this->addMainMenu('online');
227
        $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
228
        $shortcutButton = $buttonBar->makeShortcutButton()
229
            ->setRouteIdentifier('system_BeuserTxBeuser')
230
            ->setArguments(['tx_beuser_system_beusertxbeuser' => ['action' => 'online']])
231
            ->setDisplayName(LocalizationUtility::translate('onlineUsers', 'beuser'));
232
        $buttonBar->addButton($shortcutButton, ButtonBar::BUTTON_POSITION_RIGHT);
233
234
        $this->moduleTemplate->setContent($this->view->render());
235
        return $this->htmlResponse($this->moduleTemplate->renderContent());
236
    }
237
238
    public function showAction(int $uid = 0): ResponseInterface
239
    {
240
        $data = $this->userInformationService->getUserInformation($uid);
241
        $this->view->assign('data', $data);
242
243
        $this->addMainMenu('show');
244
        $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
245
        $backButton = $buttonBar->makeLinkButton()
246
            ->setIcon($this->iconFactory->getIcon('actions-view-go-back', Icon::SIZE_SMALL))
247
            ->setTitle(LocalizationUtility::translate('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.goBack'))
248
            ->setHref($this->backendUriBuilder->buildUriFromRoute('system_BeuserTxBeuser'));
249
        $buttonBar->addButton($backButton);
250
        $editButton = $buttonBar->makeLinkButton()
251
            ->setIcon($this->iconFactory->getIcon('actions-open', Icon::SIZE_SMALL))
252
            ->setTitle(LocalizationUtility::translate('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.goBack'))
253
            ->setHref($this->backendUriBuilder->buildUriFromRoute('record_edit', [
254
                'edit' => ['be_users' => [$uid => 'edit']],
255
                'returnUrl' => $this->getRequest()->getAttribute('normalizedParams')->getRequestUri()
256
            ]));
257
        $buttonBar->addButton($editButton);
258
        $addUserButton = $buttonBar->makeLinkButton()
259
            ->setIcon($this->iconFactory->getIcon('actions-add', Icon::SIZE_SMALL))
260
            ->setTitle(LocalizationUtility::translate('LLL:EXT:backend/Resources/Private/Language/locallang_layout.xlf:newRecordGeneral'))
261
            ->setHref($this->backendUriBuilder->buildUriFromRoute('record_edit', [
262
                'edit' => ['be_users' => [0 => 'new']],
263
                'returnUrl' => $this->getRequest()->getAttribute('normalizedParams')->getRequestUri()
264
            ]));
265
        $buttonBar->addButton($addUserButton);
266
        $shortcutButton = $buttonBar->makeShortcutButton()
267
            ->setRouteIdentifier('system_BeuserTxBeuser')
268
            ->setArguments(['tx_beuser_system_beusertxbeuser' => ['action' => 'show', 'uid' => $uid]])
269
            ->setDisplayName(LocalizationUtility::translate('backendUser', 'beuser') . ': ' . (string)$data['user']['username']);
270
        $buttonBar->addButton($shortcutButton, ButtonBar::BUTTON_POSITION_RIGHT);
271
272
        $this->moduleTemplate->setContent($this->view->render());
273
        return $this->htmlResponse($this->moduleTemplate->renderContent());
274
    }
275
276
    /**
277
     * Compare backend users from demand
278
     */
279
    public function compareAction(): ResponseInterface
280
    {
281
        $compareUserList = $this->moduleData->getCompareUserList();
282
        if (empty($compareUserList)) {
283
            $this->redirect('index');
284
        }
285
286
        $compareData = [];
287
        foreach ($compareUserList as $uid) {
288
            if ($compareInformation = $this->userInformationService->getUserInformation($uid)) {
289
                $compareData[] = $compareInformation;
290
            }
291
        }
292
293
        $this->view->assignMultiple([
294
            'compareUserList' => $compareData,
295
            'onlineBackendUsers' => $this->getOnlineBackendUsers()
296
        ]);
297
298
        $this->addMainMenu('compare');
299
        $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
300
        $backButton = $buttonBar->makeLinkButton()
301
            ->setIcon($this->iconFactory->getIcon('actions-view-go-back', Icon::SIZE_SMALL))
302
            ->setTitle(LocalizationUtility::translate('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.goBack'))
303
            ->setHref($this->backendUriBuilder->buildUriFromRoute('system_BeuserTxBeuser'));
304
        $buttonBar->addButton($backButton);
305
        $shortcutButton = $buttonBar->makeShortcutButton()
306
            ->setRouteIdentifier('system_BeuserTxBeuser')
307
            ->setArguments(['tx_beuser_system_beusertxbeuser' => ['action' => 'compare']])
308
            ->setDisplayName(LocalizationUtility::translate('compareUsers', 'beuser'));
309
        $buttonBar->addButton($shortcutButton, ButtonBar::BUTTON_POSITION_RIGHT);
310
311
        $this->moduleTemplate->setContent($this->view->render());
312
        return $this->htmlResponse($this->moduleTemplate->renderContent());
313
    }
314
315
    /**
316
     * Starts the password reset process for a selected user.
317
     *
318
     * @param int $user
319
     */
320
    public function initiatePasswordResetAction(int $user): ResponseInterface
321
    {
322
        $context = GeneralUtility::makeInstance(Context::class);
323
        /** @var BackendUser $user */
324
        $user = $this->backendUserRepository->findByUid($user);
0 ignored issues
show
Bug introduced by
$user of type TYPO3\CMS\Beuser\Domain\Model\BackendUser is incompatible with the type integer expected by parameter $uid of TYPO3\CMS\Extbase\Persis...Repository::findByUid(). ( Ignorable by Annotation )

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

324
        $user = $this->backendUserRepository->findByUid(/** @scrutinizer ignore-type */ $user);
Loading history...
325
        if (!$user || !$user->isPasswordResetEnabled() || !$context->getAspect('backend.user')->isAdmin()) {
0 ignored issues
show
introduced by
$user is of type TYPO3\CMS\Beuser\Domain\Model\BackendUser, thus it always evaluated to true.
Loading history...
326
            // Add an error message
327
            $this->addFlashMessage(
328
                LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang.xlf:flashMessage.resetPassword.error.text', 'beuser') ?? '',
329
                LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang.xlf:flashMessage.resetPassword.error.title', 'beuser') ?? '',
330
                FlashMessage::ERROR
331
            );
332
        } else {
333
            GeneralUtility::makeInstance(PasswordReset::class)->initiateReset(
334
                $this->getRequest(),
335
                $context,
336
                $user->getEmail()
337
            );
338
            $this->addFlashMessage(
339
                LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang.xlf:flashMessage.resetPassword.success.text', 'beuser', [$user->getEmail()]) ?? '',
340
                LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang.xlf:flashMessage.resetPassword.success.title', 'beuser') ?? '',
341
                FlashMessage::OK
342
            );
343
        }
344
        return new ForwardResponse('index');
345
    }
346
347
    /**
348
     * Attaches one backend user to the compare list
349
     *
350
     * @param int $uid
351
     */
352
    public function addToCompareListAction($uid): ResponseInterface
353
    {
354
        $this->moduleData->attachUidCompareUser($uid);
355
        $this->getBackendUser()->pushModuleData('tx_beuser', $this->moduleData->forUc());
356
        return new ForwardResponse('index');
357
    }
358
359
    /**
360
     * Removes given backend user to the compare list
361
     *
362
     * @param int $uid
363
     * @param int $redirectToCompare
364
     */
365
    public function removeFromCompareListAction($uid, int $redirectToCompare = 0): void
366
    {
367
        $this->moduleData->detachUidCompareUser($uid);
368
        $this->getBackendUser()->pushModuleData('tx_beuser', $this->moduleData->forUc());
369
        if ($redirectToCompare) {
370
            $this->redirect('compare');
371
        } else {
372
            $this->redirect('index');
373
        }
374
    }
375
376
    /**
377
     * Removes all backend users from the compare list
378
     * @throws StopActionException
379
     */
380
    public function removeAllFromCompareListAction(): void
381
    {
382
        $this->moduleData->resetCompareUserList();
383
        $this->getBackendUser()->pushModuleData('tx_beuser', $this->moduleData->forUc());
384
        $this->redirect('index');
385
    }
386
387
    /**
388
     * Terminate BackendUser session and logout corresponding client
389
     * Redirects to onlineAction with message
390
     *
391
     * @param string $sessionId
392
     */
393
    protected function terminateBackendUserSessionAction($sessionId): ResponseInterface
394
    {
395
        // terminating value of persisted session ID
396
        $success = $this->backendUserSessionRepository->terminateSessionByIdentifier($sessionId);
397
        if ($success) {
398
            $this->addFlashMessage(LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang.xlf:terminateSessionSuccess', 'beuser') ?? '');
399
        }
400
        return new ForwardResponse('online');
401
    }
402
403
    /**
404
     * Displays all BackendUserGroups
405
     *
406
     * @param int $currentPage
407
     * @return ResponseInterface
408
     */
409
    public function groupsAction(int $currentPage = 1): ResponseInterface
410
    {
411
        /** @var QueryResultInterface $backendUsers */
412
        $backendUsers = $this->backendUserGroupRepository->findAll();
413
        $paginator = new QueryResultPaginator($backendUsers, $currentPage, 50);
414
        $pagination = new SimplePagination($paginator);
415
        $compareGroupUidList = array_keys($this->getBackendUser()->uc['beuser']['compareGroupUidList'] ?? []);
416
        $this->view->assignMultiple(
417
            [
418
                'paginator' => $paginator,
419
                'pagination' => $pagination,
420
                'totalAmountOfBackendUserGroups' => $backendUsers->count(),
421
                'compareGroupUidList' => array_map(static function ($value) { // uid as key and force value to 1
422
                    return 1;
423
                }, array_flip($compareGroupUidList)),
424
                'compareGroupList' => !empty($compareGroupUidList) ? $this->backendUserGroupRepository->findByUidList($compareGroupUidList) : [],
425
            ]
426
        );
427
428
        $this->addMainMenu('groups');
429
        $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
430
        $addGroupButton = $buttonBar->makeLinkButton()
431
            ->setIcon($this->iconFactory->getIcon('actions-add', Icon::SIZE_SMALL))
432
            ->setTitle(LocalizationUtility::translate('LLL:EXT:backend/Resources/Private/Language/locallang_layout.xlf:newRecordGeneral'))
433
            ->setHref($this->backendUriBuilder->buildUriFromRoute('record_edit', [
434
                'edit' => ['be_groups' => [0 => 'new']],
435
                'returnUrl' => $this->getRequest()->getAttribute('normalizedParams')->getRequestUri()
436
            ]));
437
        $buttonBar->addButton($addGroupButton);
438
        $shortcutButton = $buttonBar->makeShortcutButton()
439
            ->setRouteIdentifier('system_BeuserTxBeuser')
440
            ->setArguments(['tx_beuser_system_beusertxbeuser' => ['action' => 'groups']])
441
            ->setDisplayName(LocalizationUtility::translate('backendUserGroupsMenu', 'beuser'));
442
        $buttonBar->addButton($shortcutButton, ButtonBar::BUTTON_POSITION_RIGHT);
443
444
        $this->moduleTemplate->setContent($this->view->render());
445
        return $this->htmlResponse($this->moduleTemplate->renderContent());
446
    }
447
448
    public function compareGroupsAction(): ResponseInterface
449
    {
450
        $compareGroupUidList = array_keys($this->getBackendUser()->uc['beuser']['compareGroupUidList'] ?? []);
451
452
        $compareData = [];
453
        foreach ($compareGroupUidList as $uid) {
454
            if ($compareInformation = $this->userInformationService->getGroupInformation($uid)) {
455
                $compareData[] = $compareInformation;
456
            }
457
        }
458
        if (empty($compareData)) {
459
            $this->redirect('groups');
460
        }
461
462
        $this->view->assign('compareGroupList', $compareData);
463
464
        $this->addMainMenu('compareGroups');
465
        $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
466
        $backButton = $buttonBar->makeLinkButton()
467
            ->setIcon($this->iconFactory->getIcon('actions-view-go-back', Icon::SIZE_SMALL))
468
            ->setTitle(LocalizationUtility::translate('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.goBack'))
469
            ->setHref($this->uriBuilder->uriFor('groups'));
470
        $buttonBar->addButton($backButton);
471
        $shortcutButton = $buttonBar->makeShortcutButton()
472
            ->setRouteIdentifier('system_BeuserTxBeuser')
473
            ->setArguments(['tx_beuser_system_beusertxbeuser' => ['action' => 'compareGroups']])
474
            ->setDisplayName(LocalizationUtility::translate('compareBackendUsersGroups', 'beuser'));
475
        $buttonBar->addButton($shortcutButton, ButtonBar::BUTTON_POSITION_RIGHT);
476
477
        $this->moduleTemplate->setContent($this->view->render());
478
        return $this->htmlResponse($this->moduleTemplate->renderContent());
479
    }
480
481
    /**
482
     * Attaches one backend user group to the compare list
483
     *
484
     * @param int $uid
485
     */
486
    public function addGroupToCompareListAction(int $uid): void
487
    {
488
        $backendUser = $this->getBackendUser();
489
        $list = $backendUser->uc['beuser']['compareGroupUidList'] ?? [];
490
        $list[$uid] = true;
491
        $backendUser->uc['beuser']['compareGroupUidList'] = $list;
492
        $backendUser->writeUC();
493
        $this->redirect('groups');
494
    }
495
496
    /**
497
     * Removes given backend user group to the compare list
498
     *
499
     * @param int $uid
500
     * @param int $redirectToCompare
501
     */
502
    public function removeGroupFromCompareListAction(int $uid, int $redirectToCompare = 0): void
503
    {
504
        $backendUser = $this->getBackendUser();
505
        $list = $backendUser->uc['beuser']['compareGroupUidList'] ?? [];
506
        unset($list[$uid]);
507
        $backendUser->uc['beuser']['compareGroupUidList'] = $list;
508
        $backendUser->writeUC();
509
510
        if ($redirectToCompare) {
511
            $this->redirect('compareGroups');
512
        } else {
513
            $this->redirect('groups');
514
        }
515
    }
516
517
    /**
518
     * Removes all backend user groups from the compare list
519
     */
520
    public function removeAllGroupsFromCompareListAction(): void
521
    {
522
        $backendUser = $this->getBackendUser();
523
        $backendUser->uc['beuser']['compareGroupUidList'] = [];
524
        $backendUser->writeUC();
525
        $this->redirect('groups');
526
    }
527
528
    /**
529
     * Create an array with the uids of online users as the keys
530
     * [
531
     *   1 => true,
532
     *   5 => true
533
     * ]
534
     * @return array
535
     */
536
    protected function getOnlineBackendUsers(): array
537
    {
538
        $onlineUsers = $this->backendUserSessionRepository->findAllActive();
539
        $onlineBackendUsers = [];
540
        foreach ($onlineUsers as $onlineUser) {
541
            $onlineBackendUsers[$onlineUser['ses_userid']] = true;
542
        }
543
        return $onlineBackendUsers;
544
    }
545
546
    /**
547
     * Doc header main drop down
548
     *
549
     * @param string $currentAction
550
     */
551
    protected function addMainMenu(string $currentAction): void
552
    {
553
        $this->uriBuilder->setRequest($this->request);
554
        $menu = $this->moduleTemplate->getDocHeaderComponent()->getMenuRegistry()->makeMenu();
555
        $menu->setIdentifier('BackendUserModuleMenu');
556
        $menu->addMenuItem(
557
            $menu->makeMenuItem()
558
            ->setTitle(LocalizationUtility::translate('backendUsers', 'beuser'))
559
            ->setHref($this->uriBuilder->uriFor('index'))
560
            ->setActive($currentAction === 'index')
561
        );
562
        if ($currentAction === 'show') {
563
            $menu->addMenuItem(
564
                $menu->makeMenuItem()
565
                ->setTitle(LocalizationUtility::translate('backendUserDetails', 'beuser'))
566
                ->setHref($this->uriBuilder->uriFor('show'))
567
                ->setActive(true)
568
            );
569
        }
570
        if ($currentAction === 'compare') {
571
            $menu->addMenuItem(
572
                $menu->makeMenuItem()
573
                ->setTitle(LocalizationUtility::translate('compareBackendUsers', 'beuser'))
574
                ->setHref($this->uriBuilder->uriFor('index'))
575
                ->setActive(true)
576
            );
577
        }
578
        $menu->addMenuItem(
579
            $menu->makeMenuItem()
580
            ->setTitle(LocalizationUtility::translate('backendUserGroupsMenu', 'beuser'))
581
            ->setHref($this->uriBuilder->uriFor('groups'))
582
            ->setActive($currentAction === 'groups')
583
        );
584
        if ($currentAction === 'compareGroups') {
585
            $menu->addMenuItem(
586
                $menu->makeMenuItem()
587
                ->setTitle(LocalizationUtility::translate('compareBackendUsersGroups', 'beuser'))
588
                ->setHref($this->uriBuilder->uriFor('compareGroups'))
589
                ->setActive(true)
590
            );
591
        }
592
        $menu->addMenuItem(
593
            $menu->makeMenuItem()
594
            ->setTitle(LocalizationUtility::translate('onlineUsers', 'beuser'))
595
            ->setHref($this->uriBuilder->uriFor('online'))
596
            ->setActive($currentAction === 'online')
597
        );
598
        $this->moduleTemplate->getDocHeaderComponent()->getMenuRegistry()->addMenu($menu);
599
    }
600
601
    /**
602
     * @return BackendUserAuthentication
603
     */
604
    protected function getBackendUser(): BackendUserAuthentication
605
    {
606
        return $GLOBALS['BE_USER'];
607
    }
608
609
    /**
610
     * This is a temporary hack to receive the PSR-7 request until extbase
611
     * provides a PSR-7 compatible request in actions.
612
     *
613
     * @return ServerRequestInterface
614
     */
615
    protected function getRequest(): ServerRequestInterface
616
    {
617
        return $GLOBALS['TYPO3_REQUEST'];
618
    }
619
}
620