‪TYPO3CMS  11.5
PageLayoutController.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Psr\Http\Message\ResponseInterface;
21 use Psr\Http\Message\ServerRequestInterface;
30 use TYPO3\CMS\Backend\Utility\BackendUtility;
45 use TYPO3\CMS\Core\Page\PageRenderer;
53 
58 {
65  public ‪$id;
66 
72  protected ‪$modTSconfig = [];
73 
79  protected ‪$modSharedTSconfig = [];
80 
87  public ‪$pageinfo;
88 
94  protected ‪$colPosList = '';
95 
102 
108  protected ‪$MOD_MENU = [];
109 
116  public ‪$MOD_SETTINGS = [];
117 
124  protected ‪$activeColPosList;
125 
131  protected ‪$moduleName = 'web_layout';
132 
136  protected ‪$moduleTemplate;
137 
141  protected ‪$buttonBar;
142 
146  protected ‪$searchContent;
147 
151  protected ‪$availableLanguages;
152 
156  protected ‪$context;
157 
159  protected PageRenderer ‪$pageRenderer;
160  protected ‪UriBuilder ‪$uriBuilder;
163 
164  public function ‪__construct(
166  PageRenderer ‪$pageRenderer,
170  ) {
171  $this->iconFactory = ‪$iconFactory;
172  $this->pageRenderer = ‪$pageRenderer;
173  $this->uriBuilder = ‪$uriBuilder;
174  $this->pageRepository = ‪$pageRepository;
175  $this->moduleTemplateFactory = ‪$moduleTemplateFactory;
176  }
184  public function ‪mainAction(ServerRequestInterface $request): ResponseInterface
185  {
186  $this->moduleTemplate = $this->moduleTemplateFactory->create($request);
187  $this->buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
188  $this->‪getLanguageService()->‪includeLLFile('EXT:backend/Resources/Private/Language/locallang_layout.xlf');
189  // Setting module configuration / page select clause
190  $this->id = (int)($request->getParsedBody()['id'] ?? $request->getQueryParams()['id'] ?? 0);
191 
192  // Load page info array
193  $this->pageinfo = BackendUtility::readPageAccess($this->id, $this->‪getBackendUser()->getPagePermsClause(‪Permission::PAGE_SHOW));
194  if ($this->pageinfo !== false) {
195  // If page info is not resolved, user has no access or the ID parameter was malformed.
196  $this->context = GeneralUtility::makeInstance(
197  PageLayoutContext::class,
198  $this->pageinfo,
199  GeneralUtility::makeInstance(BackendLayoutView::class)->getBackendLayoutForPage($this->id)
200  );
201  }
202 
204  $currentSite = $request->getAttribute('site');
205  $this->availableLanguages = $currentSite->getAvailableLanguages($this->‪getBackendUser(), false, $this->id);
206  // initialize page/be_user TSconfig settings
207  $pageTsConfig = BackendUtility::getPagesTSconfig($this->id);
208  $this->modSharedTSconfig['properties'] = $pageTsConfig['mod.']['SHARED.'] ?? [];
209  $this->modTSconfig['properties'] = $pageTsConfig['mod.']['web_layout.'] ?? [];
210 
211  // Initialize menu
212  $this->‪menuConfig($request);
213  // Setting sys language from session var
214  $this->current_sys_language = (int)$this->MOD_SETTINGS['language'];
215  // Create LanguageMenu
216  $this->‪makeLanguageMenu();
217  // Make action menu from available actions
218  $this->‪makeActionMenu();
219 
220  $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Recordlist/ClearCache');
221  $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/NewContentElementWizardButton');
222 
223  $this->moduleTemplate->setTitle(
224  $this->‪getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_mod.xlf:mlang_tabs_tab'),
225  $this->pageinfo['title'] ?? ''
226  );
227 
228  $this->‪main($request);
229  return new ‪HtmlResponse($this->moduleTemplate->renderContent());
230  }
231 
236  protected function ‪menuConfig(ServerRequestInterface $request): void
237  {
238  // MENU-ITEMS:
239  $this->MOD_MENU = [
240  'tt_content_showHidden' => '',
241  'function' => [
242  1 => $this->‪getLanguageService()->‪getLL('m_function_1'),
243  2 => $this->‪getLanguageService()->‪getLL('m_function_2'),
244  ],
245  'language' => [
246  0 => $this->‪getLanguageService()->‪getLL('m_default'),
247  ],
248  ];
249 
250  // First, select all localized page records on the current page.
251  // Each represents a possibility for a language on the page. Add these to language selector.
252  if ($this->id) {
253  // Compile language data for pid != 0 only. The language drop-down is not shown on pid 0
254  // since pid 0 can't be localized.
255  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages');
256  $queryBuilder->getRestrictions()->removeAll()
257  ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
258  ->add(GeneralUtility::makeInstance(WorkspaceRestriction::class, (int)$this->‪getBackendUser()->workspace));
259  $statement = $queryBuilder->select('uid', ‪$GLOBALS['TCA']['pages']['ctrl']['languageField'])
260  ->from('pages')
261  ->where(
262  $queryBuilder->expr()->eq(
263  ‪$GLOBALS['TCA']['pages']['ctrl']['transOrigPointerField'],
264  $queryBuilder->createNamedParameter($this->id, ‪Connection::PARAM_INT)
265  )
266  )->executeQuery();
267  while ($pageTranslation = $statement->fetchAssociative()) {
268  $languageId = $pageTranslation[‪$GLOBALS['TCA']['pages']['ctrl']['languageField']];
269  if (isset($this->availableLanguages[$languageId])) {
270  $this->MOD_MENU['language'][$languageId] = $this->availableLanguages[$languageId]->getTitle();
271  }
272  }
273  // Override the label
274  if (isset($this->availableLanguages[0])) {
275  $this->MOD_MENU['language'][0] = $this->availableLanguages[0]->getTitle();
276  }
277 
278  // Add special "-1" in case translations of the current page exist
279  if (count($this->MOD_MENU['language']) > 1) {
280  // We need to add -1 (all) here so a possible -1 value in &SET['language'] will be respected
281  // by BackendUtility::getModuleData. Actually, this is only relevant if we are dealing with the
282  // "languages" mode, which however can only be determined, after the MOD_SETTINGS have been calculated
283  // by BackendUtility::getModuleData => chicken and egg problem. We therefore remove the -1 item from
284  // the menu again, as soon as we are able to determine the requested mode.
285  // @todo Replace the whole "mode" handling with some more robust solution
286  $this->MOD_MENU['language'][-1] = $this->‪getLanguageService()->‪sL('LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:multipleLanguages');
287  }
288  }
289  // Clean up settings
290  $this->MOD_SETTINGS = BackendUtility::getModuleData($this->MOD_MENU, $request->getParsedBody()['SET'] ?? $request->getQueryParams()['SET'] ?? [], $this->moduleName);
291  // For all elements to be shown in draft workspaces & to also show hidden elements by default if user hasn't disabled the option
292  if ($this->‪getBackendUser()->workspace != 0
293  || !isset($this->MOD_SETTINGS['tt_content_showHidden'])
294  || $this->MOD_SETTINGS['tt_content_showHidden'] !== '0'
295  ) {
296  $this->MOD_SETTINGS['tt_content_showHidden'] = 1;
297  }
298  if ((int)$this->MOD_SETTINGS['function'] !== 2) {
299  // Remove -1 (all) from the module menu if not "languages" mode
300  unset($this->MOD_MENU['language'][-1]);
301  // In case -1 (all) is still set as language, but we are no longer in
302  // "languages" mode, we fall back to the default, preventing an empty grid.
303  if ((int)$this->MOD_SETTINGS['language'] === -1) {
304  $this->MOD_SETTINGS['language'] = 0;
305  }
306  }
307  }
308 
314  protected function ‪initActions(): array
315  {
316  $actions = [
317  1 => $this->‪getLanguageService()->‪getLL('m_function_1'),
318  ];
319  // Find if there are ANY languages at all (and if not, do not show the language option from function menu).
320  // The second check is for an edge case: Only two languages in the site and the default is not allowed.
321  if (count($this->availableLanguages) > 1 || (int)array_key_first($this->availableLanguages) > 0) {
322  $actions[2] = $this->‪getLanguageService()->‪getLL('m_function_2');
323  }
324  // Page / user TSconfig blinding of menu-items
325  $blindActions = $this->modTSconfig['properties']['menu.']['functions.'] ?? [];
326  foreach ($blindActions as $key => $value) {
327  if (!$value && array_key_exists($key, $actions)) {
328  unset($actions[$key]);
329  }
330  }
331 
332  return $actions;
333  }
334 
339  protected function ‪makeActionMenu(): void
340  {
341  $actions = $this->‪initActions();
342  $actionMenu = $this->moduleTemplate->getDocHeaderComponent()->getMenuRegistry()->makeMenu();
343  $actionMenu->setIdentifier('actionMenu');
344  $actionMenu->setLabel('');
345 
346  $defaultKey = null;
347  $foundDefaultKey = false;
348  foreach ($actions as $key => $action) {
349  $menuItem = $actionMenu
350  ->makeMenuItem()
351  ->setTitle($action)
352  ->setHref((string)$this->uriBuilder->buildUriFromRoute($this->moduleName, ['id' => $this->id, 'SET' => ['function' => $key]]));
353 
354  if (!$foundDefaultKey) {
355  $defaultKey = $key;
356  $foundDefaultKey = true;
357  }
358  if ((int)$this->MOD_SETTINGS['function'] === $key) {
359  $menuItem->setActive(true);
360  $defaultKey = null;
361  }
362  $actionMenu->addMenuItem($menuItem);
363  }
364  if (isset($defaultKey)) {
365  $this->MOD_SETTINGS['function'] = $defaultKey;
366  }
367  $this->moduleTemplate->getDocHeaderComponent()->getMenuRegistry()->addMenu($actionMenu);
368  }
369 
375  protected function ‪generateMessagesForCurrentPage(): string
376  {
377  $content = '';
378  $lang = $this->‪getLanguageService();
379 
380  $view = GeneralUtility::makeInstance(StandaloneView::class);
381  $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Templates/InfoBox.html'));
382 
383  // If page is a folder
384  if ($this->pageinfo['doktype'] == ‪PageRepository::DOKTYPE_SYSFOLDER) {
385  $moduleLoader = GeneralUtility::makeInstance(ModuleLoader::class);
386  $moduleLoader->load(‪$GLOBALS['TBE_MODULES']);
387  $modules = $moduleLoader->getModules();
388  if (is_array($modules['web']['sub']['list'] ?? null)) {
389  $title = $lang->getLL('goToListModule');
390  $message = '<p>' . $lang->getLL('goToListModuleMessage') . '</p>';
391  $message .= '<a class="btn btn-info" data-dispatch-action="TYPO3.ModuleMenu.showModule" data-dispatch-args-list="web_list">'
392  . $lang->getLL('goToListModule') . '</a>';
393  $view->assignMultiple([
394  'title' => $title,
395  'message' => $message,
397  ]);
398  $content .= $view->render();
399  }
400  } elseif ($this->pageinfo['doktype'] === ‪PageRepository::DOKTYPE_SHORTCUT) {
401  $shortcutMode = (int)$this->pageinfo['shortcut_mode'];
402  $targetPage = [];
403  $message = '';
405 
406  if ($shortcutMode || $this->pageinfo['shortcut']) {
407  // Store the current group access clause and unset it afterwards since it should
408  // not be used while searching for configured shortcut pages. Actually ->getPage()
409  // would allow to disable it via an argument. However, getMenu() currently does not.
410  // @todo Refactor as soon as ->getMenu() allows to dynamically disable group access check
411  $tempGroupAccess = $this->pageRepository->where_groupAccess;
412  $this->pageRepository->where_groupAccess = '';
413  switch ($shortcutMode) {
415  $targetPage = $this->‪getTargetPageIfVisible($this->pageRepository->getPage($this->pageinfo['shortcut']));
416  $message .= $targetPage === [] ? $lang->getLL('pageIsMisconfiguredOrNotAccessibleInternalLinkMessage') : '';
417  break;
419  $menuOfPages = $this->pageRepository->getMenu($this->pageinfo['uid'], '*', 'sorting', 'AND hidden = 0');
420  $targetPage = reset($menuOfPages) ?: [];
421  $message .= $targetPage === [] ? $lang->getLL('pageIsMisconfiguredFirstSubpageMessage') : '';
422  break;
424  $targetPage = $this->‪getTargetPageIfVisible($this->pageRepository->getPage($this->pageinfo['pid']));
425  $message .= $targetPage === [] ? $lang->getLL('pageIsMisconfiguredParentPageMessage') : '';
426  break;
428  $possibleTargetPages = $this->pageRepository->getMenu($this->pageinfo['uid'], '*', 'sorting', 'AND hidden = 0');
429  if ($possibleTargetPages === []) {
430  $message .= $lang->getLL('pageIsMisconfiguredOrNotAccessibleRandomInternalLinkMessage');
431  break;
432  }
433  $message = $lang->getLL('pageIsRandomInternalLinkMessage');
435  break;
436  }
437  $this->pageRepository->where_groupAccess = $tempGroupAccess;
438  $message = htmlspecialchars($message);
439  if ($targetPage !== [] && $shortcutMode !== ‪PageRepository::SHORTCUT_MODE_RANDOM_SUBPAGE) {
440  $linkToPid = $this->uriBuilder->buildUriFromRoute($this->moduleName, ['id' => $targetPage['uid']]);
441  $path = BackendUtility::getRecordPath($targetPage['uid'], $this->‪getBackendUser()->getPagePermsClause(‪Permission::PAGE_SHOW), 1000);
442  $linkedPath = '<a href="' . htmlspecialchars((string)$linkToPid) . '">' . htmlspecialchars($path) . '</a>';
443  $message .= sprintf(htmlspecialchars($lang->getLL('pageIsInternalLinkMessage')), $linkedPath);
444  $message .= ' (' . htmlspecialchars($lang->sL(BackendUtility::getLabelFromItemlist('pages', 'shortcut_mode', (string)$shortcutMode))) . ')';
446  }
447  } else {
448  $message = htmlspecialchars($lang->getLL('pageIsMisconfiguredInternalLinkMessage'));
450  }
451 
452  $view->assignMultiple([
453  'title' => $this->pageinfo['title'],
454  'message' => $message,
455  'state' => $state,
456  ]);
457  $content .= $view->render();
458  } elseif ($this->pageinfo['doktype'] === ‪PageRepository::DOKTYPE_LINK) {
459  if (empty($this->pageinfo['url'])) {
460  $view->assignMultiple([
461  'title' => $this->pageinfo['title'],
462  'message' => $lang->getLL('pageIsMisconfiguredExternalLinkMessage'),
464  ]);
465  $content .= $view->render();
466  } else {
467  $externalUrl = $this->pageRepository->getExtURL($this->pageinfo);
468  if (is_string($externalUrl)) {
469  $externalUrl = htmlspecialchars($externalUrl);
470  $externalUrlHtml = '<a href="' . $externalUrl . '" target="_blank" rel="noreferrer">' . $externalUrl . '</a>';
471  $view->assignMultiple([
472  'title' => $this->pageinfo['title'],
473  'message' => sprintf($lang->getLL('pageIsExternalLinkMessage'), $externalUrlHtml),
475  ]);
476  $content .= $view->render();
477  }
478  }
479  }
480  // If content from different pid is displayed
481  if ($this->pageinfo['content_from_pid']) {
482  $contentPage = (array)BackendUtility::getRecord('pages', (int)$this->pageinfo['content_from_pid']);
483  $linkToPid = $this->uriBuilder->buildUriFromRoute($this->moduleName, ['id' => $this->pageinfo['content_from_pid']]);
484  $title = BackendUtility::getRecordTitle('pages', $contentPage);
485  $link = '<a href="' . htmlspecialchars((string)$linkToPid) . '">' . htmlspecialchars($title) . ' (PID ' . (int)$this->pageinfo['content_from_pid'] . ')</a>';
486  $message = sprintf($lang->getLL('content_from_pid_title'), $link);
487  $view->assignMultiple([
488  'title' => $title,
489  'message' => $message,
491  ]);
492  $content .= $view->render();
493  } else {
494  $links = $this->‪getPageLinksWhereContentIsAlsoShownOn($this->pageinfo['uid']);
495  if (!empty($links)) {
496  $message = sprintf($lang->getLL('content_on_pid_title'), $links);
497  $view->assignMultiple([
498  'title' => '',
499  'message' => $message,
501  ]);
502  $content .= $view->render();
503  }
504  }
505  return $content;
506  }
507 
514  protected function ‪getPageLinksWhereContentIsAlsoShownOn($pageId): string
515  {
516  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages');
517  $queryBuilder->getRestrictions()->removeAll();
518  $queryBuilder->getRestrictions()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
519  $queryBuilder
520  ->select('*')
521  ->from('pages')
522  ->where($queryBuilder->expr()->eq('content_from_pid', $queryBuilder->createNamedParameter($pageId, ‪Connection::PARAM_INT)));
523 
524  $links = [];
525  $rows = $queryBuilder->executeQuery()->fetchAllAssociative();
526  if (!empty($rows)) {
527  foreach ($rows as $row) {
528  $linkToPid = $this->uriBuilder->buildUriFromRoute($this->moduleName, ['id' => $row['uid']]);
529  $title = BackendUtility::getRecordTitle('pages', $row);
530  $link = '<a href="' . htmlspecialchars((string)$linkToPid) . '">' . htmlspecialchars($title) . ' (PID ' . (int)$row['uid'] . ')</a>';
531  $links[] = $link;
532  }
533  }
534  return implode(', ', $links);
535  }
536 
540  protected function ‪getLocalizedPageTitle(): string
541  {
542  if ($this->current_sys_language > 0) {
543  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
544  ->getQueryBuilderForTable('pages');
545  $queryBuilder->getRestrictions()
546  ->removeAll()
547  ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
548  ->add(GeneralUtility::makeInstance(WorkspaceRestriction::class, (int)$this->‪getBackendUser()->workspace));
549  $localizedPage = $queryBuilder
550  ->select('*')
551  ->from('pages')
552  ->where(
553  $queryBuilder->expr()->eq(
554  ‪$GLOBALS['TCA']['pages']['ctrl']['transOrigPointerField'],
555  $queryBuilder->createNamedParameter($this->id, ‪Connection::PARAM_INT)
556  ),
557  $queryBuilder->expr()->eq(
558  ‪$GLOBALS['TCA']['pages']['ctrl']['languageField'],
559  $queryBuilder->createNamedParameter($this->current_sys_language, ‪Connection::PARAM_INT)
560  )
561  )
562  ->setMaxResults(1)
563  ->executeQuery()
564  ->fetchAssociative();
565  BackendUtility::workspaceOL('pages', $localizedPage);
566  return $localizedPage['title'];
567  }
568  return $this->pageinfo['title'];
569  }
570 
577  protected function ‪main(ServerRequestInterface $request): void
578  {
579  $content = '';
580  // Access check...
581  // The page will show only if there is a valid page and if this page may be viewed by the user
582  if ($this->id && is_array($this->pageinfo)) {
583  $this->moduleTemplate->getDocHeaderComponent()->setMetaInformation($this->pageinfo);
584  $content .= ‪ImmediateActionElement::moduleStateUpdateWithCurrentMount('web', (int)$this->id, true);
585  if ($this->context instanceof PageLayoutContext) {
586  $backendLayout = $this->context->getBackendLayout();
587 
588  // Find backend layout / columns
589  if (!empty($backendLayout->getColumnPositionNumbers())) {
590  $this->colPosList = implode(',', $backendLayout->getColumnPositionNumbers());
591  }
592  // Removing duplicates, if any
593  $colPosArray = array_unique(‪GeneralUtility::intExplode(',', $this->colPosList, true));
594  // Accessible columns
595  if (isset($this->modSharedTSconfig['properties']['colPos_list']) && trim($this->modSharedTSconfig['properties']['colPos_list']) !== '') {
596  $activeColPosArray = array_unique(‪GeneralUtility::intExplode(',', trim($this->modSharedTSconfig['properties']['colPos_list'])));
597  // Match with the list which is present in the colPosList for the current page
598  if (!empty($colPosArray) && !empty($activeColPosArray)) {
599  $activeColPosArray = array_unique(array_intersect(
600  $colPosArray,
601  $activeColPosArray
602  ));
603  }
604  } else {
605  $activeColPosArray = $colPosArray;
606  }
607  $this->activeColPosList = implode(',', $activeColPosArray);
608  $this->colPosList = implode(',', $colPosArray);
609  }
610 
611  $content .= $this->‪generateMessagesForCurrentPage();
612 
613  // Render the primary module content:
614  $content .= '<form action="' . htmlspecialchars((string)$this->uriBuilder->buildUriFromRoute($this->moduleName, ['id' => $this->id])) . '" id="PageLayoutController" method="post">';
615  // Page title
616  $content .= '<h1 class="' . ($this->‪isPageEditable($this->current_sys_language) ? 't3js-title-inlineedit' : '') . '">' . htmlspecialchars($this->‪getLocalizedPageTitle()) . '</h1>';
617  // All other listings
618  $content .= $this->‪renderContent();
619  $content .= '</form>';
620  // Setting up the buttons for the docheader
621  $this->‪makeButtons($request);
622  $this->‪initializeClipboard($request);
623  } else {
624  $content .= ‪ImmediateActionElement::moduleStateUpdate('web', (int)$this->id);
625  $content .= '<h1>' . htmlspecialchars(‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']) . '</h1>';
626  $view = GeneralUtility::makeInstance(StandaloneView::class);
627  $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Templates/InfoBox.html'));
628  $view->assignMultiple([
629  'title' => $this->‪getLanguageService()->getLL('clickAPage_header'),
630  'message' => $this->‪getLanguageService()->getLL('clickAPage_content'),
632  ]);
633  $content .= $view->render();
634  }
635  // Set content
636  $this->moduleTemplate->setContent($content);
637  }
638 
642  protected function ‪initializeClipboard(ServerRequestInterface $request): void
643  {
644  $clipboard = GeneralUtility::makeInstance(Clipboard::class);
645  $clipboard->initializeClipboard($request);
646  $clipboard->lockToNormal();
647  $clipboard->cleanCurrent();
648  $clipboard->endClipboard();
649  $elFromTable = $clipboard->elFromTable('tt_content');
650  if (!empty($elFromTable) && $this->‪isContentEditable($this->current_sys_language)) {
651  $pasteItem = (int)substr((string)key($elFromTable), 11);
652  $pasteRecord = BackendUtility::getRecordWSOL('tt_content', $pasteItem);
653  $pasteTitle = BackendUtility::getRecordTitle('tt_content', $pasteRecord, false, true);
654  $this->pageRenderer->getJavaScriptRenderer()->addJavaScriptModuleInstruction(
655  ‪JavaScriptModuleInstruction::forRequireJS('TYPO3/CMS/Backend/LayoutModule/Paste')
656  ->assign([
657  'itemOnClipboardUid' => $pasteItem,
658  'itemOnClipboardTitle' => $pasteTitle,
659  'copyMode' => $clipboard->clipData['normal']['mode'] ?? '',
660  ])
661  );
662  }
663  }
664 
670  protected function ‪renderContent(): string
671  {
672  $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/ContextMenu');
673  $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Tooltip');
674  $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Localization');
675  $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/LayoutModule/DragDrop');
676  $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Modal');
677  $this->pageRenderer->loadRequireJsModule(‪ImmediateActionElement::MODULE_NAME);
678  $this->pageRenderer->addInlineLanguageLabelFile('EXT:backend/Resources/Private/Language/locallang_layout.xlf');
679 
680  $tableOutput = '';
681  $numberOfHiddenElements = 0;
682 
683  if ($this->context instanceof PageLayoutContext) {
684  // Context may not be set, which happens if the page module is viewed by a user with no access to the
685  // current page, or if the ID parameter is malformed. In this case we do not resolve any backend layout
686  // or other page structure information and we do not render any "table output" for the module.
687  $configuration = $this->context->getDrawingConfiguration();
688  $configuration->setDefaultLanguageBinding(!empty($this->modTSconfig['properties']['defLangBinding']));
689  $configuration->setActiveColumns(‪GeneralUtility::trimExplode(',', $this->activeColPosList, true));
690  $configuration->setShowHidden((bool)$this->MOD_SETTINGS['tt_content_showHidden']);
691  $configuration->setLanguageColumns($this->MOD_MENU['language']);
692  $configuration->setShowNewContentWizard(empty($this->modTSconfig['properties']['disableNewContentElementWizard']));
693  $configuration->setSelectedLanguageId((int)$this->MOD_SETTINGS['language']);
694  if ($this->MOD_SETTINGS['function'] == 2) {
695  $configuration->setLanguageMode(true);
696  }
697 
698  $numberOfHiddenElements = $this->‪getNumberOfHiddenElements($configuration->getLanguageMode());
699 
700  $pageActionsInstruction = ‪JavaScriptModuleInstruction::forRequireJS('TYPO3/CMS/Backend/PageActions');
701  if ($this->context->isPageEditable()) {
702  $languageOverlayId = 0;
703  $pageLocalizationRecord = BackendUtility::getRecordLocalization('pages', $this->id, (int)$this->current_sys_language);
704  if (is_array($pageLocalizationRecord)) {
705  $pageLocalizationRecord = reset($pageLocalizationRecord);
706  }
707  if (!empty($pageLocalizationRecord['uid'])) {
708  $languageOverlayId = $pageLocalizationRecord['uid'];
709  }
710  $pageActionsInstruction
711  ->invoke('setPageId', (int)$this->id)
712  ->invoke('setLanguageOverlayId', $languageOverlayId);
713  }
714  $this->pageRenderer->getJavaScriptRenderer()->addJavaScriptModuleInstruction($pageActionsInstruction);
715  $tableOutput = GeneralUtility::makeInstance(BackendLayoutRenderer::class, $this->context)->drawContent();
716  }
717 
718  if ($this->‪getBackendUser()->check('tables_select', 'tt_content') && $numberOfHiddenElements > 0) {
719  // Toggle hidden ContentElements
720  $tableOutput .= '
721  <div class="form-check">
722  <input type="checkbox" id="checkTt_content_showHidden" class="form-check-input" name="SET[tt_content_showHidden]" value="1" ' . ($this->MOD_SETTINGS['tt_content_showHidden'] ? 'checked="checked"' : '') . ' />
723  <label class="form-check-label" for="checkTt_content_showHidden">
724  ' . htmlspecialchars($this->‪getLanguageService()->‪getLL('hiddenCE')) . ' (<span class="t3js-hidden-counter">' . $numberOfHiddenElements . '</span>)
725  </label>
726  </div>';
727  }
728 
729  // Init the content
730  $content = '';
731  // Additional header content
732  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/db_layout.php']['drawHeaderHook'] ?? [] as $hook) {
733  $params = [];
734  $content .= GeneralUtility::callUserFunction($hook, $params, $this);
735  }
736  $content .= $tableOutput;
737 
738  // Additional footer content
739  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/db_layout.php']['drawFooterHook'] ?? [] as $hook) {
740  $params = [];
741  $content .= GeneralUtility::callUserFunction($hook, $params, $this);
742  }
743  return $content;
744  }
745 
751  public function ‪getModuleTemplate(): ModuleTemplate
752  {
754  }
755 
756  /***************************
757  *
758  * Sub-content functions, rendering specific parts of the module content.
759  *
760  ***************************/
765  protected function ‪makeButtons(ServerRequestInterface $request): void
766  {
767  // Add CSH (Context Sensitive Help) icon to tool bar
768  $contextSensitiveHelpButton = $this->buttonBar->makeHelpButton()
769  ->setModuleName('_MOD_' . $this->moduleName)
770  ->setFieldName('columns_' . $this->MOD_SETTINGS['function']);
771  $this->buttonBar->addButton($contextSensitiveHelpButton);
772  $lang = $this->‪getLanguageService();
773  // View page
774  $pageTsConfig = BackendUtility::getPagesTSconfig($this->id);
775  // Exclude sysfolders, spacers and recycler by default
776  $excludeDokTypes = [
780  ];
781  // Custom override of values
782  if (isset($pageTsConfig['TCEMAIN.']['preview.']['disableButtonForDokType'])) {
783  $excludeDokTypes = ‪GeneralUtility::intExplode(
784  ',',
785  $pageTsConfig['TCEMAIN.']['preview.']['disableButtonForDokType'],
786  true
787  );
788  }
789 
790  if (
791  $this->current_sys_language !== -1
792  && !in_array((int)$this->pageinfo['doktype'], $excludeDokTypes, true)
793  && !‪VersionState::cast($this->pageinfo['t3ver_state'])->equals(‪VersionState::DELETE_PLACEHOLDER)
794  ) {
795  $languageParameter = $this->current_sys_language ? ('&L=' . ‪$this->current_sys_language) : '';
796  $previewDataAttributes = ‪PreviewUriBuilder::create((int)$this->pageinfo['uid'])
797  ->withRootLine(BackendUtility::BEgetRootLine($this->pageinfo['uid']))
798  ->withAdditionalQueryParameters($languageParameter)
799  ->buildDispatcherDataAttributes();
800  $viewButton = $this->buttonBar->makeLinkButton()
801  ->setDataAttributes($previewDataAttributes ?? [])
802  ->setTitle($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.showPage'))
803  ->setIcon($this->iconFactory->getIcon('actions-view-page', ‪Icon::SIZE_SMALL))
804  ->setHref('#');
805 
806  $this->buttonBar->addButton($viewButton, ‪ButtonBar::BUTTON_POSITION_LEFT, 3);
807  }
808  // Shortcut
809  $shortcutButton = $this->buttonBar->makeShortcutButton()
810  ->setRouteIdentifier($this->moduleName)
811  ->setDisplayName($this->‪getShortcutTitle())
812  ->setArguments([
813  'id' => (int)$this->id,
814  'SET' => [
815  'tt_content_showHidden' => (bool)$this->MOD_SETTINGS['tt_content_showHidden'],
816  'function' => (int)$this->MOD_SETTINGS['function'],
817  'language' => (int)$this->current_sys_language,
818  ],
819  ]);
820  $this->buttonBar->addButton($shortcutButton);
821 
822  // Cache
823  $clearCacheButton = $this->buttonBar->makeLinkButton()
824  ->setHref('#')
825  ->setDataAttributes(['id' => $this->pageinfo['uid']])
826  ->setClasses('t3js-clear-page-cache')
827  ->setTitle($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.clear_cache'))
828  ->setIcon($this->iconFactory->getIcon('actions-system-cache-clear', ‪Icon::SIZE_SMALL));
829  $this->buttonBar->addButton($clearCacheButton, ‪ButtonBar::BUTTON_POSITION_RIGHT, 1);
830 
831  // Edit page properties
832  if ($this->‪isPageEditable(0)) {
833  $url = (string)$this->uriBuilder->buildUriFromRoute(
834  'record_edit',
835  [
836  'edit' => [
837  'pages' => [
838  $this->id => 'edit',
839  ],
840  ],
841  'returnUrl' => $request->getAttribute('normalizedParams')->getRequestUri(),
842  ]
843  );
844  $editPageButton = $this->buttonBar->makeLinkButton()
845  ->setHref($url)
846  ->setTitle($lang->getLL('editPageProperties'))
847  ->setIcon($this->iconFactory->getIcon('actions-page-open', ‪Icon::SIZE_SMALL));
848  $this->buttonBar->addButton($editPageButton, ‪ButtonBar::BUTTON_POSITION_LEFT, 3);
849  }
850 
851  // Edit page properties of page language overlay (Only when one specific language is selected)
852  if ((int)$this->MOD_SETTINGS['function'] === 1
853  && $this->current_sys_language > 0
854  && $this->‪isPageEditable($this->current_sys_language)
855  ) {
856  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages');
857  $queryBuilder->getRestrictions()
858  ->removeAll()
859  ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
860  ->add(GeneralUtility::makeInstance(WorkspaceRestriction::class, $this->‪getBackendUser()->workspace));
861  $overlayRecord = $queryBuilder
862  ->select('uid')
863  ->from('pages')
864  ->where(
865  $queryBuilder->expr()->eq(
866  ‪$GLOBALS['TCA']['pages']['ctrl']['transOrigPointerField'],
867  $queryBuilder->createNamedParameter($this->id, ‪Connection::PARAM_INT)
868  ),
869  $queryBuilder->expr()->eq(
870  ‪$GLOBALS['TCA']['pages']['ctrl']['languageField'],
871  $queryBuilder->createNamedParameter($this->current_sys_language, ‪Connection::PARAM_INT)
872  )
873  )
874  ->setMaxResults(1)
875  ->executeQuery()
876  ->fetchAssociative();
877  BackendUtility::workspaceOL('pages', $overlayRecord, $this->‪getBackendUser()->workspace);
878  // Edit button
879  $url = (string)$this->uriBuilder->buildUriFromRoute(
880  'record_edit',
881  [
882  'edit' => [
883  'pages' => [
884  $overlayRecord['uid'] => 'edit',
885  ],
886  ],
887  'returnUrl' => $request->getAttribute('normalizedParams')->getRequestUri(),
888  ]
889  );
890  $editLanguageButton = $this->buttonBar->makeLinkButton()
891  ->setHref($url)
892  ->setTitle($lang->getLL('editPageLanguageOverlayProperties'))
893  ->setIcon($this->iconFactory->getIcon('mimetypes-x-content-page-language-overlay', ‪Icon::SIZE_SMALL));
894  $this->buttonBar->addButton($editLanguageButton, ‪ButtonBar::BUTTON_POSITION_LEFT, 3);
895  }
896  }
897 
898  /*******************************
899  *
900  * Other functions
901  *
902  ******************************/
903 
911  protected function ‪getNumberOfHiddenElements(bool $isLanguageModeActive): int
912  {
913  $andWhere = [];
914  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tt_content');
915  $queryBuilder->getRestrictions()
916  ->removeAll()
917  ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
918  ->add(GeneralUtility::makeInstance(WorkspaceRestriction::class, (int)$this->‪getBackendUser()->workspace));
919 
920  $queryBuilder
921  ->count('uid')
922  ->from('tt_content')
923  ->where(
924  $queryBuilder->expr()->eq(
925  'pid',
926  $queryBuilder->createNamedParameter($this->id, ‪Connection::PARAM_INT)
927  )
928  );
929 
930  if ($this->current_sys_language === 0) {
931  // Default language is active (in columns or language mode) - consider "all languages" and the default
932  $queryBuilder->andWhere(
933  $queryBuilder->expr()->in(
934  ‪$GLOBALS['TCA']['tt_content']['ctrl']['languageField'],
935  [-1, 0]
936  )
937  );
938  } elseif ($isLanguageModeActive && $this->current_sys_language !== -1) {
939  // Multi-language view with any translation is active -
940  // consider "all languages", the default and the translation
941  $queryBuilder->andWhere(
942  $queryBuilder->expr()->in(
943  ‪$GLOBALS['TCA']['tt_content']['ctrl']['languageField'],
944  [-1, 0, $queryBuilder->createNamedParameter($this->current_sys_language, ‪Connection::PARAM_INT)]
945  )
946  );
947  } elseif ($this->current_sys_language > 0) {
948  // Columns mode with any translation is active - consider "all languages" and the translation
949  $queryBuilder->andWhere(
950  $queryBuilder->expr()->in(
951  ‪$GLOBALS['TCA']['tt_content']['ctrl']['languageField'],
952  [-1, $queryBuilder->createNamedParameter($this->current_sys_language, ‪Connection::PARAM_INT)]
953  )
954  );
955  }
956 
957  if (!empty(‪$GLOBALS['TCA']['tt_content']['ctrl']['enablecolumns']['disabled'])) {
958  $andWhere[] = $queryBuilder->expr()->neq(
959  ‪$GLOBALS['TCA']['tt_content']['ctrl']['enablecolumns']['disabled'],
960  $queryBuilder->createNamedParameter(0, ‪Connection::PARAM_INT)
961  );
962  }
963 
964  if (!empty(‪$GLOBALS['TCA']['tt_content']['ctrl']['enablecolumns']['starttime'])) {
965  $starttimeField = ‪$GLOBALS['TCA']['tt_content']['ctrl']['enablecolumns']['starttime'];
966  $andWhere[] = $queryBuilder->expr()->andX(
967  $queryBuilder->expr()->neq(
968  $starttimeField,
969  $queryBuilder->createNamedParameter(0, ‪Connection::PARAM_INT)
970  ),
971  $queryBuilder->expr()->gt(
972  $starttimeField,
973  $queryBuilder->createNamedParameter(‪$GLOBALS['SIM_ACCESS_TIME'], ‪Connection::PARAM_INT)
974  )
975  );
976  }
977 
978  if (!empty(‪$GLOBALS['TCA']['tt_content']['ctrl']['enablecolumns']['endtime'])) {
979  $endtimeField = ‪$GLOBALS['TCA']['tt_content']['ctrl']['enablecolumns']['endtime'];
980  $andWhere[] = $queryBuilder->expr()->andX(
981  $queryBuilder->expr()->neq(
982  $endtimeField,
983  $queryBuilder->createNamedParameter(0, ‪Connection::PARAM_INT)
984  ),
985  $queryBuilder->expr()->lte(
986  $endtimeField,
987  $queryBuilder->createNamedParameter(‪$GLOBALS['SIM_ACCESS_TIME'], ‪Connection::PARAM_INT)
988  )
989  );
990  }
991 
992  if (!empty($andWhere)) {
993  $queryBuilder->andWhere(
994  $queryBuilder->expr()->orX(...$andWhere)
995  );
996  }
997 
998  $count = $queryBuilder
999  ->executeQuery()
1000  ->fetchOne();
1001 
1002  return (int)$count;
1003  }
1004 
1011  protected function ‪isPageEditable(int $languageId): bool
1012  {
1013  if (‪$GLOBALS['TCA']['pages']['ctrl']['readOnly'] ?? false) {
1014  return false;
1015  }
1016  $backendUser = $this->‪getBackendUser();
1017  if ($backendUser->isAdmin()) {
1018  return true;
1019  }
1020  if (‪$GLOBALS['TCA']['pages']['ctrl']['adminOnly'] ?? false) {
1021  return false;
1022  }
1023 
1024  return $this->pageinfo !== []
1025  && !(bool)($this->pageinfo[‪$GLOBALS['TCA']['pages']['ctrl']['editlock'] ?? null] ?? false)
1026  && $backendUser->doesUserHaveAccess($this->pageinfo, ‪Permission::PAGE_EDIT)
1027  && $backendUser->checkLanguageAccess($languageId)
1028  && $backendUser->check('tables_modify', 'pages');
1029  }
1030 
1037  protected function ‪isContentEditable(int $languageId): bool
1038  {
1039  if ($this->‪getBackendUser()->isAdmin()) {
1040  return true;
1041  }
1042 
1043  return !$this->pageinfo['editlock']
1045  && $this->‪getBackendUser()->‪check('tables_modify', 'tt_content')
1046  && $this->‪getBackendUser()->‪checkLanguageAccess($languageId);
1047  }
1048 
1054  protected function ‪getLanguageService(): LanguageService
1055  {
1056  return ‪$GLOBALS['LANG'];
1057  }
1058 
1064  protected function ‪getBackendUser(): ‪BackendUserAuthentication
1065  {
1066  return ‪$GLOBALS['BE_USER'];
1067  }
1068 
1072  protected function ‪makeLanguageMenu(): void
1073  {
1074  if (count($this->MOD_MENU['language']) > 1) {
1075  $languageMenu = $this->moduleTemplate->getDocHeaderComponent()->getMenuRegistry()->makeMenu();
1076  $languageMenu->setIdentifier('languageMenu');
1077  foreach ($this->MOD_MENU['language'] as $key => $language) {
1078  $menuItem = $languageMenu
1079  ->makeMenuItem()
1080  ->setTitle($language)
1081  ->setHref((string)$this->uriBuilder->buildUriFromRoute($this->moduleName, ['id' => $this->id, 'SET' => ['language' => $key]]));
1082  if ((int)$this->current_sys_language === $key) {
1083  $menuItem->setActive(true);
1084  }
1085  $languageMenu->addMenuItem($menuItem);
1086  }
1087  $this->moduleTemplate->getDocHeaderComponent()->getMenuRegistry()->addMenu($languageMenu);
1088  }
1089  }
1090 
1098  protected function ‪getTargetPageIfVisible(array $targetPage): array
1099  {
1100  return !(bool)($targetPage['hidden'] ?? false) ? $targetPage : [];
1101  }
1102 
1108  protected function ‪getShortcutTitle(): string
1109  {
1110  return sprintf(
1111  '%s: %s [%d]',
1112  $this->‪getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_mod.xlf:mlang_labels_tablabel'),
1113  BackendUtility::getRecordTitle('pages', (array)$this->pageinfo),
1114  $this->id
1115  );
1116  }
1117 }
‪TYPO3\CMS\Backend\Controller\PageLayoutController\renderContent
‪string renderContent()
Definition: PageLayoutController.php:655
‪TYPO3\CMS\Backend\Controller\PageLayoutController\main
‪main(ServerRequestInterface $request)
Definition: PageLayoutController.php:562
‪TYPO3\CMS\Core\Imaging\Icon\SIZE_SMALL
‪const SIZE_SMALL
Definition: Icon.php:30
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static list< string > trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
Definition: GeneralUtility.php:999
‪TYPO3\CMS\Core\Site\Entity\SiteInterface
Definition: SiteInterface.php:26
‪TYPO3\CMS\Backend\Controller\PageLayoutController\$searchContent
‪string $searchContent
Definition: PageLayoutController.php:133
‪TYPO3\CMS\Backend\Controller\PageLayoutController\$buttonBar
‪ButtonBar $buttonBar
Definition: PageLayoutController.php:129
‪TYPO3\CMS\Core\Database\Connection\PARAM_INT
‪const PARAM_INT
Definition: Connection.php:49
‪TYPO3\CMS\Backend\Controller\PageLayoutController\$current_sys_language
‪int $current_sys_language
Definition: PageLayoutController.php:95
‪TYPO3\CMS\Backend\Controller\PageLayoutController\makeButtons
‪makeButtons(ServerRequestInterface $request)
Definition: PageLayoutController.php:750
‪TYPO3\CMS\Backend\Controller\PageLayoutController\getLanguageService
‪LanguageService getLanguageService()
Definition: PageLayoutController.php:1039
‪TYPO3\CMS\Backend\Template\Components\ButtonBar\BUTTON_POSITION_LEFT
‪const BUTTON_POSITION_LEFT
Definition: ButtonBar.php:36
‪TYPO3\CMS\Backend\Template\Components\ButtonBar
Definition: ButtonBar.php:32
‪TYPO3\CMS\Backend\Controller\PageLayoutController\getTargetPageIfVisible
‪array getTargetPageIfVisible(array $targetPage)
Definition: PageLayoutController.php:1083
‪TYPO3\CMS\Backend\Controller\PageLayoutController\isPageEditable
‪bool isPageEditable(int $languageId)
Definition: PageLayoutController.php:996
‪TYPO3\CMS\Backend\Clipboard\Clipboard
Definition: Clipboard.php:49
‪TYPO3\CMS\Backend\Controller\PageLayoutController\isContentEditable
‪bool isContentEditable(int $languageId)
Definition: PageLayoutController.php:1022
‪TYPO3\CMS\Backend\Routing\PreviewUriBuilder\create
‪static static create(int $pageId, string $alternativeUri=null)
Definition: PreviewUriBuilder.php:75
‪TYPO3\CMS\Backend\Controller\PageLayoutController\initializeClipboard
‪initializeClipboard(ServerRequestInterface $request)
Definition: PageLayoutController.php:627
‪TYPO3\CMS\Core\Imaging\Icon
Definition: Icon.php:26
‪TYPO3\CMS\Backend\Template\ModuleTemplateFactory
Definition: ModuleTemplateFactory.php:29
‪TYPO3\CMS\Fluid\ViewHelpers\Be\InfoboxViewHelper\STATE_INFO
‪const STATE_INFO
Definition: InfoboxViewHelper.php:62
‪TYPO3\CMS\Backend\Domain\Model\Element\ImmediateActionElement\moduleStateUpdateWithCurrentMount
‪static moduleStateUpdateWithCurrentMount(string $module, $identifier, bool $select=null)
Definition: ImmediateActionElement.php:47
‪TYPO3\CMS\Backend\Controller\PageLayoutController\makeLanguageMenu
‪makeLanguageMenu()
Definition: PageLayoutController.php:1057
‪TYPO3\CMS\Backend\Controller\PageLayoutController\$moduleName
‪string $moduleName
Definition: PageLayoutController.php:121
‪TYPO3\CMS\Core\Domain\Repository\PageRepository\DOKTYPE_SHORTCUT
‪const DOKTYPE_SHORTCUT
Definition: PageRepository.php:112
‪TYPO3\CMS\Core\Domain\Repository\PageRepository\DOKTYPE_LINK
‪const DOKTYPE_LINK
Definition: PageRepository.php:111
‪TYPO3\CMS\Backend\Controller\PageLayoutController\__construct
‪__construct(IconFactory $iconFactory, PageRenderer $pageRenderer, UriBuilder $uriBuilder, PageRepository $pageRepository, ModuleTemplateFactory $moduleTemplateFactory)
Definition: PageLayoutController.php:149
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\check
‪bool check($type, $value)
Definition: BackendUserAuthentication.php:585
‪TYPO3\CMS\Backend\Controller\PageLayoutController\$colPosList
‪string $colPosList
Definition: PageLayoutController.php:89
‪TYPO3\CMS\Backend\Controller\PageLayoutController\$MOD_SETTINGS
‪array $MOD_SETTINGS
Definition: PageLayoutController.php:108
‪TYPO3\CMS\Backend\Domain\Model\Element\ImmediateActionElement\moduleStateUpdate
‪static moduleStateUpdate(string $module, $identifier, bool $select=null)
Definition: ImmediateActionElement.php:39
‪TYPO3\CMS\Fluid\ViewHelpers\Be\InfoboxViewHelper\STATE_ERROR
‪const STATE_ERROR
Definition: InfoboxViewHelper.php:65
‪TYPO3\CMS\Backend\Controller\PageLayoutController\$availableLanguages
‪SiteLanguage[] $availableLanguages
Definition: PageLayoutController.php:137
‪TYPO3\CMS\Core\Imaging\IconFactory
Definition: IconFactory.php:34
‪TYPO3\CMS\Core\Page\JavaScriptModuleInstruction
Definition: JavaScriptModuleInstruction.php:23
‪TYPO3\CMS\Backend\Controller\PageLayoutController\generateMessagesForCurrentPage
‪string generateMessagesForCurrentPage()
Definition: PageLayoutController.php:360
‪TYPO3\CMS\Core\Versioning\VersionState\DELETE_PLACEHOLDER
‪const DELETE_PLACEHOLDER
Definition: VersionState.php:61
‪TYPO3\CMS\Core\Localization\LanguageService\sL
‪string sL($input)
Definition: LanguageService.php:161
‪TYPO3\CMS\Backend\Controller\PageLayoutController\$modSharedTSconfig
‪array $modSharedTSconfig
Definition: PageLayoutController.php:76
‪TYPO3\CMS\Backend\Controller\PageLayoutController\$moduleTemplate
‪ModuleTemplate $moduleTemplate
Definition: PageLayoutController.php:125
‪TYPO3\CMS\Core\Domain\Repository\PageRepository\SHORTCUT_MODE_RANDOM_SUBPAGE
‪const SHORTCUT_MODE_RANDOM_SUBPAGE
Definition: PageRepository.php:124
‪TYPO3\CMS\Core\Page\JavaScriptModuleInstruction\forRequireJS
‪static self forRequireJS(string $name, string $exportName=null)
Definition: JavaScriptModuleInstruction.php:49
‪TYPO3\CMS\Backend\Template\ModuleTemplate
Definition: ModuleTemplate.php:46
‪TYPO3\CMS\Core\Domain\Repository\PageRepository\SHORTCUT_MODE_FIRST_SUBPAGE
‪const SHORTCUT_MODE_FIRST_SUBPAGE
Definition: PageRepository.php:123
‪TYPO3\CMS\Core\Type\Bitmask\Permission
Definition: Permission.php:26
‪TYPO3\CMS\Backend\Controller\PageLayoutController\getModuleTemplate
‪ModuleTemplate getModuleTemplate()
Definition: PageLayoutController.php:736
‪TYPO3\CMS\Core\Site\Entity\SiteLanguage
Definition: SiteLanguage.php:26
‪TYPO3\CMS\Backend\Controller\PageLayoutController\mainAction
‪ResponseInterface mainAction(ServerRequestInterface $request)
Definition: PageLayoutController.php:169
‪TYPO3\CMS\Core\Type\Enumeration\cast
‪static static cast($value)
Definition: Enumeration.php:186
‪TYPO3\CMS\Backend\Controller\PageLayoutController\$context
‪PageLayoutContext null $context
Definition: PageLayoutController.php:141
‪TYPO3\CMS\Backend\Controller\PageLayoutController
Definition: PageLayoutController.php:58
‪TYPO3\CMS\Backend\Controller\PageLayoutController\menuConfig
‪menuConfig(ServerRequestInterface $request)
Definition: PageLayoutController.php:221
‪TYPO3\CMS\Backend\Routing\UriBuilder
Definition: UriBuilder.php:40
‪TYPO3\CMS\Backend\Controller\PageLayoutController\getPageLinksWhereContentIsAlsoShownOn
‪string getPageLinksWhereContentIsAlsoShownOn($pageId)
Definition: PageLayoutController.php:499
‪TYPO3\CMS\Backend\Module\ModuleLoader
Definition: ModuleLoader.php:34
‪TYPO3\CMS\Backend\Controller\PageLayoutController\$iconFactory
‪IconFactory $iconFactory
Definition: PageLayoutController.php:143
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\doesUserHaveAccess
‪bool doesUserHaveAccess($row, $perms)
Definition: BackendUserAuthentication.php:283
‪TYPO3\CMS\Backend\Controller\PageLayoutController\$pageinfo
‪array bool $pageinfo
Definition: PageLayoutController.php:83
‪TYPO3\CMS\Core\Domain\Repository\PageRepository\DOKTYPE_SPACER
‪const DOKTYPE_SPACER
Definition: PageRepository.php:115
‪TYPO3\CMS\Backend\Controller\PageLayoutController\$moduleTemplateFactory
‪ModuleTemplateFactory $moduleTemplateFactory
Definition: PageLayoutController.php:147
‪TYPO3\CMS\Backend\View\Drawing\BackendLayoutRenderer
Definition: BackendLayoutRenderer.php:47
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\checkLanguageAccess
‪bool checkLanguageAccess($langValue)
Definition: BackendUserAuthentication.php:670
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:62
‪TYPO3\CMS\Core\Type\Bitmask\Permission\PAGE_SHOW
‪const PAGE_SHOW
Definition: Permission.php:35
‪TYPO3\CMS\Backend\Controller\PageLayoutController\$uriBuilder
‪UriBuilder $uriBuilder
Definition: PageLayoutController.php:145
‪TYPO3\CMS\Core\Domain\Repository\PageRepository\DOKTYPE_SYSFOLDER
‪const DOKTYPE_SYSFOLDER
Definition: PageRepository.php:116
‪TYPO3\CMS\Backend\Domain\Model\Element\ImmediateActionElement\MODULE_NAME
‪const MODULE_NAME
Definition: ImmediateActionElement.php:29
‪TYPO3\CMS\Backend\Controller\PageLayoutController\$modTSconfig
‪array $modTSconfig
Definition: PageLayoutController.php:70
‪TYPO3\CMS\Backend\Controller\PageLayoutController\initActions
‪array initActions()
Definition: PageLayoutController.php:299
‪TYPO3\CMS\Core\Versioning\VersionState
Definition: VersionState.php:24
‪TYPO3\CMS\Core\Domain\Repository\PageRepository\SHORTCUT_MODE_PARENT_PAGE
‪const SHORTCUT_MODE_PARENT_PAGE
Definition: PageRepository.php:125
‪TYPO3\CMS\Backend\Controller\PageLayoutController\$pageRepository
‪PageRepository $pageRepository
Definition: PageLayoutController.php:146
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:38
‪TYPO3\CMS\Backend\Controller\PageLayoutController\getBackendUser
‪BackendUserAuthentication getBackendUser()
Definition: PageLayoutController.php:1049
‪TYPO3\CMS\Backend\Controller\PageLayoutController\$MOD_MENU
‪array $MOD_MENU
Definition: PageLayoutController.php:101
‪TYPO3\CMS\Fluid\View\StandaloneView
Definition: StandaloneView.php:31
‪TYPO3\CMS\Core\Type\Bitmask\Permission\CONTENT_EDIT
‪const CONTENT_EDIT
Definition: Permission.php:55
‪TYPO3\CMS\Backend\View\BackendLayoutView
Definition: BackendLayoutView.php:37
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Domain\Repository\PageRepository\SHORTCUT_MODE_NONE
‪const SHORTCUT_MODE_NONE
Definition: PageRepository.php:122
‪TYPO3\CMS\Backend\View\PageLayoutContext
Definition: PageLayoutContext.php:43
‪TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction
Definition: DeletedRestriction.php:28
‪TYPO3\CMS\Backend\Routing\PreviewUriBuilder
Definition: PreviewUriBuilder.php:32
‪TYPO3\CMS\Core\Type\Bitmask\Permission\PAGE_EDIT
‪const PAGE_EDIT
Definition: Permission.php:40
‪TYPO3\CMS\Core\Utility\GeneralUtility\intExplode
‪static int[] intExplode($delimiter, $string, $removeEmptyValues=false, $limit=0)
Definition: GeneralUtility.php:927
‪TYPO3\CMS\Fluid\ViewHelpers\Be\InfoboxViewHelper
Definition: InfoboxViewHelper.php:59
‪TYPO3\CMS\Backend\Controller\PageLayoutController\$id
‪int $id
Definition: PageLayoutController.php:64
‪TYPO3\CMS\Backend\Controller\PageLayoutController\getNumberOfHiddenElements
‪int getNumberOfHiddenElements(bool $isLanguageModeActive)
Definition: PageLayoutController.php:896
‪TYPO3\CMS\Core\Localization\LanguageService\includeLLFile
‪array includeLLFile($fileRef)
Definition: LanguageService.php:271
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:42
‪TYPO3\CMS\Backend\Controller\PageLayoutController\getShortcutTitle
‪string getShortcutTitle()
Definition: PageLayoutController.php:1093
‪TYPO3\CMS\Core\Domain\Repository\PageRepository
Definition: PageRepository.php:53
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Core\Localization\LanguageService\getLL
‪string getLL($index)
Definition: LanguageService.php:121
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50
‪TYPO3\CMS\Backend\Template\Components\ButtonBar\BUTTON_POSITION_RIGHT
‪const BUTTON_POSITION_RIGHT
Definition: ButtonBar.php:41
‪TYPO3\CMS\Backend\Domain\Model\Element\ImmediateActionElement
Definition: ImmediateActionElement.php:28
‪TYPO3\CMS\Backend\Controller
Definition: AboutController.php:16
‪TYPO3\CMS\Backend\Controller\PageLayoutController\$activeColPosList
‪string $activeColPosList
Definition: PageLayoutController.php:115
‪TYPO3\CMS\Backend\Controller\PageLayoutController\getLocalizedPageTitle
‪string getLocalizedPageTitle()
Definition: PageLayoutController.php:525
‪TYPO3\CMS\Core\Domain\Repository\PageRepository\DOKTYPE_RECYCLER
‪const DOKTYPE_RECYCLER
Definition: PageRepository.php:117
‪TYPO3\CMS\Backend\Controller\PageLayoutController\makeActionMenu
‪makeActionMenu()
Definition: PageLayoutController.php:324
‪TYPO3\CMS\Backend\Controller\PageLayoutController\$pageRenderer
‪PageRenderer $pageRenderer
Definition: PageLayoutController.php:144
‪TYPO3\CMS\Core\Http\HtmlResponse
Definition: HtmlResponse.php:26
‪TYPO3\CMS\Core\Database\Query\Restriction\WorkspaceRestriction
Definition: WorkspaceRestriction.php:40