getBackendUser(); $currentModule = $request->getAttribute('module'); $currentModuleIdentifier = $currentModule->getIdentifier(); $pageUid = (int)($request->getQueryParams()['id'] ?? 0); $pageRecord = BackendUtility::readPageAccess($pageUid, '1=1') ?: []; if ($pageUid > 0 && empty($pageRecord)) { // Redirect to records overview of page 0 if page could not be determined. // Edge case if page has been removed meanwhile. BackendUtility::setUpdateSignal('updatePageTree'); return new RedirectResponse($this->uriBuilder->buildUriFromRoute('web_typoscript_recordsoverview')); } $moduleData = $request->getAttribute('moduleData'); if ($moduleData->cleanUp([])) { $backendUser->pushModuleData($currentModuleIdentifier, $moduleData->toArray()); } $pagesWithTemplates = []; $sites = $this->siteFinder->getAllSites(); foreach ($sites as $site) { if (!$site->isTypoScriptRoot()) { continue; } $rootPageId = $site->getRootPageId(); $additionalFieldsForRootline = ['sorting', 'shortcut']; $rootline = array_reverse(BackendUtility::BEgetRootLine($rootPageId, '', true, $additionalFieldsForRootline)); if ($rootline !== []) { $pagesWithTemplates = $this->setInPageArray($pagesWithTemplates, $rootline, [ 'type' => 'site', 'root' => 1, 'clear' => 1, 'pid' => $rootPageId, 'sorting' => -1, 'uid' => -1, 'title' => $site->getConfiguration()['websiteTitle'] ?? '', 'site' => $site, ]); } } $queryBuilder = $this->connectionPool->getQueryBuilderForTable('sys_template'); $queryBuilder->getRestrictions()->removeAll() ->add(GeneralUtility::makeInstance(DeletedRestriction::class)); $result = $queryBuilder ->select('uid', 'pid', 'title', 'root', 'hidden', 'starttime', 'endtime') ->from('sys_template') // sys_template shouldn't exist pid 0, they'll be ignored in FE anyway. Ignore them. ->where($queryBuilder->expr()->gt('pid', $queryBuilder->createNamedParameter(0, Connection::PARAM_INT))) ->orderBy('sys_template.pid') ->addOrderBy('sys_template.sorting') ->executeQuery(); while ($record = $result->fetchAssociative()) { $additionalFieldsForRootline = ['sorting', 'shortcut']; $rootline = array_reverse(BackendUtility::BEgetRootLine($record['pid'], '', true, $additionalFieldsForRootline)); if ($rootline !== []) { $pagesWithTemplates = $this->setInPageArray($pagesWithTemplates, $rootline, [...$record, 'type' => 'sys_template']); } } $view = $this->moduleTemplateFactory->create($request); $view->setTitle($this->getLanguageService()->sL($currentModule->getTitle()), ''); $view->getDocHeaderComponent()->setPageBreadcrumb($pageRecord); $this->addPreviewButtonToDocHeader($view, $pageRecord); $this->addShortcutButtonToDocHeader($view, $currentModuleIdentifier, $pageRecord, $pageUid, $this->getLanguageService()->sL('LLL:EXT:tstemplate/Resources/Private/Language/locallang_overview.xlf:typoscriptRecords.title')); if ($pageUid !== 0) { $view->makeDocHeaderModuleMenu(['id' => $pageUid]); } $view->assign('pageTree', $pagesWithTemplates); return $view->renderResponse('TemplateRecordsOverview'); } /** * Recursively add template row in pages tree array by given pages rootline to prepare tree rendering. * @param non-empty-array $rootline */ private function setInPageArray(array $pages, array $rootline, array $row): array { if (!$rootline[0]['uid']) { // Skip 'root' array_shift($rootline); } $currentRootlineElement = current($rootline); if (empty($pages[$currentRootlineElement['uid']])) { // Page not in tree yet. Add it. $pages[$currentRootlineElement['uid']] = $currentRootlineElement; } array_shift($rootline); if (empty($rootline)) { // Last rootline element: Add template row $pages[$currentRootlineElement['uid']]['_templates'][] = $row; } else { // Recurse into sub array $pages[$currentRootlineElement['uid']]['_nodes'] ??= []; $pages[$currentRootlineElement['uid']]['_nodes'] = $this->setInPageArray($pages[$currentRootlineElement['uid']]['_nodes'], $rootline, $row); } // Tree node sorting by pages sorting field uasort($pages, static fn($a, $b) => $a['sorting'] - $b['sorting']); return $pages; } }