isAdmin()) { return new HtmlResponse($this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_codeeditor.xlf:noPermission'), 500); } $pageId = (int)($request->getParsedBody()['pageId'] ?? $request->getQueryParams()['pageId']); // Check whether there is a pageId given: if (!$pageId) { return new HtmlResponse($this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_codeeditor.xlf:pageIDInteger'), 500); } // Fetch the templates return new JsonResponse($this->getMergedTemplates($pageId, $request)); } /** * Gets merged templates by walking the rootline to a given page id. * This is loaded once via ajax when a code editor in typoscript mode is fired. * JS then knows the object types and can auto-complete on CTRL+space. * * @return array Setup part of merged template records */ protected function getMergedTemplates(int $pageId, ServerRequestInterface $request): array { $rootLine = GeneralUtility::makeInstance(RootlineUtility::class, $pageId)->get(); $sysTemplateRows = $this->sysTemplateRepository->getSysTemplateRowsByRootline($rootLine, $request); /** @var SiteInterface|null $site */ $site = $request->getAttribute('site'); $setupIncludeTree = $this->treeBuilder->getTreeBySysTemplateRowsAndSite('setup', $sysTemplateRows, $this->lossyTokenizer, $site); $setupAstBuilderVisitor = GeneralUtility::makeInstance(IncludeTreeAstBuilderVisitor::class); $this->treeTraverser->traverse($setupIncludeTree, [$setupAstBuilderVisitor]); $setupAst = $setupAstBuilderVisitor->getAst(); return $this->treeWalkCleanup($setupAst->toArray()); } /** * Walks through a tree of TypoScript configuration and prepares it for JS. */ private function treeWalkCleanup(array $treeBranch): array { $cleanedTreeBranch = []; foreach ($treeBranch as $key => $value) { $key = is_int($key) ? (string)$key : $key; //type definition or value-assignment if (substr($key, -1) !== '.') { if ($value != '') { if (mb_strlen($value) > 20) { $value = mb_substr($value, 0, 20); } if (!isset($cleanedTreeBranch[$key])) { $cleanedTreeBranch[$key] = []; } $cleanedTreeBranch[$key]['v'] = $value; } } else { // subtree (definition of properties) $subBranch = $this->treeWalkCleanup($value); if ($subBranch) { if (substr($key, -1) === '.') { $key = rtrim($key, '.'); } if (!isset($cleanedTreeBranch[$key])) { $cleanedTreeBranch[$key] = []; } $cleanedTreeBranch[$key]['c'] = $subBranch; } } } return $cleanedTreeBranch; } protected function getLanguageService(): LanguageService { return $GLOBALS['LANG']; } }