ccc7f70c7332ff5ab71350283b4e96fdbb6b1076
[Packages/TYPO3.CMS.git] / typo3 / sysext / recordlist / Classes / RecordList.php
1 <?php
2 namespace TYPO3\CMS\Recordlist;
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\Clipboard\Clipboard;
20 use TYPO3\CMS\Backend\Module\AbstractModule;
21 use TYPO3\CMS\Backend\Template\Components\ButtonBar;
22 use TYPO3\CMS\Backend\Template\DocumentTemplate;
23 use TYPO3\CMS\Backend\Template\ModuleTemplate;
24 use TYPO3\CMS\Backend\Utility\BackendUtility;
25 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
26 use TYPO3\CMS\Core\DataHandling\DataHandler;
27 use TYPO3\CMS\Core\Imaging\Icon;
28 use TYPO3\CMS\Core\Imaging\IconFactory;
29 use TYPO3\CMS\Core\Messaging\FlashMessage;
30 use TYPO3\CMS\Core\Messaging\FlashMessageService;
31 use TYPO3\CMS\Core\Page\PageRenderer;
32 use TYPO3\CMS\Core\Type\Bitmask\Permission;
33 use TYPO3\CMS\Core\TypoScript\TypoScriptService;
34 use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
35 use TYPO3\CMS\Core\Utility\GeneralUtility;
36 use TYPO3\CMS\Lang\LanguageService;
37
38 /**
39 * Script Class for the Web > List module; rendering the listing of records on a page
40 */
41 class RecordList extends AbstractModule
42 {
43 /**
44 * Page Id for which to make the listing
45 *
46 * @var int
47 */
48 public $id;
49
50 /**
51 * Pointer - for browsing list of records.
52 *
53 * @var int
54 */
55 public $pointer;
56
57 /**
58 * Thumbnails or not
59 *
60 * @var string
61 */
62 public $imagemode;
63
64 /**
65 * Which table to make extended listing for
66 *
67 * @var string
68 */
69 public $table;
70
71 /**
72 * Search-fields
73 *
74 * @var string
75 */
76 public $search_field;
77
78 /**
79 * Search-levels
80 *
81 * @var int
82 */
83 public $search_levels;
84
85 /**
86 * Show-limit
87 *
88 * @var int
89 */
90 public $showLimit;
91
92 /**
93 * Return URL
94 *
95 * @var string
96 */
97 public $returnUrl;
98
99 /**
100 * Clear-cache flag - if set, clears page cache for current id.
101 *
102 * @var bool
103 */
104 public $clear_cache;
105
106 /**
107 * Command: Eg. "delete" or "setCB" (for DataHandler / clipboard operations)
108 *
109 * @var string
110 */
111 public $cmd;
112
113 /**
114 * Table on which the cmd-action is performed.
115 *
116 * @var string
117 */
118 public $cmd_table;
119
120 /**
121 * Page select perms clause
122 *
123 * @var int
124 */
125 public $perms_clause;
126
127 /**
128 * Module TSconfig
129 *
130 * @var array
131 */
132 public $modTSconfig;
133
134 /**
135 * Current ids page record
136 *
137 * @var mixed[]|bool
138 */
139 public $pageinfo;
140
141 /**
142 * Document template object
143 *
144 * @var DocumentTemplate
145 */
146 public $doc;
147
148 /**
149 * Menu configuration
150 *
151 * @var string[]
152 */
153 public $MOD_MENU = [];
154
155 /**
156 * Module settings (session variable)
157 *
158 * @var string[]
159 */
160 public $MOD_SETTINGS = [];
161
162 /**
163 * Module output accumulation
164 *
165 * @var string
166 */
167 public $content;
168
169 /**
170 * The name of the module
171 *
172 * @var string
173 */
174 protected $moduleName = 'web_list';
175
176 /**
177 * @var string
178 */
179 public $body = '';
180
181 /**
182 * @var PageRenderer
183 */
184 protected $pageRenderer = null;
185
186 /**
187 * @var IconFactory
188 */
189 protected $iconFactory;
190
191 /**
192 * Constructor
193 */
194 public function __construct()
195 {
196 parent::__construct();
197 $this->getLanguageService()->includeLLFile('EXT:lang/Resources/Private/Language/locallang_mod_web_list.xlf');
198 $this->moduleTemplate->getPageRenderer()->loadJquery();
199 $this->moduleTemplate->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Recordlist/FieldSelectBox');
200 $this->moduleTemplate->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Recordlist/Recordlist');
201 }
202
203 /**
204 * Initializing the module
205 */
206 public function init()
207 {
208 $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
209 $backendUser = $this->getBackendUserAuthentication();
210 $this->perms_clause = $backendUser->getPagePermsClause(1);
211 // Get session data
212 $sessionData = $backendUser->getSessionData(__CLASS__);
213 $this->search_field = !empty($sessionData['search_field']) ? $sessionData['search_field'] : '';
214 // GPvars:
215 $this->id = (int)GeneralUtility::_GP('id');
216 $this->pointer = GeneralUtility::_GP('pointer');
217 $this->imagemode = GeneralUtility::_GP('imagemode');
218 $this->table = GeneralUtility::_GP('table');
219 $this->search_field = GeneralUtility::_GP('search_field');
220 $this->search_levels = (int)GeneralUtility::_GP('search_levels');
221 $this->showLimit = GeneralUtility::_GP('showLimit');
222 $this->returnUrl = GeneralUtility::sanitizeLocalUrl(GeneralUtility::_GP('returnUrl'));
223 $this->clear_cache = GeneralUtility::_GP('clear_cache');
224 $this->cmd = GeneralUtility::_GP('cmd');
225 $this->cmd_table = GeneralUtility::_GP('cmd_table');
226 $sessionData['search_field'] = $this->search_field;
227 // Initialize menu
228 $this->menuConfig();
229 // Store session data
230 $backendUser->setAndSaveSessionData(self::class, $sessionData);
231 $this->getPageRenderer()->addInlineLanguageLabelFile('EXT:lang/Resources/Private/Language/locallang_mod_web_list.xlf');
232 }
233
234 /**
235 * Initialize function menu array
236 */
237 public function menuConfig()
238 {
239 // MENU-ITEMS:
240 $this->MOD_MENU = [
241 'bigControlPanel' => '',
242 'clipBoard' => '',
243 'localization' => ''
244 ];
245 // Loading module configuration:
246 $this->modTSconfig = BackendUtility::getModTSconfig($this->id, 'mod.' . $this->moduleName);
247 // Clean up settings:
248 $this->MOD_SETTINGS = BackendUtility::getModuleData($this->MOD_MENU, GeneralUtility::_GP('SET'), $this->moduleName);
249 }
250
251 /**
252 * Clears page cache for the current id, $this->id
253 */
254 public function clearCache()
255 {
256 if ($this->clear_cache) {
257 $tce = GeneralUtility::makeInstance(DataHandler::class);
258 $tce->start([], []);
259 $tce->clear_cacheCmd($this->id);
260 }
261 }
262
263 /**
264 * Main function, starting the rendering of the list.
265 */
266 public function main()
267 {
268 $backendUser = $this->getBackendUserAuthentication();
269 $lang = $this->getLanguageService();
270 // Loading current page record and checking access:
271 $this->pageinfo = BackendUtility::readPageAccess($this->id, $this->perms_clause);
272 $access = is_array($this->pageinfo) ? 1 : 0;
273 // Start document template object:
274 // We need to keep this due to deeply nested dependencies
275 $this->doc = GeneralUtility::makeInstance(DocumentTemplate::class);
276
277 $this->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/AjaxDataHandler');
278 $calcPerms = $backendUser->calcPerms($this->pageinfo);
279 $userCanEditPage = $calcPerms & Permission::PAGE_EDIT && !empty($this->id) && ($backendUser->isAdmin() || (int)$this->pageinfo['editlock'] === 0);
280 if ($userCanEditPage) {
281 $this->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/PageActions', 'function(PageActions) {
282 PageActions.setPageId(' . (int)$this->id . ');
283 PageActions.initializePageTitleRenaming();
284 }');
285 }
286 $this->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Recordlist/Tooltip');
287 // Apply predefined values for hidden checkboxes
288 // Set predefined value for DisplayBigControlPanel:
289 if ($this->modTSconfig['properties']['enableDisplayBigControlPanel'] === 'activated') {
290 $this->MOD_SETTINGS['bigControlPanel'] = true;
291 } elseif ($this->modTSconfig['properties']['enableDisplayBigControlPanel'] === 'deactivated') {
292 $this->MOD_SETTINGS['bigControlPanel'] = false;
293 }
294 // Set predefined value for Clipboard:
295 if ($this->modTSconfig['properties']['enableClipBoard'] === 'activated') {
296 $this->MOD_SETTINGS['clipBoard'] = true;
297 } elseif ($this->modTSconfig['properties']['enableClipBoard'] === 'deactivated') {
298 $this->MOD_SETTINGS['clipBoard'] = false;
299 } else {
300 if ($this->MOD_SETTINGS['clipBoard'] === null) {
301 $this->MOD_SETTINGS['clipBoard'] = true;
302 }
303 }
304 // Set predefined value for LocalizationView:
305 if ($this->modTSconfig['properties']['enableLocalizationView'] === 'activated') {
306 $this->MOD_SETTINGS['localization'] = true;
307 } elseif ($this->modTSconfig['properties']['enableLocalizationView'] === 'deactivated') {
308 $this->MOD_SETTINGS['localization'] = false;
309 }
310
311 // Initialize the dblist object:
312 /** @var $dblist RecordList\DatabaseRecordList */
313 $dblist = GeneralUtility::makeInstance(RecordList\DatabaseRecordList::class);
314 $dblist->script = BackendUtility::getModuleUrl('web_list');
315 $dblist->calcPerms = $calcPerms;
316 $dblist->thumbs = $backendUser->uc['thumbnailsByDefault'];
317 $dblist->returnUrl = $this->returnUrl;
318 $dblist->allFields = $this->MOD_SETTINGS['bigControlPanel'] || $this->table ? 1 : 0;
319 $dblist->localizationView = $this->MOD_SETTINGS['localization'];
320 $dblist->showClipboard = 1;
321 $dblist->disableSingleTableView = $this->modTSconfig['properties']['disableSingleTableView'];
322 $dblist->listOnlyInSingleTableMode = $this->modTSconfig['properties']['listOnlyInSingleTableView'];
323 $dblist->hideTables = $this->modTSconfig['properties']['hideTables'];
324 $dblist->hideTranslations = $this->modTSconfig['properties']['hideTranslations'];
325 $dblist->tableTSconfigOverTCA = $this->modTSconfig['properties']['table.'];
326 $dblist->allowedNewTables = GeneralUtility::trimExplode(',', $this->modTSconfig['properties']['allowedNewTables'], true);
327 $dblist->deniedNewTables = GeneralUtility::trimExplode(',', $this->modTSconfig['properties']['deniedNewTables'], true);
328 $dblist->newWizards = $this->modTSconfig['properties']['newWizards'] ? 1 : 0;
329 $dblist->pageRow = $this->pageinfo;
330 $dblist->counter++;
331 $dblist->MOD_MENU = ['bigControlPanel' => '', 'clipBoard' => '', 'localization' => ''];
332 $dblist->modTSconfig = $this->modTSconfig;
333 $clickTitleMode = trim($this->modTSconfig['properties']['clickTitleMode']);
334 $dblist->clickTitleMode = $clickTitleMode === '' ? 'edit' : $clickTitleMode;
335 if (isset($this->modTSconfig['properties']['tableDisplayOrder.'])) {
336 $typoScriptService = GeneralUtility::makeInstance(TypoScriptService::class);
337 $dblist->setTableDisplayOrder($typoScriptService->convertTypoScriptArrayToPlainArray($this->modTSconfig['properties']['tableDisplayOrder.']));
338 }
339 // Clipboard is initialized:
340 // Start clipboard
341 $dblist->clipObj = GeneralUtility::makeInstance(Clipboard::class);
342 // Initialize - reads the clipboard content from the user session
343 $dblist->clipObj->initializeClipboard();
344 // Clipboard actions are handled:
345 // CB is the clipboard command array
346 $CB = GeneralUtility::_GET('CB');
347 if ($this->cmd === 'setCB') {
348 // CBH is all the fields selected for the clipboard, CBC is the checkbox fields which were checked.
349 // By merging we get a full array of checked/unchecked elements
350 // This is set to the 'el' array of the CB after being parsed so only the table in question is registered.
351 $CB['el'] = $dblist->clipObj->cleanUpCBC(array_merge(GeneralUtility::_POST('CBH'), (array)GeneralUtility::_POST('CBC')), $this->cmd_table);
352 }
353 if (!$this->MOD_SETTINGS['clipBoard']) {
354 // If the clipboard is NOT shown, set the pad to 'normal'.
355 $CB['setP'] = 'normal';
356 }
357 // Execute commands.
358 $dblist->clipObj->setCmd($CB);
359 // Clean up pad
360 $dblist->clipObj->cleanCurrent();
361 // Save the clipboard content
362 $dblist->clipObj->endClipboard();
363 // This flag will prevent the clipboard panel in being shown.
364 // It is set, if the clickmenu-layer is active AND the extended view is not enabled.
365 $dblist->dontShowClipControlPanels = ($dblist->clipObj->current === 'normal' && !$this->modTSconfig['properties']['showClipControlPanelsDespiteOfCMlayers']);
366 // If there is access to the page or root page is used for searching, then render the list contents and set up the document template object:
367 if ($access || ($this->id === 0 && $this->search_levels !== 0 && $this->search_field !== '')) {
368 // Deleting records...:
369 // Has not to do with the clipboard but is simply the delete action. The clipboard object is used to clean up the submitted entries to only the selected table.
370 if ($this->cmd === 'delete') {
371 $items = $dblist->clipObj->cleanUpCBC(GeneralUtility::_POST('CBC'), $this->cmd_table, 1);
372 if (!empty($items)) {
373 $cmd = [];
374 foreach ($items as $iK => $value) {
375 $iKParts = explode('|', $iK);
376 $cmd[$iKParts[0]][$iKParts[1]]['delete'] = 1;
377 }
378 $tce = GeneralUtility::makeInstance(DataHandler::class);
379 $tce->start([], $cmd);
380 $tce->process_cmdmap();
381 if (isset($cmd['pages'])) {
382 BackendUtility::setUpdateSignal('updatePageTree');
383 }
384 $tce->printLogErrorMessages(GeneralUtility::getIndpEnv('REQUEST_URI'));
385 }
386 }
387 // Initialize the listing object, dblist, for rendering the list:
388 $this->pointer = max(0, (int)$this->pointer);
389 $dblist->start($this->id, $this->table, $this->pointer, $this->search_field, $this->search_levels, $this->showLimit);
390 $dblist->setDispFields();
391 // Render versioning selector:
392 if (ExtensionManagementUtility::isLoaded('version')) {
393 $dblist->HTMLcode .= $this->moduleTemplate->getVersionSelector($this->id);
394 }
395 // Render the list of tables:
396 $dblist->generateList();
397 $listUrl = $dblist->listURL();
398 // Add JavaScript functions to the page:
399
400 $this->moduleTemplate->addJavaScriptCode(
401 'RecordListInlineJS',
402 '
403 function jumpExt(URL,anchor) { //
404 var anc = anchor?anchor:"";
405 window.location.href = URL+(T3_THIS_LOCATION?"&returnUrl="+T3_THIS_LOCATION:"")+anc;
406 return false;
407 }
408 function jumpSelf(URL) { //
409 window.location.href = URL+(T3_RETURN_URL?"&returnUrl="+T3_RETURN_URL:"");
410 return false;
411 }
412 function jumpToUrl(URL) {
413 window.location.href = URL;
414 return false;
415 }
416
417 function setHighlight(id) { //
418 top.fsMod.recentIds["web"]=id;
419 top.fsMod.navFrameHighlightedID["web"]="pages"+id+"_"+top.fsMod.currentBank; // For highlighting
420
421 if (top.nav_frame && top.nav_frame.refresh_nav) {
422 top.nav_frame.refresh_nav();
423 }
424 }
425 ' . $this->moduleTemplate->redirectUrls($listUrl) . '
426 ' . $dblist->CBfunctions() . '
427 function editRecords(table,idList,addParams,CBflag) { //
428 window.location.href="' . BackendUtility::getModuleUrl('record_edit', ['returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')]) . '&edit["+table+"]["+idList+"]=edit"+addParams;
429 }
430 function editList(table,idList) { //
431 var list="";
432
433 // Checking how many is checked, how many is not
434 var pointer=0;
435 var pos = idList.indexOf(",");
436 while (pos!=-1) {
437 if (cbValue(table+"|"+idList.substr(pointer,pos-pointer))) {
438 list+=idList.substr(pointer,pos-pointer)+",";
439 }
440 pointer=pos+1;
441 pos = idList.indexOf(",",pointer);
442 }
443 if (cbValue(table+"|"+idList.substr(pointer))) {
444 list+=idList.substr(pointer)+",";
445 }
446
447 return list ? list : idList;
448 }
449
450 if (top.fsMod) top.fsMod.recentIds["web"] = ' . (int)$this->id . ';
451 '
452 );
453
454 // Setting up the context sensitive menu:
455 $this->moduleTemplate->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/ContextMenu');
456 }
457 // access
458 // Begin to compile the whole page, starting out with page header:
459 if (!$this->id) {
460 $title = $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'];
461 } else {
462 $title = $this->pageinfo['title'];
463 }
464 $this->body = $this->moduleTemplate->header($title);
465 $this->moduleTemplate->setTitle($title);
466
467 if (!empty($dblist->HTMLcode)) {
468 $output = $dblist->HTMLcode;
469 } else {
470 $output = '';
471 $flashMessage = GeneralUtility::makeInstance(
472 FlashMessage::class,
473 $lang->getLL('noRecordsOnThisPage'),
474 '',
475 FlashMessage::INFO
476 );
477 /** @var $flashMessageService \TYPO3\CMS\Core\Messaging\FlashMessageService */
478 $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
479 /** @var $defaultFlashMessageQueue \TYPO3\CMS\Core\Messaging\FlashMessageQueue */
480 $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
481 $defaultFlashMessageQueue->enqueue($flashMessage);
482 }
483
484 $this->body .= '<form action="' . htmlspecialchars($dblist->listURL()) . '" method="post" name="dblistForm">';
485 $this->body .= $output;
486 $this->body .= '<input type="hidden" name="cmd_table" /><input type="hidden" name="cmd" /></form>';
487 // If a listing was produced, create the page footer with search form etc:
488 if ($dblist->HTMLcode) {
489 // Making field select box (when extended view for a single table is enabled):
490 if ($dblist->table) {
491 $this->body .= $dblist->fieldSelectBox($dblist->table);
492 }
493 // Adding checkbox options for extended listing and clipboard display:
494 $this->body .= '
495
496 <!--
497 Listing options for extended view, clipboard and localization view
498 -->
499 <div class="typo3-listOptions">
500 <form action="" method="post">';
501
502 // Add "display bigControlPanel" checkbox:
503 if ($this->modTSconfig['properties']['enableDisplayBigControlPanel'] === 'selectable') {
504 $this->body .= '<div class="checkbox">' .
505 '<label for="checkLargeControl">' .
506 BackendUtility::getFuncCheck($this->id, 'SET[bigControlPanel]', $this->MOD_SETTINGS['bigControlPanel'], '', $this->table ? '&table=' . $this->table : '', 'id="checkLargeControl"') .
507 BackendUtility::wrapInHelp('xMOD_csh_corebe', 'list_options', htmlspecialchars($lang->getLL('largeControl'))) .
508 '</label>' .
509 '</div>';
510 }
511
512 // Add "clipboard" checkbox:
513 if ($this->modTSconfig['properties']['enableClipBoard'] === 'selectable') {
514 if ($dblist->showClipboard) {
515 $this->body .= '<div class="checkbox">' .
516 '<label for="checkShowClipBoard">' .
517 BackendUtility::getFuncCheck($this->id, 'SET[clipBoard]', $this->MOD_SETTINGS['clipBoard'], '', $this->table ? '&table=' . $this->table : '', 'id="checkShowClipBoard"') .
518 BackendUtility::wrapInHelp('xMOD_csh_corebe', 'list_options', htmlspecialchars($lang->getLL('showClipBoard'))) .
519 '</label>' .
520 '</div>';
521 }
522 }
523
524 // Add "localization view" checkbox:
525 if ($this->modTSconfig['properties']['enableLocalizationView'] === 'selectable') {
526 $this->body .= '<div class="checkbox">' .
527 '<label for="checkLocalization">' .
528 BackendUtility::getFuncCheck($this->id, 'SET[localization]', $this->MOD_SETTINGS['localization'], '', $this->table ? '&table=' . $this->table : '', 'id="checkLocalization"') .
529 BackendUtility::wrapInHelp('xMOD_csh_corebe', 'list_options', htmlspecialchars($lang->getLL('localization'))) .
530 '</label>' .
531 '</div>';
532 }
533
534 $this->body .= '
535 </form>
536 </div>';
537 }
538 // Printing clipboard if enabled
539 if ($this->MOD_SETTINGS['clipBoard'] && $dblist->showClipboard && ($dblist->HTMLcode || $dblist->clipObj->hasElements())) {
540 $this->body .= '<div class="db_list-dashboard">' . $dblist->clipObj->printClipboard() . '</div>';
541 }
542 // Additional footer content
543 $footerContentHook = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['recordlist/Modules/Recordlist/index.php']['drawFooterHook'];
544 if (is_array($footerContentHook)) {
545 foreach ($footerContentHook as $hook) {
546 $params = [];
547 $this->body .= GeneralUtility::callUserFunction($hook, $params, $this);
548 }
549 }
550 // Setting up the buttons for docheader
551 $dblist->getDocHeaderButtons($this->moduleTemplate);
552 // searchbox toolbar
553 if (!$this->modTSconfig['properties']['disableSearchBox'] && ($dblist->HTMLcode || !empty($dblist->searchString))) {
554 $this->content = $dblist->getSearchBox();
555 $this->moduleTemplate->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Backend/ToggleSearchToolbox');
556
557 $searchButton = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar()->makeLinkButton();
558 $searchButton
559 ->setHref('#')
560 ->setClasses('t3js-toggle-search-toolbox')
561 ->setTitle($lang->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.title.searchIcon'))
562 ->setIcon($this->iconFactory->getIcon('actions-search', Icon::SIZE_SMALL));
563 $this->moduleTemplate->getDocHeaderComponent()->getButtonBar()->addButton($searchButton,
564 ButtonBar::BUTTON_POSITION_LEFT, 90);
565 }
566
567 if ($this->pageinfo) {
568 $this->moduleTemplate->getDocHeaderComponent()->setMetaInformation($this->pageinfo);
569 }
570
571 // Build the <body> for the module
572 $this->content .= $this->body;
573 }
574
575 /**
576 * Injects the request object for the current request or subrequest
577 * Simply calls main() and init() and outputs the content
578 *
579 * @param ServerRequestInterface $request the current request
580 * @param ResponseInterface $response
581 * @return ResponseInterface the response with the content
582 */
583 public function mainAction(ServerRequestInterface $request, ResponseInterface $response)
584 {
585 BackendUtility::lockRecords();
586 $GLOBALS['SOBE'] = $this;
587 $this->init();
588 $this->clearCache();
589 $this->main();
590 $this->moduleTemplate->setContent($this->content);
591 $response->getBody()->write($this->moduleTemplate->renderContent());
592 return $response;
593 }
594
595 /**
596 * @return ModuleTemplate
597 */
598 public function getModuleTemplate()
599 {
600 return $this->moduleTemplate;
601 }
602
603 /**
604 * @return BackendUserAuthentication
605 */
606 protected function getBackendUserAuthentication()
607 {
608 return $GLOBALS['BE_USER'];
609 }
610
611 /**
612 * @return LanguageService
613 */
614 protected function getLanguageService()
615 {
616 return $GLOBALS['LANG'];
617 }
618
619 /**
620 * @return PageRenderer
621 */
622 protected function getPageRenderer()
623 {
624 if ($this->pageRenderer === null) {
625 $this->pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
626 }
627
628 return $this->pageRenderer;
629 }
630 }