[TASK] Streamline PHPDoc comment matches function/method signature
[Packages/TYPO3.CMS.git] / typo3 / sysext / beuser / Classes / Controller / BackendUserController.php
1 <?php
2 namespace TYPO3\CMS\Beuser\Controller;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
18 use TYPO3\CMS\Core\Session\Backend\SessionBackendInterface;
19 use TYPO3\CMS\Core\Session\SessionManager;
20 use TYPO3\CMS\Core\Utility\GeneralUtility;
21 use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
22 use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
23 use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
24
25 /**
26 * Backend module user administration controller
27 */
28 class BackendUserController extends ActionController
29 {
30 /**
31 * @var int
32 */
33 const RECENT_USERS_LIMIT = 3;
34
35 /**
36 * @var \TYPO3\CMS\Beuser\Domain\Model\ModuleData
37 */
38 protected $moduleData;
39
40 /**
41 * @var \TYPO3\CMS\Beuser\Service\ModuleDataStorageService
42 */
43 protected $moduleDataStorageService;
44
45 /**
46 * @var \TYPO3\CMS\Beuser\Domain\Repository\BackendUserRepository
47 */
48 protected $backendUserRepository;
49
50 /**
51 * @var \TYPO3\CMS\Beuser\Domain\Repository\BackendUserGroupRepository
52 */
53 protected $backendUserGroupRepository;
54
55 /**
56 * @var \TYPO3\CMS\Beuser\Domain\Repository\BackendUserSessionRepository
57 */
58 protected $backendUserSessionRepository;
59
60 /**
61 * @param \TYPO3\CMS\Beuser\Service\ModuleDataStorageService $moduleDataStorageService
62 */
63 public function injectModuleDataStorageService(\TYPO3\CMS\Beuser\Service\ModuleDataStorageService $moduleDataStorageService)
64 {
65 $this->moduleDataStorageService = $moduleDataStorageService;
66 }
67
68 /**
69 * @param \TYPO3\CMS\Beuser\Domain\Repository\BackendUserRepository $backendUserRepository
70 */
71 public function injectBackendUserRepository(\TYPO3\CMS\Beuser\Domain\Repository\BackendUserRepository $backendUserRepository)
72 {
73 $this->backendUserRepository = $backendUserRepository;
74 }
75
76 /**
77 * @param \TYPO3\CMS\Beuser\Domain\Repository\BackendUserGroupRepository $backendUserGroupRepository
78 */
79 public function injectBackendUserGroupRepository(\TYPO3\CMS\Beuser\Domain\Repository\BackendUserGroupRepository $backendUserGroupRepository)
80 {
81 $this->backendUserGroupRepository = $backendUserGroupRepository;
82 }
83
84 /**
85 * @param \TYPO3\CMS\Beuser\Domain\Repository\BackendUserSessionRepository $backendUserSessionRepository
86 */
87 public function injectBackendUserSessionRepository(\TYPO3\CMS\Beuser\Domain\Repository\BackendUserSessionRepository $backendUserSessionRepository)
88 {
89 $this->backendUserSessionRepository = $backendUserSessionRepository;
90 }
91
92 /**
93 * Load and persist module data
94 *
95 * @param \TYPO3\CMS\Extbase\Mvc\RequestInterface $request
96 * @param \TYPO3\CMS\Extbase\Mvc\ResponseInterface $response
97 * @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
98 */
99 public function processRequest(\TYPO3\CMS\Extbase\Mvc\RequestInterface $request, \TYPO3\CMS\Extbase\Mvc\ResponseInterface $response)
100 {
101 $this->moduleData = $this->moduleDataStorageService->loadModuleData();
102 // We "finally" persist the module data.
103 try {
104 parent::processRequest($request, $response);
105 $this->moduleDataStorageService->persistModuleData($this->moduleData);
106 } catch (\TYPO3\CMS\Extbase\Mvc\Exception\StopActionException $e) {
107 $this->moduleDataStorageService->persistModuleData($this->moduleData);
108 throw $e;
109 }
110 }
111
112 /**
113 * Assign default variables to view
114 * @param ViewInterface $view
115 */
116 public function initializeView(ViewInterface $view)
117 {
118 $view->assignMultiple([
119 'shortcutLabel' => 'backendUsers',
120 'dateFormat' => $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'],
121 'timeFormat' => $GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'],
122 ]);
123 }
124
125 /**
126 * Displays all BackendUsers
127 * - Switch session to different user
128 *
129 * @param \TYPO3\CMS\Beuser\Domain\Model\Demand $demand
130 */
131 public function indexAction(\TYPO3\CMS\Beuser\Domain\Model\Demand $demand = null)
132 {
133 if ($demand === null) {
134 $demand = $this->moduleData->getDemand();
135 } else {
136 $this->moduleData->setDemand($demand);
137 }
138 // Switch user until logout
139 $switchUser = (int)GeneralUtility::_GP('SwitchUser');
140 if ($switchUser > 0) {
141 $this->switchUser($switchUser);
142 }
143 $compareUserList = $this->moduleData->getCompareUserList();
144
145 // Create online user list for easy parsing
146 $onlineUsers = $this->backendUserSessionRepository->findAllActive();
147 $onlineBackendUsers = [];
148 if (is_array($onlineUsers)) {
149 foreach ($onlineUsers as $onlineUser) {
150 $onlineBackendUsers[$onlineUser['ses_userid']] = true;
151 }
152 }
153
154 $this->view->assignMultiple([
155 'onlineBackendUsers' => $onlineBackendUsers,
156 'demand' => $demand,
157 'backendUsers' => $this->backendUserRepository->findDemanded($demand),
158 'backendUserGroups' => array_merge([''], $this->backendUserGroupRepository->findAll()->toArray()),
159 'compareUserUidList' => array_combine(array_keys($compareUserList), array_fill(0, count($compareUserList), true)),
160 'currentUserUid' => $this->getBackendUserAuthentication()->user['uid'],
161 'compareUserList' => !empty($compareUserList) ? $this->backendUserRepository->findByUidList($compareUserList) : '',
162 ]);
163 }
164
165 /**
166 * Views all currently logged in BackendUsers and their sessions
167 */
168 public function onlineAction()
169 {
170 $onlineUsersAndSessions = [];
171 $onlineUsers = $this->backendUserRepository->findOnline();
172 foreach ($onlineUsers as $onlineUser) {
173 $onlineUsersAndSessions[] = [
174 'backendUser' => $onlineUser,
175 'sessions' => $this->backendUserSessionRepository->findByBackendUser($onlineUser)
176 ];
177 }
178
179 $this->view->assignMultiple([
180 'shortcutLabel' => 'onlineUsers',
181 'onlineUsersAndSessions' => $onlineUsersAndSessions,
182 'currentSessionId' => $this->getBackendUserAuthentication()->user['ses_id'],
183 ]);
184 }
185
186 /**
187 * Compare backend users from demand
188 */
189 public function compareAction()
190 {
191 $compareUserList = $this->moduleData->getCompareUserList();
192 if (empty($compareUserList)) {
193 $this->redirect('index');
194 }
195
196 $this->view->assignMultiple([
197 'shortcutLabel' => 'compareUsers',
198 'compareUserList' => $this->backendUserRepository->findByUidList($compareUserList),
199 ]);
200 }
201
202 /**
203 * Attaches one backend user to the compare list
204 *
205 * @param int $uid
206 */
207 public function addToCompareListAction($uid)
208 {
209 $this->moduleData->attachUidCompareUser($uid);
210 $this->moduleDataStorageService->persistModuleData($this->moduleData);
211 $this->forward('index');
212 }
213
214 /**
215 * Removes given backend user to the compare list
216 *
217 * @param int $uid
218 */
219 public function removeFromCompareListAction($uid)
220 {
221 $this->moduleData->detachUidCompareUser($uid);
222 $this->moduleDataStorageService->persistModuleData($this->moduleData);
223 $this->forward('index');
224 }
225
226 /**
227 * Terminate BackendUser session and logout corresponding client
228 * Redirects to onlineAction with message
229 *
230 * @param \TYPO3\CMS\Beuser\Domain\Model\BackendUser $backendUser
231 * @param string $sessionId
232 */
233 protected function terminateBackendUserSessionAction(\TYPO3\CMS\Beuser\Domain\Model\BackendUser $backendUser, $sessionId)
234 {
235 $sessionBackend = $this->getSessionBackend();
236 $success = $sessionBackend->remove($sessionId);
237
238 if ($success) {
239 $this->addFlashMessage(LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang.xlf:terminateSessionSuccess', 'beuser'));
240 }
241 $this->forward('online');
242 }
243
244 /**
245 * Switches to a given user (SU-mode) and then redirects to the start page of the backend to refresh the navigation etc.
246 *
247 * @param string $switchUser BE-user record that will be switched to
248 */
249 protected function switchUser($switchUser)
250 {
251 $targetUser = \TYPO3\CMS\Backend\Utility\BackendUtility::getRecord('be_users', $switchUser);
252 if (is_array($targetUser) && $this->getBackendUserAuthentication()->isAdmin()) {
253 // Set backend user listing module as starting module for switchback
254 $this->getBackendUserAuthentication()->uc['startModuleOnFirstLogin'] = 'system_BeuserTxBeuser';
255 $this->getBackendUserAuthentication()->uc['recentSwitchedToUsers'] = $this->generateListOfMostRecentSwitchedUsers($targetUser['uid']);
256 $this->getBackendUserAuthentication()->writeUC();
257
258 $sessionBackend = $this->getSessionBackend();
259 $sessionBackend->update(
260 $this->getBackendUserAuthentication()->getSessionId(),
261 [
262 'ses_userid' => (int)$targetUser['uid'],
263 'ses_backuserid' => (int)$this->getBackendUserAuthentication()->user['uid']
264 ]
265 );
266
267 $this->emitSwitchUserSignal($targetUser);
268
269 $redirectUrl = 'index.php' . ($GLOBALS['TYPO3_CONF_VARS']['BE']['interfaces'] ? '' : '?commandLI=1');
270 \TYPO3\CMS\Core\Utility\HttpUtility::redirect($redirectUrl);
271 }
272 }
273
274 /**
275 * Generates a list of users to whom where switched in the past. This is limited by RECENT_USERS_LIMIT.
276 *
277 * @param int $targetUserUid
278 * @return int[]
279 */
280 protected function generateListOfMostRecentSwitchedUsers(int $targetUserUid): array
281 {
282 $latestUserUids = [];
283 $backendUser = $this->getBackendUserAuthentication();
284
285 if (isset($backendUser->uc['recentSwitchedToUsers']) && is_array($backendUser->uc['recentSwitchedToUsers'])) {
286 $latestUserUids = $backendUser->uc['recentSwitchedToUsers'];
287 }
288
289 // Remove potentially existing user in that list
290 $index = array_search($targetUserUid, $latestUserUids, true);
291 if ($index !== false) {
292 unset($latestUserUids[$index]);
293 }
294
295 array_unshift($latestUserUids, $targetUserUid);
296 $latestUserUids = array_slice($latestUserUids, 0, static::RECENT_USERS_LIMIT);
297
298 return $latestUserUids;
299 }
300
301 /**
302 * Emit a signal when using the "switch to user" functionality
303 *
304 * @param array $targetUser
305 */
306 protected function emitSwitchUserSignal(array $targetUser)
307 {
308 $this->signalSlotDispatcher->dispatch(__CLASS__, 'switchUser', [$targetUser]);
309 }
310
311 /**
312 * @return BackendUserAuthentication
313 */
314 protected function getBackendUserAuthentication(): BackendUserAuthentication
315 {
316 return $GLOBALS['BE_USER'];
317 }
318
319 /**
320 * @return SessionBackendInterface
321 */
322 protected function getSessionBackend()
323 {
324 $loginType = $this->getBackendUserAuthentication()->getLoginType();
325 return GeneralUtility::makeInstance(SessionManager::class)->getSessionBackend($loginType);
326 }
327 }