Skip to content
Snippets Groups Projects
Commit 62915d76 authored by Christian Kuhn's avatar Christian Kuhn Committed by Georg Ringer
Browse files

[TASK] Use new TS parser in t3editor

Avoid another TemplateService usage by switching
to the new TypoScript parser logic.

Resolves: #98983
Related: #97816
Releases: main
Change-Id: Ia15c5bfe86d47a9f61779be1e6bea02187ee7d35
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/76389


Tested-by: default avatarcore-ci <typo3@b13.com>
Tested-by: default avatarStefan Bürk <stefan@buerk.tech>
Tested-by: default avatarBenni Mack <benni@typo3.org>
Tested-by: default avatarGeorg Ringer <georg.ringer@gmail.com>
Reviewed-by: default avatarStefan Bürk <stefan@buerk.tech>
Reviewed-by: default avatarBenni Mack <benni@typo3.org>
Reviewed-by: default avatarGeorg Ringer <georg.ringer@gmail.com>
parent 032417a9
No related branches found
No related tags found
No related merge requests found
......@@ -22,22 +22,33 @@ use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Core\Http\HtmlResponse;
use TYPO3\CMS\Core\Http\JsonResponse;
use TYPO3\CMS\Core\Localization\LanguageService;
use TYPO3\CMS\Core\TypoScript\TemplateService;
use TYPO3\CMS\Core\Site\Entity\SiteInterface;
use TYPO3\CMS\Core\TypoScript\IncludeTree\SysTemplateRepository;
use TYPO3\CMS\Core\TypoScript\IncludeTree\Traverser\IncludeTreeTraverser;
use TYPO3\CMS\Core\TypoScript\IncludeTree\TreeBuilder;
use TYPO3\CMS\Core\TypoScript\IncludeTree\Visitor\IncludeTreeAstBuilderVisitor;
use TYPO3\CMS\Core\TypoScript\Tokenizer\LossyTokenizer;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\RootlineUtility;
/**
* Code completion for t3editor
*
* @internal This is a specific Backend Controller implementation and is not considered part of the Public TYPO3 API.
*/
class CodeCompletionController
{
public function __construct(
private readonly SysTemplateRepository $sysTemplateRepository,
private readonly TreeBuilder $treeBuilder,
private readonly LossyTokenizer $lossyTokenizer,
private readonly IncludeTreeTraverser $treeTraverser,
) {
}
/**
* Loads all templates up to a given page id (walking the rootline) and
* cleans parts that are not required for the t3editor codecompletion.
*
* @param ServerRequestInterface $request
* @return ResponseInterface
* cleans parts that are not required for the t3editor code-completion.
*/
public function loadCompletions(ServerRequestInterface $request): ResponseInterface
{
......@@ -51,39 +62,35 @@ class CodeCompletionController
return new HtmlResponse($this->getLanguageService()->sL('LLL:EXT:t3editor/Resources/Private/Language/locallang.xlf:pageIDInteger'), 500);
}
// Fetch the templates
return new JsonResponse($this->getMergedTemplates($pageId));
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 t3editor in typoscript mode is fired.
* JS then knows the object types and can auto-complete on CTRL+space.
*
* @todo oliver@typo3.org: Refactor this method and comment what's going on there
* @param int $pageId
* @return array Setup part of merged template records
*/
protected function getMergedTemplates($pageId)
protected function getMergedTemplates(int $pageId, ServerRequestInterface $request): array
{
$tsParser = GeneralUtility::makeInstance(TemplateService::class);
$rootLine = GeneralUtility::makeInstance(RootlineUtility::class, $pageId)->get();
// This generates the constants/config + hierarchy info for the template.
$tsParser->runThroughTemplates($rootLine);
// ts-setup & ts-constants of the currently edited template should not be included
// therefore we have to delete the last template from the stack
array_pop($tsParser->config);
array_pop($tsParser->constants);
$tsParser->generateConfig();
$result = $this->treeWalkCleanup($tsParser->setup);
$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->addVisitor($setupAstBuilderVisitor);
$this->treeTraverser->traverse($setupIncludeTree);
$setupAst = $setupAstBuilderVisitor->getAst();
$result = $this->treeWalkCleanup($setupAst->toArray());
return $result;
}
/**
* Walks through a tree of TypoScript configuration and cleans it up.
*
* @TODO oliver@typo3.org: Define and comment why this is necessary and exactly happens below
* @param array $treeBranch TypoScript configuration or sub branch of it
* @return array Cleaned TypoScript branch
* Walks through a tree of TypoScript configuration and prepares it for JS.
*/
private function treeWalkCleanup(array $treeBranch)
private function treeWalkCleanup(array $treeBranch): array
{
$cleanedTreeBranch = [];
foreach ($treeBranch as $key => $value) {
......
......@@ -11,3 +11,6 @@ services:
tags:
- name: event.listener
identifier: 'typo3-t3editor/initialize-t3editor-in-edit-file-form'
TYPO3\CMS\T3editor\Controller\CodeCompletionController:
tags: ['backend.controller']
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment