‪TYPO3CMS  ‪main
SysTemplateTreeBuilder.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 Symfony\Component\DependencyInjection\Attribute\Autoconfigure;
27 use TYPO3\CMS\Core\Package\PackageManager;
46 
74 #[Autoconfigure(public: true)]
76 {
83  private array ‪$includedSysTemplateUids = [];
84 
86  private string ‪$type;
87 
89  private ?‪PhpFrontend ‪$cache = null;
90 
91  private bool ‪$enableStaticMagicIncludes = false;
92 
93  public function ‪__construct(
94  private readonly ‪ConnectionPool $connectionPool,
95  private readonly PackageManager $packageManager,
96  private readonly ‪Context $context,
97  private readonly ‪TreeFromLineStreamBuilder $treeFromTokenStreamBuilder,
98  private readonly ‪SetRegistry $setRegistry,
99  ) {}
100 
105  string ‪$type,
106  array $sysTemplateRows,
108  ?‪SiteInterface $site = null,
109  ?‪PhpFrontend ‪$cache = null
110  ): ‪RootInclude {
111  if (!in_array(‪$type, ['constants', 'setup'], true)) {
112  throw new \RuntimeException('type must be either constants or setup', 1653737656);
113  }
114  $this->tokenizer = ‪$tokenizer;
115  $this->cache = ‪$cache;
116  $this->type = ‪$type;
117  $this->includedSysTemplateUids = [];
118 
119  $rootNode = new ‪RootInclude();
120 
121  $siteIsTypoScriptRoot = $site instanceof ‪Site ? $site->‪isTypoScriptRoot() : false;
122  if ($siteIsTypoScriptRoot) {
123  $this->enableStaticMagicIncludes = false;
124  $cacheIdentifier = 'site-template-' . $this->type . '-' . $site->getIdentifier();
125  $includeNode = $this->cache?->require($cacheIdentifier) ?: null;
126  $includeNode ??= $this->‪createSiteTemplateInclude($site, $cacheIdentifier);
127  $rootNode->addChild($includeNode);
128  }
129 
130  if (empty($sysTemplateRows)) {
131  return $rootNode;
132  }
133 
134  $this->enableStaticMagicIncludes = true;
135  // Convenience code: Usually, at least one sys_template records needs to have 'clear' set. This resets
136  // the AST and triggers inclusion of "globals" TypoScript. When integrators missed to set the clear flags,
137  // important globals TypoScript is not loaded, leading to pretty hard to find issues in Frontend
138  // rendering. Since the details of the 'clear' flags are rather complex anyway, this code scans the given
139  // sys_template records if the flag is set somewhere and if not, actively sets it dynamically for the
140  // first templates. As a result, integrators do not need to think about the 'clear' flags at all for
141  // simple instances, it 'just works'.
142  $atLeastOneSysTemplateRowHasClearFlag = $siteIsTypoScriptRoot;
143  if (!$atLeastOneSysTemplateRowHasClearFlag) {
144  foreach ($sysTemplateRows as $sysTemplateRow) {
145  if (($this->type === 'constants' && $sysTemplateRow['clear'] & 1) || ($this->type === 'setup' && $sysTemplateRow['clear'] & 2)) {
146  $atLeastOneSysTemplateRowHasClearFlag = true;
147  break;
148  }
149  }
150  $firstRow = reset($sysTemplateRows);
151  $firstRow['clear'] = $this->type === 'constants' ? 1 : 2;
152  $sysTemplateRows[array_key_first($sysTemplateRows)] = $firstRow;
153  }
154 
155  foreach ($sysTemplateRows as $sysTemplateRow) {
156  $cacheIdentifier = 'sys-template-' . $this->type . '-' . $this->‪getSysTemplateRowIdentifier($sysTemplateRow, $site);
157  if ($this->cache) {
158  // Get from cache if possible
159  $includeNode = $this->cache->require($cacheIdentifier);
160  if ($includeNode) {
161  $rootNode->addChild($includeNode);
162  continue;
163  }
164  }
165  $includeNode = new ‪SysTemplateInclude();
166  ‪$name = '[sys_template:' . $sysTemplateRow['uid'] . '] ' . $sysTemplateRow['title'];
167  $includeNode->setName(‪$name);
168  $includeNode->setPid((int)$sysTemplateRow['pid']);
169  if ($this->type === 'constants') {
170  $includeNode->setLineStream($this->tokenizer->tokenize($sysTemplateRow['constants'] ?? ''));
171  } else {
172  $includeNode->setLineStream($this->tokenizer->tokenize($sysTemplateRow['config'] ?? ''));
173  }
174  if ($sysTemplateRow['root']) {
175  $includeNode->setRoot(true);
176  }
177  $clear = $sysTemplateRow['clear'];
178  if (($this->type === 'constants' && $clear & 1) || ($this->type === 'setup' && $clear & 2)) {
179  $includeNode->setClear(true);
180  }
181  $this->‪handleSysTemplateRecordInclude($includeNode, $sysTemplateRow, $site);
182  $this->treeFromTokenStreamBuilder->buildTree($includeNode, $this->type, $this->tokenizer);
183  $this->cache?->set($cacheIdentifier, $this->‪prepareNodeForCache($includeNode));
184  $rootNode->addChild($includeNode);
185  }
186 
187  return $rootNode;
188  }
189 
191  ‪Site $site,
192  string $cacheIdentifier
194  $includeNode = new ‪SiteTemplateInclude();
195  $includeNode->setRoot(true);
196  $includeNode->setClear(true);
197 
198  $this->‪addScopedStaticsFromGlobals($includeNode, 'siteSets');
199  $this->‪addContentRenderingFromGlobals($includeNode, 'TYPO3_CONF_VARS defaultContentRendering');
200 
201  $sets = $this->setRegistry->getSets(...$site->getSets());
202  if (count($sets) > 0) {
203  $includeSetInclude = new ‪IncludeStaticFileFileInclude();
204  $includeSetInclude->setName('site:' . $site->‪getIdentifier() . ':sets');
205  $includeSetInclude->setPath('site:' . $site->‪getIdentifier() . '/');
206  foreach ($sets as $set) {
207  $this->‪handleSetInclude($includeSetInclude, rtrim($set->typoscript, '/') . '/', 'set:' . $set->name);
208  }
209  $includeNode->addChild($includeSetInclude);
210  }
211 
212  if ($this->type === 'constants') {
213  $this->‪addDefaultTypoScriptConstantsFromSite($includeNode, $site);
214  }
215 
216  $siteTypoScript = $site->‪getTypoScript();
217  $content = $this->type === 'constants' ? $siteTypoScript?->constants : $siteTypoScript?->setup;
218  if ($content !== null) {
219  $includeNode->setLineStream($this->tokenizer->tokenize($content));
220  $this->treeFromTokenStreamBuilder->buildTree($includeNode, $this->type, $this->tokenizer, false);
221  }
222 
223  $includeNode->setName(sprintf(
224  '[site:%s%s] %s',
225  $site->‪getIdentifier(),
226  $content === null ? '' : '/' . $this->type . '.typoscript',
227  $site->‪getConfiguration()['websiteTitle'] ?? ''
228  ));
229 
230  $this->cache?->set($cacheIdentifier, $this->‪prepareNodeForCache($includeNode));
231 
232  return $includeNode;
233  }
234 
235  private function ‪handleSetInclude(‪IncludeInterface $parentNode, string $path, string $label): void
236  {
237  $path = GeneralUtility::getFileAbsFileName($path);
238 
239  // '/.../my_extension/Configuration/TypoScript/MyStaticInclude/include_static_file.txt'
240  $includeStaticFileFileIncludePath = $path . 'include_static_file.txt';
241  if (file_exists($path . 'include_static_file.txt')) {
242  $includeStaticFileFileInclude = new ‪IncludeStaticFileFileInclude();
243  //$name = 'EXT:' . $extensionKey . '/' . $pathSegmentWithAppendedSlash . 'include_static_file.txt';
244  //$includeStaticFileFileInclude->setName($name);
245  $includeStaticFileFileInclude->setName($label . ':include_static_file.txt');
246  $includeStaticFileFileInclude->setPath($path . 'include_static_file.txt');
247  $parentNode->‪addChild($includeStaticFileFileInclude);
248  $includeStaticFileFileIncludeContent = (string)file_get_contents($includeStaticFileFileIncludePath);
249  // @todo: There is no array_unique() for DB based include_static_file content?!
250  $includeStaticFileFileIncludeArray = array_unique(‪GeneralUtility::trimExplode(',', $includeStaticFileFileIncludeContent, true));
251  foreach ($includeStaticFileFileIncludeArray as $includeStaticFileFileIncludeString) {
252  $this->‪handleSingleIncludeStaticFile($includeStaticFileFileInclude, $includeStaticFileFileIncludeString);
253  }
254  }
255 
256  $fileName = $path . $this->type . '.typoscript';
257  if (file_exists($fileName)) {
258  $fileContent = file_get_contents($fileName);
259  $fileNode = new ‪FileInclude();
260  $fileNode->setName($label . ':' . $this->type . '.typoscript');
261  $fileNode->setPath($fileName);
262  $fileNode->setLineStream($this->tokenizer->tokenize($fileContent));
263  $this->treeFromTokenStreamBuilder->buildTree($fileNode, $this->type, $this->tokenizer, false);
264  $parentNode->‪addChild($fileNode);
265  }
266  }
267 
271  private function ‪handleSysTemplateRecordInclude(‪IncludeInterface $parentNode, array $row, ?‪SiteInterface $site): void
272  {
273  $this->includedSysTemplateUids[] = (int)$row['uid'];
274 
275  $isRoot = (bool)$row['root'];
276  $clearConstants = (int)$row['clear'] & 1;
277  $clearSetup = (int)$row['clear'] & 2;
278  $staticFileMode = (int)($row['static_file_mode']);
279  $includeStaticAfterBasedOn = (bool)$row['includeStaticAfterBasedOn'];
280 
281  if ($this->type === 'constants' && $clearConstants) {
282  $this->‪addDefaultTypoScriptFromGlobals($parentNode);
283  $this->‪addDefaultTypoScriptConstantsFromSite($parentNode, $site);
284  }
285  if ($this->type === 'setup' && $clearSetup) {
286  $this->‪addDefaultTypoScriptFromGlobals($parentNode);
287  }
288  if ($staticFileMode === 3 && $isRoot) {
289  $this->‪addExtensionStatics($parentNode);
290  }
291  if (!$includeStaticAfterBasedOn) {
292  $this->‪handleIncludeStaticFileArray($parentNode, (string)$row['include_static_file']);
293  }
294  if (!empty($row['basedOn'])) {
295  $this->‪handleIncludeBasedOnTemplates($parentNode, (string)$row['basedOn'], $site);
296  }
297  if ($includeStaticAfterBasedOn) {
298  $this->‪handleIncludeStaticFileArray($parentNode, (string)$row['include_static_file']);
299  }
300  if ($staticFileMode === 1 || ($staticFileMode === 0 && $isRoot)) {
301  $this->‪addExtensionStatics($parentNode);
302  }
303  }
304 
318  private function ‪handleIncludeStaticFileArray(‪IncludeInterface $parentNode, string $includeStaticFileString): void
319  {
320  $includeStaticFileIncludeArray = ‪GeneralUtility::trimExplode(',', $includeStaticFileString, true);
321  foreach ($includeStaticFileIncludeArray as $includeStaticFile) {
322  $cacheIdentifier = preg_replace('/[^[:alnum:]]/u', '-', mb_strtolower($includeStaticFile)) . '-' . ‪$this->type;
323  if ($this->cache) {
324  $node = $this->cache->require($cacheIdentifier);
325  if ($node) {
326  $parentNode->‪addChild($node);
327  continue;
328  }
329  }
331  $node->setName($includeStaticFile);
332  $this->‪handleSingleIncludeStaticFile($node, $includeStaticFile);
333  $this->cache?->set($cacheIdentifier, $this->‪prepareNodeForCache($node));
334  $parentNode->‪addChild($node);
335  }
336  }
337 
343  private function ‪handleIncludeBasedOnTemplates(‪IncludeInterface $parentNode, string $basedOnList, ?‪SiteInterface $site): void
344  {
345  $basedOnTemplateUids = ‪GeneralUtility::intExplode(',', $basedOnList, true);
346  // Filter uids that have been handled already.
347  $basedOnTemplateUids = array_diff($basedOnTemplateUids, $this->includedSysTemplateUids);
348  if (empty($basedOnTemplateUids)) {
349  return;
350  }
351 
352  $basedOnTemplateRows = $this->‪getBasedOnSysTemplateRowsFromDatabase($basedOnTemplateUids);
353 
354  foreach ($basedOnTemplateUids as $basedOnTemplateUid) {
355  if (is_array($basedOnTemplateRows[$basedOnTemplateUid] ?? false)) {
356  $sysTemplateRow = $basedOnTemplateRows[$basedOnTemplateUid];
357  $this->includedSysTemplateUids[] = (int)$sysTemplateRow['uid'];
358  $includeNode = new ‪SysTemplateInclude();
359  ‪$name = '[sys_template:' . $sysTemplateRow['uid'] . '] ' . $sysTemplateRow['title'];
360  $includeNode->setName(‪$name);
361  $includeNode->setPid((int)$sysTemplateRow['pid']);
362  if ($this->type === 'constants') {
363  $includeNode->setLineStream($this->tokenizer->tokenize($sysTemplateRow['constants'] ?? ''));
364  } else {
365  $includeNode->setLineStream($this->tokenizer->tokenize($sysTemplateRow['config'] ?? ''));
366  }
367  $this->treeFromTokenStreamBuilder->buildTree($includeNode, $this->type, $this->tokenizer);
368  if ($sysTemplateRow['root']) {
369  $includeNode->setRoot(true);
370  }
371  $clear = $sysTemplateRow['clear'];
372  if (($this->type === 'constants' && $clear & 1)
373  || ($this->type === 'setup' && $clear & 2)
374  ) {
375  $includeNode->setClear(true);
376  }
377  $parentNode->‪addChild($includeNode);
378  $this->‪handleSysTemplateRecordInclude($includeNode, $sysTemplateRow, $site);
379  }
380  }
381  }
382 
391  private function ‪handleSingleIncludeStaticFile(‪IncludeInterface $parentNode, $includeStaticFileString): void
392  {
393  if (!‪PathUtility::isExtensionPath($includeStaticFileString)) {
394  // Must start with 'EXT:'
395  throw new \RuntimeException(
396  'Single include_static_file does not start with "EXT:": ' . $includeStaticFileString,
397  1651137904
398  );
399  }
400 
401  // Cut off 'EXT:'
402  $includeStaticFileWithoutExt = substr($includeStaticFileString, 4);
403  $includeStaticFileExtKeyAndPath = ‪GeneralUtility::trimExplode('/', $includeStaticFileWithoutExt, true, 2);
404  if (empty($includeStaticFileExtKeyAndPath[0]) || empty($includeStaticFileExtKeyAndPath[1])) {
405  throw new \RuntimeException(
406  'Syntax of static includes is "EXT:extension_key/Path". Usually enforced as such by ExtensionManagementUtility::addStaticFile',
407  1651138603
408  );
409  }
410  $extensionKey = $includeStaticFileExtKeyAndPath[0];
411  if (!‪ExtensionManagementUtility::isLoaded($extensionKey)) {
412  return;
413  }
414  // example: '/.../my_extension/Configuration/TypoScript/MyStaticInclude/'
415  $pathSegmentWithAppendedSlash = rtrim($includeStaticFileExtKeyAndPath[1]) . '/';
416  $path = ‪ExtensionManagementUtility::extPath($extensionKey, $pathSegmentWithAppendedSlash);
417 
418  // '/.../my_extension/Configuration/TypoScript/MyStaticInclude/include_static_file.txt'
419  $includeStaticFileFileIncludePath = $path . 'include_static_file.txt';
420  if (file_exists($path . 'include_static_file.txt')) {
421  $includeStaticFileFileInclude = new ‪IncludeStaticFileFileInclude();
422  ‪$name = 'EXT:' . $extensionKey . '/' . $pathSegmentWithAppendedSlash . 'include_static_file.txt';
423  $includeStaticFileFileInclude->setName(‪$name);
424  $includeStaticFileFileInclude->setPath($includeStaticFileString);
425  $parentNode->‪addChild($includeStaticFileFileInclude);
426  $includeStaticFileFileIncludeContent = (string)file_get_contents($includeStaticFileFileIncludePath);
427  // @todo: There is no array_unique() for DB based include_static_file content?!
428  $includeStaticFileFileIncludeArray = array_unique(‪GeneralUtility::trimExplode(',', $includeStaticFileFileIncludeContent, true));
429  foreach ($includeStaticFileFileIncludeArray as $includeStaticFileFileIncludeString) {
430  $this->‪handleSingleIncludeStaticFile($includeStaticFileFileInclude, $includeStaticFileFileIncludeString);
431  }
432  }
433 
434  $extensions = ['.typoscript', '.ts', '.txt'];
435  foreach ($extensions as $extension) {
436  // '/.../my_extension/Configuration/TypoScript/MyStaticInclude/[constants|setup]' plus one of the allowed extensions like '.typoscript'
437  $fileName = $path . $this->type . $extension;
438  if (file_exists($fileName)) {
439  $fileContent = file_get_contents($fileName);
440  $fileNode = new ‪FileInclude();
441  ‪$name = 'EXT:' . $extensionKey . '/' . $pathSegmentWithAppendedSlash . $this->type . $extension;
442  $fileNode->setName(‪$name);
443  $fileNode->setPath(‪$name);
444  $fileNode->setLineStream($this->tokenizer->tokenize($fileContent));
445  $this->treeFromTokenStreamBuilder->buildTree($fileNode, $this->type, $this->tokenizer);
446  $parentNode->‪addChild($fileNode);
447  }
448  }
449 
450  if ($this->enableStaticMagicIncludes) {
451  $extensionKeyWithoutUnderscores = str_replace('_', '', $extensionKey);
452  $this->‪addStaticMagicFromGlobals($parentNode, $extensionKeyWithoutUnderscores . '/' . $pathSegmentWithAppendedSlash);
453  }
454  }
455 
460  private function ‪addExtensionStatics(‪IncludeInterface $parentNode): void
461  {
462  foreach ($this->packageManager->getActivePackages() as $package) {
463  $extensionKey = $package->getPackageKey();
464  $extensionKeyWithoutUnderscores = str_replace('_', '', $extensionKey);
465  $file = $package->getPackagePath() . 'ext_typoscript_' . $this->type . '.typoscript';
466  if (file_exists($file)) {
467  ‪$identifier = preg_replace('/[^[:alnum:]]/u', '-', 'ext-' . $extensionKey . '-ext-typoscript-' . $this->type . '-typoscript');
468  if ($this->cache) {
469  $node = $this->cache->require(‪$identifier);
470  if ($node) {
471  $parentNode->‪addChild($node);
472  continue;
473  }
474  }
475  $fileContent = file_get_contents($file);
476  $this->‪addStaticMagicFromGlobals($parentNode, $extensionKeyWithoutUnderscores);
477  $node = new ‪ExtensionStaticInclude();
478  $node->setName('EXT:' . $extensionKey . '/ext_typoscript_' . $this->type . '.typoscript');
479  $node->setPath('EXT:' . $extensionKey . '/ext_typoscript_' . $this->type . '.typoscript');
480  $node->setLineStream($this->tokenizer->tokenize($fileContent));
481  $this->treeFromTokenStreamBuilder->buildTree($node, $this->type, $this->tokenizer);
482  $this->cache?->set(‪$identifier, $this->‪prepareNodeForCache($node));
483  $parentNode->‪addChild($node);
484  }
485  }
486  }
487 
492  private function ‪addDefaultTypoScriptFromGlobals(‪IncludeInterface $parentConstantNode): void
493  {
494  $defaultTypoScriptConstants = ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_' . ‪$this->type] ?? '';
495  if (!empty($defaultTypoScriptConstants)) {
496  $cacheIdentifier = 'globals-defaulttyposcript-' . $this->type . '-' . hash('xxh3', $defaultTypoScriptConstants);
497  if ($this->cache) {
498  $node = $this->cache->require($cacheIdentifier);
499  if ($node) {
500  $parentConstantNode->‪addChild($node);
501  return;
502  }
503  }
504  $node = new ‪DefaultTypoScriptInclude();
505  $node->setName('TYPO3_CONF_VARS[\'FE\'][\'defaultTypoScript_' . $this->type . '\']');
506  $node->setLineStream($this->tokenizer->tokenize($defaultTypoScriptConstants));
507  $this->treeFromTokenStreamBuilder->buildTree($node, $this->type, $this->tokenizer);
508  $this->cache?->set($cacheIdentifier, $this->prepareNodeForCache($node));
509  $parentConstantNode->addChild($node);
510  }
511  }
512 
516  private function addDefaultTypoScriptConstantsFromSite(IncludeInterface $parentConstantNode, ?SiteInterface $site): void
517  {
518  if (!$site instanceof Site) {
519  return;
520  }
521  $siteConstants = '';
522  $siteSettings = $site->getSettings();
523  if ($siteSettings->isEmpty()) {
524  return;
525  }
526  $cacheIdentifier = 'site-constants-' . hash('xxh3', json_encode($siteSettings, JSON_THROW_ON_ERROR));
527  if ($this->cache) {
528  $node = $this->cache->require($cacheIdentifier);
529  if ($node) {
530  $parentConstantNode->addChild($node);
531  return;
532  }
533  }
534  $siteSettings = $siteSettings->getAllFlat();
535  foreach ($siteSettings as $nodeIdentifier => $value) {
536  $siteConstants .= $nodeIdentifier . ' = ' . $value . LF;
537  }
538  $node = new SiteInclude();
539  $node->setName('‪Site constants settings of site "' . $site->getIdentifier() . '"');
540  $node->setLineStream($this->tokenizer->tokenize($siteConstants));
541  $this->cache?->set($cacheIdentifier, $this->prepareNodeForCache($node));
542  $parentConstantNode->addChild($node);
543  }
544 
545  private function addScopedStaticsFromGlobals(IncludeInterface $parentNode, string $identifier): void
546  {
547  // defaultTypoScript_constants.' or defaultTypoScript_setup.'
548  $source = $GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_' . $this->type . '.'][$identifier] ?? null;
549  if (!empty($source)) {
550  $node = new DefaultTypoScriptMagicKeyInclude();
551  $node->setName('TYPO3_CONF_VARS globals_defaultTypoScript_' . $this->type . '.' . $identifier);
552  $node->setLineStream($this->tokenizer->tokenize($source));
553  $this->treeFromTokenStreamBuilder->buildTree($node, $this->type, $this->tokenizer);
554  $parentNode->addChild($node);
555  }
556  }
557 
558  private function addContentRenderingFromGlobals(IncludeInterface $parentNode, string $name): void
559  {
560  $source = $GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_' . $this->type . '.']['defaultContentRendering'] ?? null;
561  if (!empty($source)) {
562  $node = new DefaultTypoScriptMagicKeyInclude();
563  $node->setName($name);
564  $node->setLineStream($this->tokenizer->tokenize($source));
565  $this->treeFromTokenStreamBuilder->buildTree($node, $this->type, $this->tokenizer);
566  $parentNode->addChild($node);
567  }
568  }
569 
574  private function addStaticMagicFromGlobals(IncludeInterface $parentNode, string $identifier): void
575  {
576  $this->addScopedStaticsFromGlobals($parentNode, $identifier);
577  // If this is a template of type "default content rendering", see if other extensions have added their TypoScript that should be included.
578  if (in_array($identifier, $GLOBALS['TYPO3_CONF_VARS']['FE']['contentRenderingTemplates'], true)) {
579  $this->addContentRenderingFromGlobals($parentNode, 'TYPO3_CONF_VARS defaultContentRendering ' . $this->type . ' for ' . $identifier);
580  }
581  }
582 
589  private function getBasedOnSysTemplateRowsFromDatabase(array $basedOnTemplateUids): array
590  {
591  $queryBuilder = $this->connectionPool->getQueryBuilderForTable('sys_template');
592  $queryBuilder->setRestrictions($this->getSysTemplateQueryRestrictionContainer());
593  $basedOnTemplateRows = $queryBuilder
594  ->select('*')
595  ->from('sys_template')
596  ->where(
597  $queryBuilder->expr()->in(
598  'uid',
599  $queryBuilder->createNamedParameter($basedOnTemplateUids, Connection::PARAM_INT_ARRAY)
600  )
601  )
602  ->executeQuery()
603  ->fetchAllAssociative();
604  return array_combine(array_column($basedOnTemplateRows, 'uid'), $basedOnTemplateRows);
605  }
606 
621  private function getSysTemplateRowIdentifier(array $sysTemplateRow, ?SiteInterface $site): string
622  {
623  $siteIdentifier = 'dummy';
624  if ($this->type === 'constants' && ((int)$sysTemplateRow['clear'] & 1) && $site !== null) {
625  $siteIdentifier = $site->getIdentifier();
626  }
627  $cacheRelevantSysTemplateRowValues = [
628  'root' => (int)$sysTemplateRow['root'],
629  'clear' => (int)$sysTemplateRow['clear'],
630  'include_static_file' => (string)$sysTemplateRow['include_static_file'],
631  'constants' => (string)$sysTemplateRow['constants'],
632  'config' => (string)$sysTemplateRow['config'],
633  'basedOn' => (string)$sysTemplateRow['basedOn'],
634  'includeStaticAfterBasedOn' => (int)$sysTemplateRow['includeStaticAfterBasedOn'],
635  'static_file_mode' => (int)$sysTemplateRow['static_file_mode'],
636  'siteIdentifier' => $siteIdentifier,
637  ];
638  return hash('xxh3', json_encode($cacheRelevantSysTemplateRowValues, JSON_THROW_ON_ERROR));
639  }
640 
641  private function prepareNodeForCache(IncludeInterface $node): string
642  {
643  return 'return unserialize(\'' . addcslashes(serialize($node), '\'\\') . '\');';
644  }
645 
651  {
652  $restrictionContainer = GeneralUtility::makeInstance(DefaultRestrictionContainer::class);
653  if ($this->context->getPropertyFromAspect('visibility', 'includeHiddenContent', false)) {
654  $restrictionContainer->removeByType(HiddenRestriction::class);
655  }
656  return $restrictionContainer;
657  }
658 }
‪TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\IncludeStaticFileFileInclude
Definition: IncludeStaticFileFileInclude.php:26
‪TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction
Definition: HiddenRestriction.php:27
‪TYPO3\CMS\Core\Site\Entity\SiteInterface
Definition: SiteInterface.php:26
‪TYPO3\CMS\Core\Utility\PathUtility\isExtensionPath
‪static isExtensionPath(string $path)
Definition: PathUtility.php:118
‪TYPO3\CMS\Core\Utility\PathUtility
Definition: PathUtility.php:27
‪TYPO3\CMS\Core\TypoScript\IncludeTree\SysTemplateTreeBuilder\addScopedStaticsFromGlobals
‪addScopedStaticsFromGlobals(IncludeInterface $parentNode, string $identifier)
Definition: SysTemplateTreeBuilder.php:545
‪TYPO3\CMS\Core\TypoScript\IncludeTree\SysTemplateTreeBuilder\$cache
‪PhpFrontend $cache
Definition: SysTemplateTreeBuilder.php:89
‪TYPO3\CMS\Core\TypoScript\IncludeTree\SysTemplateTreeBuilder\getTreeBySysTemplateRowsAndSite
‪getTreeBySysTemplateRowsAndSite(string $type, array $sysTemplateRows, TokenizerInterface $tokenizer, ?SiteInterface $site=null, ?PhpFrontend $cache=null)
Definition: SysTemplateTreeBuilder.php:104
‪TYPO3\CMS\Core\TypoScript\IncludeTree\SysTemplateTreeBuilder\$type
‪string $type
Definition: SysTemplateTreeBuilder.php:86
‪TYPO3\CMS\Core\TypoScript\IncludeTree
‪TYPO3\CMS\Core\Cache\Frontend\PhpFrontend
Definition: PhpFrontend.php:25
‪TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\SiteTemplateInclude
Definition: SiteTemplateInclude.php:27
‪TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\ExtensionStaticInclude
Definition: ExtensionStaticInclude.php:26
‪TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\IncludeInterface\addChild
‪addChild(IncludeInterface $node)
‪TYPO3\CMS\Core\TypoScript\IncludeTree\SysTemplateTreeBuilder\addExtensionStatics
‪addExtensionStatics(IncludeInterface $parentNode)
Definition: SysTemplateTreeBuilder.php:460
‪TYPO3\CMS\Core\TypoScript\IncludeTree\SysTemplateTreeBuilder\prepareNodeForCache
‪prepareNodeForCache(IncludeInterface $node)
Definition: SysTemplateTreeBuilder.php:641
‪TYPO3\CMS\Core\TypoScript\IncludeTree\TreeFromLineStreamBuilder
Definition: TreeFromLineStreamBuilder.php:59
‪TYPO3\CMS\Core\Context\Context
Definition: Context.php:54
‪TYPO3\CMS\Core\TypoScript\IncludeTree\SysTemplateTreeBuilder\handleSysTemplateRecordInclude
‪handleSysTemplateRecordInclude(IncludeInterface $parentNode, array $row, ?SiteInterface $site)
Definition: SysTemplateTreeBuilder.php:271
‪TYPO3\CMS\Core\TypoScript\IncludeTree\SysTemplateTreeBuilder\createSiteTemplateInclude
‪createSiteTemplateInclude(Site $site, string $cacheIdentifier)
Definition: SysTemplateTreeBuilder.php:190
‪TYPO3\CMS\Core\TypoScript\IncludeTree\SysTemplateTreeBuilder\addDefaultTypoScriptFromGlobals
‪addDefaultTypoScriptFromGlobals(IncludeInterface $parentConstantNode)
Definition: SysTemplateTreeBuilder.php:492
‪TYPO3\CMS\Core\TypoScript\IncludeTree\SysTemplateTreeBuilder\addContentRenderingFromGlobals
‪addContentRenderingFromGlobals(IncludeInterface $parentNode, string $name)
Definition: SysTemplateTreeBuilder.php:558
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\isLoaded
‪static isLoaded(string $key)
Definition: ExtensionManagementUtility.php:55
‪TYPO3\CMS\Core\Site\Entity\Site
Definition: Site.php:42
‪TYPO3\CMS\Core\TypoScript\IncludeTree\SysTemplateTreeBuilder\handleIncludeBasedOnTemplates
‪handleIncludeBasedOnTemplates(IncludeInterface $parentNode, string $basedOnList, ?SiteInterface $site)
Definition: SysTemplateTreeBuilder.php:343
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility
Definition: ExtensionManagementUtility.php:32
‪TYPO3\CMS\Core\Site\Set\SetRegistry
Definition: SetRegistry.php:30
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\extPath
‪static extPath(string $key, string $script='')
Definition: ExtensionManagementUtility.php:82
‪TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\SiteInclude
Definition: SiteInclude.php:25
‪TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\IncludeInterface
Definition: IncludeInterface.php:39
‪TYPO3\CMS\Core\TypoScript\IncludeTree\SysTemplateTreeBuilder\handleIncludeStaticFileArray
‪handleIncludeStaticFileArray(IncludeInterface $parentNode, string $includeStaticFileString)
Definition: SysTemplateTreeBuilder.php:318
‪TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\FileInclude
Definition: FileInclude.php:28
‪TYPO3\CMS\Core\TypoScript\IncludeTree\SysTemplateTreeBuilder\handleSingleIncludeStaticFile
‪handleSingleIncludeStaticFile(IncludeInterface $parentNode, $includeStaticFileString)
Definition: SysTemplateTreeBuilder.php:391
‪$name
‪$name
Definition: phpIntegrityChecker.php:235
‪TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\IncludeStaticFileDatabaseInclude
Definition: IncludeStaticFileDatabaseInclude.php:27
‪TYPO3\CMS\Core\TypoScript\IncludeTree\SysTemplateTreeBuilder\getSysTemplateRowIdentifier
‪getSysTemplateRowIdentifier(array $sysTemplateRow, ?SiteInterface $site)
Definition: SysTemplateTreeBuilder.php:621
‪TYPO3\CMS\Core\TypoScript\IncludeTree\SysTemplateTreeBuilder\$tokenizer
‪TokenizerInterface $tokenizer
Definition: SysTemplateTreeBuilder.php:88
‪TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\DefaultTypoScriptMagicKeyInclude
Definition: DefaultTypoScriptMagicKeyInclude.php:26
‪TYPO3\CMS\Core\Site\Entity\Site\getTypoScript
‪getTypoScript()
Definition: Site.php:334
‪TYPO3\CMS\Core\TypoScript\IncludeTree\SysTemplateTreeBuilder\addDefaultTypoScriptConstantsFromSite
‪addDefaultTypoScriptConstantsFromSite(IncludeInterface $parentConstantNode, ?SiteInterface $site)
Definition: SysTemplateTreeBuilder.php:516
‪TYPO3\CMS\Core\TypoScript\IncludeTree\SysTemplateTreeBuilder\handleSetInclude
‪handleSetInclude(IncludeInterface $parentNode, string $path, string $label)
Definition: SysTemplateTreeBuilder.php:235
‪TYPO3\CMS\Core\Site\Entity\Site\isTypoScriptRoot
‪isTypoScriptRoot()
Definition: Site.php:329
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:41
‪TYPO3\CMS\Core\TypoScript\IncludeTree\SysTemplateTreeBuilder\$includedSysTemplateUids
‪array $includedSysTemplateUids
Definition: SysTemplateTreeBuilder.php:83
‪TYPO3\CMS\Core\TypoScript\IncludeTree\SysTemplateTreeBuilder\$enableStaticMagicIncludes
‪bool $enableStaticMagicIncludes
Definition: SysTemplateTreeBuilder.php:91
‪TYPO3\CMS\Core\Site\Entity\Site\getConfiguration
‪getConfiguration()
Definition: Site.php:316
‪TYPO3\CMS\Core\TypoScript\IncludeTree\SysTemplateTreeBuilder\getBasedOnSysTemplateRowsFromDatabase
‪getBasedOnSysTemplateRowsFromDatabase(array $basedOnTemplateUids)
Definition: SysTemplateTreeBuilder.php:589
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\TypoScript\IncludeTree\SysTemplateTreeBuilder\__construct
‪__construct(private readonly ConnectionPool $connectionPool, private readonly PackageManager $packageManager, private readonly Context $context, private readonly TreeFromLineStreamBuilder $treeFromTokenStreamBuilder, private readonly SetRegistry $setRegistry,)
Definition: SysTemplateTreeBuilder.php:93
‪TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\DefaultTypoScriptInclude
Definition: DefaultTypoScriptInclude.php:26
‪TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\RootInclude
Definition: RootInclude.php:27
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Core\TypoScript\Tokenizer\TokenizerInterface
Definition: TokenizerInterface.php:40
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Core\TypoScript\IncludeTree\SysTemplateTreeBuilder\getSysTemplateQueryRestrictionContainer
‪getSysTemplateQueryRestrictionContainer()
Definition: SysTemplateTreeBuilder.php:650
‪TYPO3\CMS\Core\Utility\GeneralUtility\intExplode
‪static list< int > intExplode(string $delimiter, string $string, bool $removeEmptyValues=false)
Definition: GeneralUtility.php:756
‪TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\SysTemplateInclude
Definition: SysTemplateInclude.php:26
‪TYPO3\CMS\Core\TypoScript\IncludeTree\SysTemplateTreeBuilder
Definition: SysTemplateTreeBuilder.php:76
‪TYPO3\CMS\Core\TypoScript\IncludeTree\SysTemplateTreeBuilder\addStaticMagicFromGlobals
‪addStaticMagicFromGlobals(IncludeInterface $parentNode, string $identifier)
Definition: SysTemplateTreeBuilder.php:574
‪TYPO3\CMS\Core\Site\Entity\Site\getIdentifier
‪getIdentifier()
Definition: Site.php:185
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static list< string > trimExplode(string $delim, string $string, bool $removeEmptyValues=false, int $limit=0)
Definition: GeneralUtility.php:822
‪TYPO3\CMS\Webhooks\Message\$identifier
‪identifier readonly string $identifier
Definition: FileAddedMessage.php:37
‪TYPO3\CMS\Core\Database\Query\Restriction\DefaultRestrictionContainer
Definition: DefaultRestrictionContainer.php:24