[BUGFIX] Fix log module bootstrap
[Packages/TYPO3.CMS.git] / typo3 / sysext / info / Classes / Controller / InfoModuleController.php
1 <?php
2 namespace TYPO3\CMS\Info\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 Psr\Http\Message\ResponseInterface;
18 use Psr\Http\Message\ServerRequestInterface;
19 use TYPO3\CMS\Backend\Routing\UriBuilder;
20 use TYPO3\CMS\Backend\Template\Components\ButtonBar;
21 use TYPO3\CMS\Backend\Template\DocumentTemplate;
22 use TYPO3\CMS\Backend\Template\ModuleTemplate;
23 use TYPO3\CMS\Backend\Utility\BackendUtility;
24 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
25 use TYPO3\CMS\Core\Compatibility\PublicMethodDeprecationTrait;
26 use TYPO3\CMS\Core\Compatibility\PublicPropertyDeprecationTrait;
27 use TYPO3\CMS\Core\Http\HtmlResponse;
28 use TYPO3\CMS\Core\Imaging\Icon;
29 use TYPO3\CMS\Core\Localization\LanguageService;
30 use TYPO3\CMS\Core\Messaging\FlashMessage;
31 use TYPO3\CMS\Core\Messaging\FlashMessageService;
32 use TYPO3\CMS\Core\Type\Bitmask\Permission;
33 use TYPO3\CMS\Core\Utility\GeneralUtility;
34 use TYPO3\CMS\Fluid\View\StandaloneView;
35
36 /**
37 * Script Class for the Web > Info module
38 * This class creates the framework to which other extensions can connect their sub-modules
39 */
40 class InfoModuleController
41 {
42 use PublicPropertyDeprecationTrait;
43 use PublicMethodDeprecationTrait;
44
45 /**
46 * @var array
47 */
48 private $deprecatedPublicProperties = [
49 'perms_clause' => 'Using InfoModuleController::$perms_clause is deprecated and will not be possible anymore in TYPO3 v10.0.',
50 'modTSconfig' => 'Using InfoModuleController::$modTSconfig is deprecated and will not be possible anymore in TYPO3 v10.0.',
51 'modMenu_setDefaultList' => 'Using InfoModuleController::$modMenu_setDefaultList is deprecated and will not be possible anymore in TYPO3 v10.0.',
52 'modMenu_dontValidateList' => 'Using InfoModuleController::$modMenu_dontValidateList is deprecated and will not be possible anymore in TYPO3 v10.0.',
53 'modMenu_type' => 'Using InfoModuleController::$modMenu_type$ is deprecated and will not be possible anymore in TYPO3 v10.0.',
54 'extClassConf' => 'Using InfoModuleController::extClassConf$ is deprecated and will not be possible anymore in TYPO3 v10.0.',
55 'extObj' => 'Using InfoModuleController::$extObj is deprecated and will not be possible anymore in TYPO3 v10.0.',
56 'content' => 'Using InfoModuleController::$content is deprecated and will not be possible anymore in TYPO3 v10.0.',
57 'pObj' => 'Using InfoModuleController::$pObj is deprecated and will not be possible anymore in TYPO3 v10.0.',
58 'id' => 'Using InfoModuleController::id$ is deprecated and will not be possible anymore in TYPO3 v10.0.',
59 'CMD' => 'Using InfoModuleController::$CMD is deprecated, property will be removed in TYPO3 v10.0.',
60 'doc' => 'Using InfoModuleController::$doc is deprecated, property will be removed in TYPO3 v10.0.',
61 'MCONF' => 'Using InfoModuleController::$MCONF is deprecated, property will be removed in TYPO3 v10.0.',
62 ];
63
64 /**
65 * @var array
66 */
67 private $deprecatedPublicMethods = [
68 'main' => 'Using InfoModuleController::main() is deprecated and will not be possible anymore in TYPO3 v10.0.',
69 'init' => 'Using InfoModuleController::init() is deprecated and will not be possible anymore in TYPO3 v10.0.',
70 'getModuleTemplate' => 'Using InfoModuleController::getModuleTemplate() is deprecated and will not be possible anymore in TYPO3 v10.0.',
71 'menuConfig' => 'Using InfoModuleController::menuConfig() is deprecated and will not be possible anymore in TYPO3 v10.0.',
72 'handleExternalFunctionValue' => 'Using InfoModuleController::handleExternalFunctionValue() is deprecated and will not be possible anymore in TYPO3 v10.0.',
73 'mergeExternalItems' => 'Using InfoModuleController::mergeExternalItems() is deprecated and will not be possible anymore in TYPO3 v10.0.',
74 'getExternalItemConfig' => 'Using InfoModuleController::getExternalItemConfig() is deprecated and will not be possible anymore in TYPO3 v10.0.',
75 'extObjContent' => 'Using InfoModuleController::extObjContent() is deprecated and will not be possible anymore in TYPO3 v10.0.',
76 'getExtObjContent' => 'Using InfoModuleController::getExtObjContent() is deprecated and will not be possible anymore in TYPO3 v10.0.',
77 'checkExtObj' => 'Using InfoModuleController::checkExtObj() is deprecated and will not be possible anymore in TYPO3 v10.0.',
78 'extObjHeader' => 'Using InfoModuleController::extObjHeader() is deprecated, method will be removed in TYPO3 v10.0.',
79 'checkSubExtObj' => 'Using InfoModuleController::checkSubExtObj() is deprecated, method will be removed in TYPO3 v10.0.',
80 ];
81
82 /**
83 * @var array Used by client classes.
84 */
85 public $pageinfo;
86
87 /**
88 * The name of the module
89 *
90 * @var string
91 */
92 protected $moduleName = 'web_info';
93
94 /**
95 * ModuleTemplate Container
96 *
97 * @var ModuleTemplate
98 */
99 protected $moduleTemplate;
100
101 /**
102 * @var StandaloneView
103 */
104 protected $view;
105
106 /**
107 * Loaded with the global array $MCONF which holds some module configuration from the conf.php file of backend modules.
108 *
109 * @var array
110 */
111 protected $MCONF = [];
112
113 /**
114 * @var int Value of the GET/POST var 'id'
115 */
116 protected $id;
117
118 /**
119 * The value of GET/POST var, 'CMD'
120 *
121 * @var mixed
122 * @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
123 */
124 protected $CMD;
125
126 /**
127 * A WHERE clause for selection records from the pages table based on read-permissions of the current backend user.
128 *
129 * @var string
130 */
131 protected $perms_clause;
132
133 /**
134 * The module menu items array. Each key represents a key for which values can range between the items in the array of that key.
135 * Written by client classes.
136 *
137 * @var array
138 */
139 public $MOD_MENU = [
140 'function' => []
141 ];
142
143 /**
144 * Current settings for the keys of the MOD_MENU array
145 * Written by client classes.
146 *
147 * @var array
148 */
149 public $MOD_SETTINGS = [];
150
151 /**
152 * Module TSconfig based on PAGE TSconfig / USER TSconfig
153 *
154 * @var array
155 */
156 protected $modTSconfig;
157
158 /**
159 * If type is 'ses' then the data is stored as session-lasting data. This means that it'll be wiped out the next time the user logs in.
160 * Can be set from extension classes of this class before the init() function is called.
161 *
162 * @var string
163 */
164 protected $modMenu_type = '';
165
166 /**
167 * dontValidateList can be used to list variables that should not be checked if their value is found in the MOD_MENU array. Used for dynamically generated menus.
168 * Can be set from extension classes of this class before the init() function is called.
169 *
170 * @var string
171 */
172 protected $modMenu_dontValidateList = '';
173
174 /**
175 * List of default values from $MOD_MENU to set in the output array (only if the values from MOD_MENU are not arrays)
176 * Can be set from extension classes of this class before the init() function is called.
177 *
178 * @var string
179 */
180 protected $modMenu_setDefaultList = '';
181
182 /**
183 * @var array Contains module configuration parts from TBE_MODULES_EXT if found
184 */
185 protected $extClassConf;
186
187 /**
188 * Generally used for accumulating the output content of backend modules
189 *
190 * @var string
191 */
192 protected $content = '';
193
194 /**
195 * @var DocumentTemplate
196 */
197 protected $doc;
198
199 /**
200 * May contain an instance of a 'Function menu module' which connects to this backend module.
201 *
202 * @var \object
203 */
204 protected $extObj;
205
206 /**
207 * Constructor
208 */
209 public function __construct()
210 {
211 $this->moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
212 $languageService = $this->getLanguageService();
213 $languageService->includeLLFile('EXT:info/Resources/Private/Language/locallang_mod_web_info.xlf');
214
215 // @deprecated and will be removed in TYPO3 v10.0.
216 $this->MCONF = [
217 'name' => $this->moduleName,
218 ];
219 }
220
221 /**
222 * Initializes the backend module by setting internal variables, initializing the menu.
223 */
224 protected function init()
225 {
226 $this->id = (int)GeneralUtility::_GP('id');
227 // @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
228 $this->CMD = GeneralUtility::_GP('CMD');
229 $this->perms_clause = $this->getBackendUser()->getPagePermsClause(Permission::PAGE_SHOW);
230 $this->menuConfig();
231 $this->handleExternalFunctionValue();
232 }
233
234 /**
235 * Initialize module header etc and call extObjContent function
236 */
237 protected function main()
238 {
239 // since TYPO3 v9, will be removed in TYPO3 v10.0.
240 $this->doc = GeneralUtility::makeInstance(DocumentTemplate::class);
241
242 $languageService = $this->getLanguageService();
243 $backendUser = $this->getBackendUser();
244
245 // The page will show only if there is a valid page and if this page
246 // may be viewed by the user
247 $this->pageinfo = BackendUtility::readPageAccess($this->id, $this->perms_clause);
248 if ($this->pageinfo) {
249 $this->moduleTemplate->getDocHeaderComponent()->setMetaInformation($this->pageinfo);
250 }
251 $access = is_array($this->pageinfo);
252 if ($this->id && $access || $backendUser->isAdmin() && !$this->id) {
253 if ($backendUser->isAdmin() && !$this->id) {
254 $this->pageinfo = ['title' => '[root-level]', 'uid' => 0, 'pid' => 0];
255 }
256 // JavaScript
257 $this->moduleTemplate->addJavaScriptCode(
258 'WebFuncInLineJS',
259 'if (top.fsMod) top.fsMod.recentIds["web"] = ' . (int)$this->id . ';
260 function jumpToUrl(URL) {
261 window.location.href = URL;
262 return false;
263 }
264 '
265 );
266 // Setting up the context sensitive menu:
267 $this->moduleTemplate->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/ContextMenu');
268
269 $this->view = $this->getFluidTemplateObject();
270 $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
271 $this->view->assign('moduleName', (string)$uriBuilder->buildUriFromRoute($this->moduleName));
272 $this->view->assign('functionMenuModuleContent', $this->getExtObjContent());
273 // Setting up the buttons and markers for doc header
274 $this->getButtons();
275 $this->generateMenu();
276 $this->content .= $this->view->render();
277 } else {
278 // If no access or if ID == zero
279 $this->content = $this->moduleTemplate->header($languageService->getLL('title'));
280 }
281 }
282
283 /**
284 * Injects the request object for the current request or subrequest
285 * Then checks for module functions that have hooked in, and renders menu etc.
286 *
287 * @param ServerRequestInterface $request the current request
288 * @return ResponseInterface the response with the content
289 */
290 public function mainAction(ServerRequestInterface $request): ResponseInterface
291 {
292 // @deprecated and will be removed in TYPO3 v10.0.
293 $GLOBALS['SOBE'] = $this;
294
295 $this->init();
296
297 // Checking for first level external objects
298 $this->checkExtObj();
299
300 // Checking second level external objects
301 // @deprecated and will be removed in TYPO3 v10.0.
302 $this->checkSubExtObj();
303 $this->main();
304
305 $this->moduleTemplate->setContent($this->content);
306 return new HtmlResponse($this->moduleTemplate->renderContent());
307 }
308
309 /**
310 * Create the panel of buttons for submitting the form or otherwise perform operations.
311 */
312 protected function getButtons()
313 {
314 $languageService = $this->getLanguageService();
315 $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
316 // View page
317 $viewButton = $buttonBar->makeLinkButton()
318 ->setHref('#')
319 ->setOnClick(BackendUtility::viewOnClick(
320 $this->pageinfo['uid'],
321 '',
322 BackendUtility::BEgetRootLine($this->pageinfo['uid'])
323 ))
324 ->setTitle($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.showPage'))
325 ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-view-page', Icon::SIZE_SMALL));
326 $buttonBar->addButton($viewButton, ButtonBar::BUTTON_POSITION_LEFT, 1);
327 // Shortcut
328 $shortCutButton = $buttonBar->makeShortcutButton()
329 ->setModuleName($this->moduleName)
330 ->setDisplayName($this->MOD_MENU['function'][$this->MOD_SETTINGS['function']])
331 ->setGetVariables([
332 'route',
333 'id',
334 'edit_record',
335 'pointer',
336 'new_unique_uid',
337 'search_field',
338 'search_levels',
339 'showLimit'
340 ])
341 ->setSetVariables(array_keys($this->MOD_MENU));
342 $buttonBar->addButton($shortCutButton, ButtonBar::BUTTON_POSITION_RIGHT);
343
344 // CSH
345 $cshButton = $buttonBar->makeHelpButton()
346 ->setModuleName('xMOD_csh_corebe')
347 ->setFieldName('pagetree_overview');
348 $buttonBar->addButton($cshButton);
349 }
350
351 /**
352 * Generate the ModuleMenu
353 */
354 protected function generateMenu()
355 {
356 $menu = $this->moduleTemplate->getDocHeaderComponent()->getMenuRegistry()->makeMenu();
357 $menu->setIdentifier('WebInfoJumpMenu');
358 $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
359 foreach ($this->MOD_MENU['function'] as $controller => $title) {
360 $item = $menu
361 ->makeMenuItem()
362 ->setHref(
363 (string)$uriBuilder->buildUriFromRoute(
364 $this->moduleName,
365 [
366 'id' => $this->id,
367 'SET' => [
368 'function' => $controller
369 ]
370 ]
371 )
372 )
373 ->setTitle($title);
374 if ($controller === $this->MOD_SETTINGS['function']) {
375 $item->setActive(true);
376 }
377 $menu->addMenuItem($item);
378 }
379 $this->moduleTemplate->getDocHeaderComponent()->getMenuRegistry()->addMenu($menu);
380 }
381
382 /**
383 * Returns the ModuleTemplate container
384 * This is used by PageLayoutView.php
385 *
386 * @return ModuleTemplate
387 */
388 protected function getModuleTemplate()
389 {
390 return $this->moduleTemplate;
391 }
392
393 /**
394 * returns a new standalone view, shorthand function
395 *
396 * @return StandaloneView
397 */
398 protected function getFluidTemplateObject()
399 {
400 $view = GeneralUtility::makeInstance(StandaloneView::class);
401 $view->setLayoutRootPaths([GeneralUtility::getFileAbsFileName('EXT:info/Resources/Private/Layouts')]);
402 $view->setPartialRootPaths([GeneralUtility::getFileAbsFileName('EXT:info/Resources/Private/Partials')]);
403 $view->setTemplateRootPaths([GeneralUtility::getFileAbsFileName('EXT:info/Resources/Private/Templates')]);
404
405 $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName('EXT:info/Resources/Private/Templates/Main.html'));
406
407 $view->getRequest()->setControllerExtensionName('info');
408 return $view;
409 }
410
411 /**
412 * Initializes the internal MOD_MENU array setting and unsetting items based on various conditions. It also merges in external menu items from the global array TBE_MODULES_EXT (see mergeExternalItems())
413 * Then MOD_SETTINGS array is cleaned up (see \TYPO3\CMS\Backend\Utility\BackendUtility::getModuleData()) so it contains only valid values. It's also updated with any SET[] values submitted.
414 * Also loads the modTSconfig internal variable.
415 */
416 protected function menuConfig()
417 {
418 // Page / user TSconfig settings and blinding of menu-items
419 $this->modTSconfig['properties'] = BackendUtility::getPagesTSconfig($this->id)['mod.']['web_info.'] ?? [];
420 $this->MOD_MENU['function'] = $this->mergeExternalItems('web_info', 'function', $this->MOD_MENU['function']);
421 $blindActions = $this->modTSconfig['properties']['menu.']['function.'] ?? [];
422 foreach ($blindActions as $key => $value) {
423 if (!$value && array_key_exists($key, $this->MOD_MENU['function'])) {
424 unset($this->MOD_MENU['function'][$key]);
425 }
426 }
427 $this->MOD_SETTINGS = BackendUtility::getModuleData($this->MOD_MENU, GeneralUtility::_GP('SET'), 'web_info', $this->modMenu_type, $this->modMenu_dontValidateList, $this->modMenu_setDefaultList);
428 }
429
430 /**
431 * Merges menu items from global array $TBE_MODULES_EXT
432 *
433 * @param string $modName Module name for which to find value
434 * @param string $menuKey Menu key, eg. 'function' for the function menu.
435 * @param array $menuArr The part of a MOD_MENU array to work on.
436 * @return array Modified array part.
437 * @internal
438 */
439 protected function mergeExternalItems($modName, $menuKey, $menuArr)
440 {
441 $mergeArray = $GLOBALS['TBE_MODULES_EXT'][$modName]['MOD_MENU'][$menuKey];
442 if (is_array($mergeArray)) {
443 $backendUser = $this->getBackendUser();
444 foreach ($mergeArray as $k => $v) {
445 if (((string)$v['ws'] === '' || $backendUser->workspace === 0 && GeneralUtility::inList($v['ws'], 'online'))
446 || $backendUser->workspace === -1 && GeneralUtility::inList($v['ws'], 'offline')
447 || $backendUser->workspace > 0 && GeneralUtility::inList($v['ws'], 'custom')
448 ) {
449 $menuArr[$k] = $this->getLanguageService()->sL($v['title']);
450 }
451 }
452 }
453 return $menuArr;
454 }
455
456 /**
457 * Loads $this->extClassConf with the configuration for the CURRENT function of the menu.
458 *
459 * @param string $MM_key The key to MOD_MENU for which to fetch configuration. 'function' is default since it is first and foremost used to get information per "extension object" (I think that is what its called)
460 * @param string $MS_value The value-key to fetch from the config array. If NULL (default) MOD_SETTINGS[$MM_key] will be used. This is useful if you want to force another function than the one defined in MOD_SETTINGS[function]. Call this in init() function of your Script Class: handleExternalFunctionValue('function', $forcedSubModKey)
461 */
462 protected function handleExternalFunctionValue($MM_key = 'function', $MS_value = null)
463 {
464 if ($MS_value === null) {
465 $MS_value = $this->MOD_SETTINGS[$MM_key];
466 }
467 $this->extClassConf = $this->getExternalItemConfig('web_info', $MM_key, $MS_value);
468 }
469
470 /**
471 * Returns configuration values from the global variable $TBE_MODULES_EXT for the module given.
472 * For example if the module is named "web_info" and the "function" key ($menuKey) of MOD_SETTINGS is "stat" ($value) then you will have the values
473 * of $TBE_MODULES_EXT['webinfo']['MOD_MENU']['function']['stat'] returned.
474 *
475 * @param string $modName Module name
476 * @param string $menuKey Menu key, eg. "function" for the function menu. See $this->MOD_MENU
477 * @param string $value Optionally the value-key to fetch from the array that would otherwise have been returned if this value was not set. Look source...
478 * @return mixed The value from the TBE_MODULES_EXT array.
479 */
480 protected function getExternalItemConfig($modName, $menuKey, $value = '')
481 {
482 if (isset($GLOBALS['TBE_MODULES_EXT'][$modName])) {
483 return (string)$value !== ''
484 ? $GLOBALS['TBE_MODULES_EXT'][$modName]['MOD_MENU'][$menuKey][$value]
485 : $GLOBALS['TBE_MODULES_EXT'][$modName]['MOD_MENU'][$menuKey];
486 }
487 return null;
488 }
489
490 /**
491 * Creates an instance of the class found in $this->extClassConf['name'] in $this->extObj if any (this should hold three keys, "name", "path" and "title" if a "Function menu module" tries to connect...)
492 * This value in extClassConf might be set by an extension (in an ext_tables/ext_localconf file) which thus "connects" to a module.
493 * The array $this->extClassConf is set in handleExternalFunctionValue() based on the value of MOD_SETTINGS[function]
494 * If an instance is created it is initiated with $this passed as value and $this->extClassConf as second argument. Further the $this->MOD_SETTING is cleaned up again after calling the init function.
495 */
496 protected function checkExtObj()
497 {
498 if (is_array($this->extClassConf) && $this->extClassConf['name']) {
499 $this->extObj = GeneralUtility::makeInstance($this->extClassConf['name']);
500 if (is_callable([$this->extObj, 'init'])) {
501 $this->extObj->init($this);
502 }
503 // Re-write:
504 $this->MOD_SETTINGS = BackendUtility::getModuleData($this->MOD_MENU, GeneralUtility::_GP('SET'), 'web_info', $this->modMenu_type, $this->modMenu_dontValidateList, $this->modMenu_setDefaultList);
505 }
506 }
507
508 /**
509 * Calls the checkExtObj function in sub module if present.
510 *
511 * @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
512 */
513 protected function checkSubExtObj()
514 {
515 if (is_object($this->extObj) && is_callable([$this->extObj, 'checkExtObj'])) {
516 $this->extObj->checkExtObj();
517 }
518 }
519
520 /**
521 * Calls the 'header' function inside the "Function menu module" if present.
522 * A header function might be needed to add JavaScript or other stuff in the head. This can't be done in the main function because the head is already written.
523 *
524 * @deprecated since TYPO3 v9, will be removed in TYPO3 v10.0.
525 */
526 protected function extObjHeader()
527 {
528 if (is_callable([$this->extObj, 'head'])) {
529 $this->extObj->head();
530 }
531 }
532
533 /**
534 * Calls the 'main' function inside the "Function menu module" if present
535 */
536 protected function extObjContent()
537 {
538 if ($this->extObj === null) {
539 $languageService = $this->getLanguageService();
540 $flashMessage = GeneralUtility::makeInstance(
541 FlashMessage::class,
542 $languageService->sL('LLL:EXT:backend/Resources/Private/Language/locallang.xlf:no_modules_registered'),
543 $languageService->getLL('title'),
544 FlashMessage::ERROR
545 );
546 $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
547 /** @var \TYPO3\CMS\Core\Messaging\FlashMessageQueue $defaultFlashMessageQueue */
548 $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
549 $defaultFlashMessageQueue->enqueue($flashMessage);
550 } else {
551 if (is_callable([$this->extObj, 'main'])) {
552 $main = $this->extObj->main();
553 if ($main instanceof ResponseInterface) {
554 $stream = $main->getBody();
555 $stream->rewind();
556 $main = $stream->getContents();
557 }
558 $this->content .= $main;
559 }
560 }
561 }
562
563 /**
564 * Return the content of the 'main' function inside the "Function menu module" if present
565 *
566 * @return string
567 */
568 protected function getExtObjContent()
569 {
570 $savedContent = $this->content;
571 $this->content = '';
572 $this->extObjContent();
573 $newContent = $this->content;
574 $this->content = $savedContent;
575 return $newContent;
576 }
577
578 /**
579 * @return LanguageService
580 */
581 protected function getLanguageService(): LanguageService
582 {
583 return $GLOBALS['LANG'];
584 }
585
586 /**
587 * @return BackendUserAuthentication
588 */
589 protected function getBackendUser(): BackendUserAuthentication
590 {
591 return $GLOBALS['BE_USER'];
592 }
593 }