Passed
Push — master ( 6c08ab...5a4560 )
by
unknown
34:08 queued 20:19
created

BackendUserController::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 8
dl 0
loc 18
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 8

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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\Event\SwitchUserEvent;
21
use TYPO3\CMS\Backend\Authentication\PasswordReset;
22
use TYPO3\CMS\Backend\Routing\UriBuilder as BackendUriBuilder;
23
use TYPO3\CMS\Backend\Template\Components\ButtonBar;
24
use TYPO3\CMS\Backend\Template\ModuleTemplate;
25
use TYPO3\CMS\Backend\Template\ModuleTemplateFactory;
26
use TYPO3\CMS\Backend\Utility\BackendUtility;
27
use TYPO3\CMS\Beuser\Domain\Model\BackendUser;
28
use TYPO3\CMS\Beuser\Domain\Model\Demand;
29
use TYPO3\CMS\Beuser\Domain\Model\ModuleData;
30
use TYPO3\CMS\Beuser\Domain\Repository\BackendUserGroupRepository;
31
use TYPO3\CMS\Beuser\Domain\Repository\BackendUserRepository;
32
use TYPO3\CMS\Beuser\Domain\Repository\BackendUserSessionRepository;
33
use TYPO3\CMS\Beuser\Service\UserInformationService;
34
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
35
use TYPO3\CMS\Core\Context\Context;
36
use TYPO3\CMS\Core\Http\PropagateResponseException;
37
use TYPO3\CMS\Core\Http\RedirectResponse;
38
use TYPO3\CMS\Core\Imaging\Icon;
39
use TYPO3\CMS\Core\Imaging\IconFactory;
40
use TYPO3\CMS\Core\Messaging\FlashMessage;
41
use TYPO3\CMS\Core\Page\PageRenderer;
42
use TYPO3\CMS\Core\Pagination\SimplePagination;
43
use TYPO3\CMS\Core\Utility\GeneralUtility;
44
use TYPO3\CMS\Extbase\Http\ForwardResponse;
45
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
46
use TYPO3\CMS\Extbase\Mvc\Exception\StopActionException;
47
use TYPO3\CMS\Extbase\Mvc\Request;
48
use TYPO3\CMS\Extbase\Mvc\RequestInterface;
49
use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
50
use TYPO3\CMS\Extbase\Pagination\QueryResultPaginator;
51
use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
52
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
53
54
/**
55
 * Backend module user and user group administration controller
56
 * @internal This class is a TYPO3 Backend implementation and is not considered part of the Public TYPO3 API.
57
 */
58
class BackendUserController extends ActionController
59
{
60
    /**
61
     * @var int
62
     */
63
    const RECENT_USERS_LIMIT = 3;
64
65
    protected ?ModuleData $moduleData = null;
66
    protected ?ModuleTemplate $moduleTemplate = null;
67
    protected BackendUserRepository $backendUserRepository;
68
    protected BackendUserGroupRepository $backendUserGroupRepository;
69
    protected BackendUserSessionRepository $backendUserSessionRepository;
70
    protected UserInformationService $userInformationService;
71
    protected ModuleTemplateFactory $moduleTemplateFactory;
72
    protected BackendUriBuilder $backendUriBuilder;
73
    protected IconFactory $iconFactory;
74
    protected PageRenderer $pageRenderer;
75
76
    public function __construct(
77
        BackendUserRepository $backendUserRepository,
78
        BackendUserGroupRepository $backendUserGroupRepository,
79
        BackendUserSessionRepository $backendUserSessionRepository,
80
        UserInformationService $userInformationService,
81
        ModuleTemplateFactory $moduleTemplateFactory,
82
        BackendUriBuilder $backendUriBuilder,
83
        IconFactory $iconFactory,
84
        PageRenderer $pageRenderer
85
    ) {
86
        $this->backendUserRepository = $backendUserRepository;
87
        $this->backendUserGroupRepository = $backendUserGroupRepository;
88
        $this->backendUserSessionRepository = $backendUserSessionRepository;
89
        $this->userInformationService = $userInformationService;
90
        $this->moduleTemplateFactory = $moduleTemplateFactory;
91
        $this->backendUriBuilder = $backendUriBuilder;
92
        $this->iconFactory = $iconFactory;
93
        $this->pageRenderer = $pageRenderer;
94
    }
95
96
    /**
97
     * Override the default action if found in user uc
98
     *
99
     * @param RequestInterface $request
100
     * @return ResponseInterface
101
     */
102
    public function processRequest(RequestInterface $request): ResponseInterface
103
    {
104
        $arguments = $request->getArguments();
105
        $backendUser = $this->getBackendUser();
106
        if (is_array($arguments) && isset($arguments['action']) && in_array((string)$arguments['action'], ['index', 'groups', 'online'])
107
            && (string)($backendUser->uc['beuser']['defaultAction'] ?? '') !== (string)$arguments['action']
108
        ) {
109
            $backendUser->uc['beuser']['defaultAction'] = (string)$arguments['action'];
110
            $backendUser->writeUC();
111
        } elseif (!isset($arguments['action']) && isset($backendUser->uc['beuser']['defaultAction'])
112
            && in_array((string)$backendUser->uc['beuser']['defaultAction'], ['index', 'groups', 'online'])
113
        ) {
114
            if ($request instanceof Request) {
115
                $request->setControllerActionName((string)$backendUser->uc['beuser']['defaultAction']);
116
            }
117
        }
118
        return parent::processRequest($request);
119
    }
120
121
    /**
122
     * Init module state.
123
     * This isn't done within __construct() since the controller
124
     * object is only created once in extbase when multiple actions are called in
125
     * one call. When those change module state, the second action would see old state.
126
     */
127
    public function initializeAction(): void
128
    {
129
        $this->moduleData = ModuleData::fromUc((array)($this->getBackendUser()->getModuleData('tx_beuser')));
130
        $this->moduleTemplate = $this->moduleTemplateFactory->create($this->getRequest());
131
        $this->moduleTemplate->setTitle(LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod.xlf:mlang_tabs_tab'));
132
    }
133
134
    /**
135
     * Assign default variables to view
136
     * @param ViewInterface $view
137
     */
138
    protected function initializeView(ViewInterface $view): void
139
    {
140
        $view->assignMultiple([
141
            'dateFormat' => $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'],
142
            'timeFormat' => $GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'],
143
        ]);
144
145
        // Load requireJS modules
146
        $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/ContextMenu');
147
        $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Modal');
148
        $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Beuser/BackendUserListing');
149
    }
150
151
    /**
152
     * Displays all BackendUsers
153
     * - Switch session to different user
154
     *
155
     * @param Demand|null $demand
156
     * @param int $currentPage
157
     * @param string $operation
158
     * @return ResponseInterface
159
     */
160
    public function indexAction(Demand $demand = null, int $currentPage = 1, string $operation = ''): ResponseInterface
161
    {
162
        $backendUser = $this->getBackendUser();
163
164
        if ($operation === 'reset-filters') {
165
            // Reset the module data demand object
166
            $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

166
            $this->moduleData->/** @scrutinizer ignore-call */ 
167
                               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...
167
            $demand = null;
168
        }
169
        if ($demand === null) {
170
            $demand = $this->moduleData->getDemand();
171
        } else {
172
            $this->moduleData->setDemand($demand);
173
        }
174
        $backendUser->pushModuleData('tx_beuser', $this->moduleData->forUc());
175
176
        // Switch user until logout
177
        $switchUser = (int)GeneralUtility::_GP('SwitchUser');
178
        if ($switchUser > 0) {
179
            $this->switchUser($switchUser);
180
        }
181
        $compareUserList = $this->moduleData->getCompareUserList();
182
183
        $backendUsers = $this->backendUserRepository->findDemanded($demand);
184
        $paginator = new QueryResultPaginator($backendUsers, $currentPage, 50);
185
        $pagination = new SimplePagination($paginator);
186
187
        $this->view->assignMultiple([
188
            'onlineBackendUsers' => $this->getOnlineBackendUsers(),
189
            'demand' => $demand,
190
            'paginator' => $paginator,
191
            'pagination' => $pagination,
192
            'totalAmountOfBackendUsers' => $backendUsers->count(),
193
            'backendUserGroups' => array_merge([''], $this->backendUserGroupRepository->findAll()->toArray()),
194
            'compareUserUidList' => array_combine($compareUserList, $compareUserList),
195
            'currentUserUid' => $backendUser->user['uid'],
196
            'compareUserList' => !empty($compareUserList) ? $this->backendUserRepository->findByUidList($compareUserList) : '',
197
        ]);
198
199
        $this->addMainMenu('index');
200
        $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

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

338
        $user = $this->backendUserRepository->findByUid(/** @scrutinizer ignore-type */ $user);
Loading history...
339
        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...
340
            // Add an error message
341
            $this->addFlashMessage(
342
                LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang.xlf:flashMessage.resetPassword.error.text', 'beuser') ?? '',
343
                LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang.xlf:flashMessage.resetPassword.error.title', 'beuser') ?? '',
344
                FlashMessage::ERROR
345
            );
346
        } else {
347
            GeneralUtility::makeInstance(PasswordReset::class)->initiateReset(
348
                $this->getRequest(),
349
                $context,
350
                $user->getEmail()
351
            );
352
            $this->addFlashMessage(
353
                LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang.xlf:flashMessage.resetPassword.success.text', 'beuser', [$user->getEmail()]) ?? '',
354
                LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang.xlf:flashMessage.resetPassword.success.title', 'beuser') ?? '',
355
                FlashMessage::OK
356
            );
357
        }
358
        return new ForwardResponse('index');
359
    }
360
361
    /**
362
     * Attaches one backend user to the compare list
363
     *
364
     * @param int $uid
365
     */
366
    public function addToCompareListAction($uid): ResponseInterface
367
    {
368
        $this->moduleData->attachUidCompareUser($uid);
369
        $this->getBackendUser()->pushModuleData('tx_beuser', $this->moduleData->forUc());
370
        return new ForwardResponse('index');
371
    }
372
373
    /**
374
     * Removes given backend user to the compare list
375
     *
376
     * @param int $uid
377
     * @param int $redirectToCompare
378
     */
379
    public function removeFromCompareListAction($uid, int $redirectToCompare = 0): void
380
    {
381
        $this->moduleData->detachUidCompareUser($uid);
382
        $this->getBackendUser()->pushModuleData('tx_beuser', $this->moduleData->forUc());
383
        if ($redirectToCompare) {
384
            $this->redirect('compare');
385
        } else {
386
            $this->redirect('index');
387
        }
388
    }
389
390
    /**
391
     * Removes all backend users from the compare list
392
     * @throws StopActionException
393
     */
394
    public function removeAllFromCompareListAction(): void
395
    {
396
        $this->moduleData->resetCompareUserList();
397
        $this->getBackendUser()->pushModuleData('tx_beuser', $this->moduleData->forUc());
398
        $this->redirect('index');
399
    }
400
401
    /**
402
     * Terminate BackendUser session and logout corresponding client
403
     * Redirects to onlineAction with message
404
     *
405
     * @param string $sessionId
406
     */
407
    protected function terminateBackendUserSessionAction($sessionId): ResponseInterface
408
    {
409
        // terminating value of persisted session ID
410
        $success = $this->backendUserSessionRepository->terminateSessionByIdentifier($sessionId);
411
        if ($success) {
412
            $this->addFlashMessage(LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang.xlf:terminateSessionSuccess', 'beuser') ?? '');
413
        }
414
        return new ForwardResponse('online');
415
    }
416
417
    /**
418
     * Displays all BackendUserGroups
419
     *
420
     * @param int $currentPage
421
     * @return ResponseInterface
422
     */
423
    public function groupsAction(int $currentPage = 1): ResponseInterface
424
    {
425
        /** @var QueryResultInterface $backendUsers */
426
        $backendUsers = $this->backendUserGroupRepository->findAll();
427
        $paginator = new QueryResultPaginator($backendUsers, $currentPage, 50);
428
        $pagination = new SimplePagination($paginator);
429
        $compareGroupUidList = array_keys($this->getBackendUser()->uc['beuser']['compareGroupUidList'] ?? []);
430
        $this->view->assignMultiple(
431
            [
432
                'paginator' => $paginator,
433
                'pagination' => $pagination,
434
                'totalAmountOfBackendUserGroups' => $backendUsers->count(),
435
                'compareGroupUidList' => array_map(static function ($value) { // uid as key and force value to 1
436
                    return 1;
437
                }, array_flip($compareGroupUidList)),
438
                'compareGroupList' => !empty($compareGroupUidList) ? $this->backendUserGroupRepository->findByUidList($compareGroupUidList) : [],
439
            ]
440
        );
441
442
        $this->addMainMenu('groups');
443
        $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
444
        $addGroupButton = $buttonBar->makeLinkButton()
445
            ->setIcon($this->iconFactory->getIcon('actions-add', Icon::SIZE_SMALL))
446
            ->setTitle(LocalizationUtility::translate('LLL:EXT:backend/Resources/Private/Language/locallang_layout.xlf:newRecordGeneral'))
447
            ->setHref($this->backendUriBuilder->buildUriFromRoute('record_edit', [
448
                'edit' => ['be_groups' => [0 => 'new']],
449
                'returnUrl' => $this->getRequest()->getAttribute('normalizedParams')->getRequestUri()
450
            ]));
451
        $buttonBar->addButton($addGroupButton);
452
        $shortcutButton = $buttonBar->makeShortcutButton()
453
            ->setRouteIdentifier('system_BeuserTxBeuser')
454
            ->setArguments(['tx_beuser_system_beusertxbeuser' => ['action' => 'groups']])
455
            ->setDisplayName(LocalizationUtility::translate('backendUserGroupsMenu', 'beuser'));
456
        $buttonBar->addButton($shortcutButton, ButtonBar::BUTTON_POSITION_RIGHT);
457
458
        $this->moduleTemplate->setContent($this->view->render());
459
        return $this->htmlResponse($this->moduleTemplate->renderContent());
460
    }
461
462
    public function compareGroupsAction(): ResponseInterface
463
    {
464
        $compareGroupUidList = array_keys($this->getBackendUser()->uc['beuser']['compareGroupUidList'] ?? []);
465
466
        $compareData = [];
467
        foreach ($compareGroupUidList as $uid) {
468
            if ($compareInformation = $this->userInformationService->getGroupInformation($uid)) {
469
                $compareData[] = $compareInformation;
470
            }
471
        }
472
        if (empty($compareData)) {
473
            $this->redirect('groups');
474
        }
475
476
        $this->view->assign('compareGroupList', $compareData);
477
478
        $this->addMainMenu('compareGroups');
479
        $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
480
        $backButton = $buttonBar->makeLinkButton()
481
            ->setIcon($this->iconFactory->getIcon('actions-view-go-back', Icon::SIZE_SMALL))
482
            ->setTitle(LocalizationUtility::translate('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.goBack'))
483
            ->setHref($this->uriBuilder->uriFor('groups'));
484
        $buttonBar->addButton($backButton);
485
        $shortcutButton = $buttonBar->makeShortcutButton()
486
            ->setRouteIdentifier('system_BeuserTxBeuser')
487
            ->setArguments(['tx_beuser_system_beusertxbeuser' => ['action' => 'compareGroups']])
488
            ->setDisplayName(LocalizationUtility::translate('compareBackendUsersGroups', 'beuser'));
489
        $buttonBar->addButton($shortcutButton, ButtonBar::BUTTON_POSITION_RIGHT);
490
491
        $this->moduleTemplate->setContent($this->view->render());
492
        return $this->htmlResponse($this->moduleTemplate->renderContent());
493
    }
494
495
    /**
496
     * Attaches one backend user group to the compare list
497
     *
498
     * @param int $uid
499
     */
500
    public function addGroupToCompareListAction(int $uid): void
501
    {
502
        $backendUser = $this->getBackendUser();
503
        $list = $backendUser->uc['beuser']['compareGroupUidList'] ?? [];
504
        $list[$uid] = true;
505
        $backendUser->uc['beuser']['compareGroupUidList'] = $list;
506
        $backendUser->writeUC();
507
        $this->redirect('groups');
508
    }
509
510
    /**
511
     * Removes given backend user group to the compare list
512
     *
513
     * @param int $uid
514
     * @param int $redirectToCompare
515
     */
516
    public function removeGroupFromCompareListAction(int $uid, int $redirectToCompare = 0): void
517
    {
518
        $backendUser = $this->getBackendUser();
519
        $list = $backendUser->uc['beuser']['compareGroupUidList'] ?? [];
520
        unset($list[$uid]);
521
        $backendUser->uc['beuser']['compareGroupUidList'] = $list;
522
        $backendUser->writeUC();
523
524
        if ($redirectToCompare) {
525
            $this->redirect('compareGroups');
526
        } else {
527
            $this->redirect('groups');
528
        }
529
    }
530
531
    /**
532
     * Removes all backend user groups from the compare list
533
     */
534
    public function removeAllGroupsFromCompareListAction(): void
535
    {
536
        $backendUser = $this->getBackendUser();
537
        $backendUser->uc['beuser']['compareGroupUidList'] = [];
538
        $backendUser->writeUC();
539
        $this->redirect('groups');
540
    }
541
542
    /**
543
     * Switches to a given user (SU-mode) and then redirects to the start page of the backend to refresh the navigation etc.
544
     *
545
     * @param int $switchUser BE-user record that will be switched to
546
     */
547
    protected function switchUser($switchUser)
548
    {
549
        $backendUser = $this->getBackendUser();
550
        $targetUser = BackendUtility::getRecord('be_users', $switchUser);
551
        if (is_array($targetUser) && $backendUser->isAdmin()) {
552
            // Set backend user listing module as starting module for switchback
553
            $backendUser->uc['startModuleOnFirstLogin'] = 'system_BeuserTxBeuser';
554
            $backendUser->uc['recentSwitchedToUsers'] = $this->generateListOfMostRecentSwitchedUsers($targetUser['uid']);
555
            $backendUser->writeUC();
556
557
            // User switch   written to log
558
            $backendUser->writelog(
559
                255,
560
                2,
561
                0,
562
                1,
563
                'User %s switched to user %s (be_users:%s)',
564
                [
565
                    $backendUser->user['username'],
566
                    $targetUser['username'],
567
                    $targetUser['uid'],
568
                ]
569
            );
570
571
            $this->backendUserSessionRepository->switchToUser($backendUser, (int)$targetUser['uid']);
572
573
            $event = new SwitchUserEvent(
574
                $backendUser->getSession()->getIdentifier(),
575
                $targetUser,
576
                (array)$backendUser->user
577
            );
578
            $this->eventDispatcher->dispatch($event);
579
580
            $redirectUri = $this->backendUriBuilder->buildUriFromRoute(
581
                'main',
582
                $GLOBALS['TYPO3_CONF_VARS']['BE']['interfaces'] ? [] : ['commandLI' => '1']
583
            );
584
            throw new PropagateResponseException(new RedirectResponse($redirectUri, 303), 1607271592);
585
        }
586
    }
587
588
    /**
589
     * Generates a list of users to whom where switched in the past. This is limited by RECENT_USERS_LIMIT.
590
     *
591
     * @param int $targetUserUid
592
     * @return int[]
593
     */
594
    protected function generateListOfMostRecentSwitchedUsers(int $targetUserUid): array
595
    {
596
        $latestUserUids = [];
597
        $backendUser = $this->getBackendUser();
598
599
        if (isset($backendUser->uc['recentSwitchedToUsers']) && is_array($backendUser->uc['recentSwitchedToUsers'])) {
600
            $latestUserUids = $backendUser->uc['recentSwitchedToUsers'];
601
        }
602
603
        // Remove potentially existing user in that list
604
        $index = array_search($targetUserUid, $latestUserUids, true);
605
        if ($index !== false) {
606
            unset($latestUserUids[$index]);
607
        }
608
609
        array_unshift($latestUserUids, $targetUserUid);
610
        $latestUserUids = array_slice($latestUserUids, 0, static::RECENT_USERS_LIMIT);
611
612
        return $latestUserUids;
613
    }
614
615
    /**
616
     * Create an array with the uids of online users as the keys
617
     * [
618
     *   1 => true,
619
     *   5 => true
620
     * ]
621
     * @return array
622
     */
623
    protected function getOnlineBackendUsers(): array
624
    {
625
        $onlineUsers = $this->backendUserSessionRepository->findAllActive();
626
        $onlineBackendUsers = [];
627
        foreach ($onlineUsers as $onlineUser) {
628
            $onlineBackendUsers[$onlineUser['ses_userid']] = true;
629
        }
630
        return $onlineBackendUsers;
631
    }
632
633
    /**
634
     * Doc header main drop down
635
     *
636
     * @param string $currentAction
637
     */
638
    protected function addMainMenu(string $currentAction): void
639
    {
640
        $this->uriBuilder->setRequest($this->request);
641
        $menu = $this->moduleTemplate->getDocHeaderComponent()->getMenuRegistry()->makeMenu();
642
        $menu->setIdentifier('BackendUserModuleMenu');
643
        $menu->addMenuItem(
644
            $menu->makeMenuItem()
645
            ->setTitle(LocalizationUtility::translate('backendUsers', 'beuser'))
646
            ->setHref($this->uriBuilder->uriFor('index'))
647
            ->setActive($currentAction === 'index')
648
        );
649
        if ($currentAction === 'show') {
650
            $menu->addMenuItem(
651
                $menu->makeMenuItem()
652
                ->setTitle(LocalizationUtility::translate('backendUserDetails', 'beuser'))
653
                ->setHref($this->uriBuilder->uriFor('show'))
654
                ->setActive(true)
655
            );
656
        }
657
        if ($currentAction === 'compare') {
658
            $menu->addMenuItem(
659
                $menu->makeMenuItem()
660
                ->setTitle(LocalizationUtility::translate('compareBackendUsers', 'beuser'))
661
                ->setHref($this->uriBuilder->uriFor('index'))
662
                ->setActive(true)
663
            );
664
        }
665
        $menu->addMenuItem(
666
            $menu->makeMenuItem()
667
            ->setTitle(LocalizationUtility::translate('backendUserGroupsMenu', 'beuser'))
668
            ->setHref($this->uriBuilder->uriFor('groups'))
669
            ->setActive($currentAction === 'groups')
670
        );
671
        if ($currentAction === 'compareGroups') {
672
            $menu->addMenuItem(
673
                $menu->makeMenuItem()
674
                ->setTitle(LocalizationUtility::translate('compareBackendUsersGroups', 'beuser'))
675
                ->setHref($this->uriBuilder->uriFor('compareGroups'))
676
                ->setActive(true)
677
            );
678
        }
679
        $menu->addMenuItem(
680
            $menu->makeMenuItem()
681
            ->setTitle(LocalizationUtility::translate('onlineUsers', 'beuser'))
682
            ->setHref($this->uriBuilder->uriFor('online'))
683
            ->setActive($currentAction === 'online')
684
        );
685
        $this->moduleTemplate->getDocHeaderComponent()->getMenuRegistry()->addMenu($menu);
686
    }
687
688
    /**
689
     * @return BackendUserAuthentication
690
     */
691
    protected function getBackendUser(): BackendUserAuthentication
692
    {
693
        return $GLOBALS['BE_USER'];
694
    }
695
696
    /**
697
     * This is a temporary hack to receive the PSR-7 request until extbase
698
     * provides a PSR-7 compatible request in actions.
699
     *
700
     * @return ServerRequestInterface
701
     */
702
    protected function getRequest(): ServerRequestInterface
703
    {
704
        return $GLOBALS['TYPO3_REQUEST'];
705
    }
706
}
707