‪TYPO3CMS  ‪main
TemplateService.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
17 
18 use Psr\Log\LogLevel;
27 use TYPO3\CMS\Core\Package\PackageManager;
38 
46 {
54  protected ‪$verbose = false;
55 
61  public ‪$tt_track = true;
62 
71  public ‪$matchAlternative = [];
72 
78  protected ‪$matchAll = false;
79 
83  public ‪$ext_regLinenumbers = false;
84 
88  public ‪$ext_regComments = false;
89 
95  protected ‪$simulationHiddenOrTime = false;
96 
102  public ‪$loaded = false;
103 
107  public ‪$setup = [];
108 
112  public ‪$flatSetup = [];
113 
121  public ‪$config = [];
122 
128  public ‪$constants = [];
129 
135  protected ‪$templateIncludePaths = [];
136 
142  public ‪$hierarchyInfo = [];
143 
149  protected ‪$hierarchyInfoToRoot = [];
150 
156  protected ‪$rootId;
157 
180  public $rootLine;
181 
208  protected array $absoluteRootLine = [];
209 
215  protected $rowSum;
216 
222  public $sections;
223 
229  protected $sectionsMatch;
230 
235  public $clearList_const = [];
236 
242  public $clearList_setup = [];
243 
247  public $parserErrors = [];
248 
252  public $setup_constants = [];
253 
263  protected $extensionStaticsProcessed = false;
264 
270  protected $processExtensionStatics = false;
271 
279  protected $isDefaultTypoScriptAdded = false;
280 
289  protected $processIncludesHasBeenRun = false;
290 
295  protected $queryBuilderRestrictions;
296 
300  protected $context;
301 
305  protected $packageManager;
306 
310  protected $frontendController;
311 
312  private static bool $deprecationLogged = false;
313 
319  public function __construct(‪Context $context = null, PackageManager $packageManager = null, ‪TypoScriptFrontendController $frontendController = null)
320  {
321  $this->‪context = $context ?? GeneralUtility::makeInstance(Context::class);
322  $this->‪packageManager = $packageManager ?? GeneralUtility::makeInstance(PackageManager::class);
323  $this->‪frontendController = $frontendController;
325  if ($this->‪context->getPropertyFromAspect('visibility', 'includeHiddenContent', false) || ‪$GLOBALS['SIM_ACCESS_TIME'] !== ‪$GLOBALS['ACCESS_TIME']) {
326  // Set the simulation flag, if simulation is detected!
327  $this->simulationHiddenOrTime = true;
328  }
329  $this->‪tt_track = $this->verbose = (bool)$this->‪context->getPropertyFromAspect('backend.user', 'isLoggedIn', false);
330  }
331 
335  public function ‪getProcessExtensionStatics()
336  {
337  if (!self::$deprecationLogged) {
338  trigger_error(__CLASS__ . ' has been marked as deprecated in TYPO3 v12 and will be removed in v13.', E_USER_DEPRECATED);
339  self::$deprecationLogged = true;
340  }
341  return $this->processExtensionStatics;
342  }
343 
347  public function ‪setProcessExtensionStatics($processExtensionStatics)
348  {
349  if (!self::$deprecationLogged) {
350  trigger_error(__CLASS__ . ' has been marked as deprecated in TYPO3 v12 and will be removed in v13.', E_USER_DEPRECATED);
351  self::$deprecationLogged = true;
352  }
353  $this->processExtensionStatics = (bool)$processExtensionStatics;
354  }
355 
360  public function ‪setVerbose(‪$verbose)
361  {
362  if (!self::$deprecationLogged) {
363  trigger_error(__CLASS__ . ' has been marked as deprecated in TYPO3 v12 and will be removed in v13.', E_USER_DEPRECATED);
364  self::$deprecationLogged = true;
365  }
366  $this->verbose = (bool)‪$verbose;
367  }
368 
372  protected function ‪initializeDatabaseQueryRestrictions()
373  {
374  $this->queryBuilderRestrictions = GeneralUtility::makeInstance(DefaultRestrictionContainer::class);
375 
376  if ($this->‪context->getPropertyFromAspect('visibility', 'includeHiddenContent', false)) {
377  $this->queryBuilderRestrictions->removeByType(HiddenRestriction::class);
378  }
379  }
380 
387  public function ‪matching($cc)
388  {
389  if (!self::$deprecationLogged) {
390  trigger_error(__CLASS__ . ' has been marked as deprecated in TYPO3 v12 and will be removed in v13.', E_USER_DEPRECATED);
391  self::$deprecationLogged = true;
392  }
393  if (is_array($cc['all'])) {
394  $matchObj = GeneralUtility::makeInstance(ConditionMatcher::class, null, null, null, $this->absoluteRootLine);
395  $matchObj->setRootline((array)($cc['rootLine'] ?? []));
396  $sectionsMatch = [];
397  foreach ($cc['all'] as $key => $pre) {
398  if ($matchObj->match($pre)) {
399  $sectionsMatch[$key] = $pre;
400  }
401  }
402  $cc['match'] = $sectionsMatch;
403  }
404  return $cc;
405  }
406 
414  public function ‪start($theRootLine)
415  {
416  if (!self::$deprecationLogged) {
417  trigger_error(__CLASS__ . ' has been marked as deprecated in TYPO3 v12 and will be removed in v13.', E_USER_DEPRECATED);
418  self::$deprecationLogged = true;
419  }
420  $cc = [];
421  if (is_array($theRootLine)) {
422  $constantsData = [];
423  $setupData = [];
424  $cacheIdentifier = '';
425  $this->‪runThroughTemplates($theRootLine);
426  // This is about getting the hash string which is used to fetch the cached TypoScript template.
427  // If there was some cached currentPageData ($cc) then that's good (it gives us the hash).
428  // If currentPageData was not there, we first find $rowSum (freshly generated). After that we try to see, if it is stored with a list of all conditions. If so we match the result.
429  $rowSumHash = md5('ROWSUM:' . serialize($this->rowSum));
430  $result = $this->‪getCacheEntry($rowSumHash);
431  if (is_array($result)) {
432  $cc['all'] = $result;
433  $cc['rowSum'] = $this->rowSum;
434  $cc = $this->‪matching($cc);
435  ksort($cc);
436  $cacheIdentifier = md5(serialize($cc));
437  }
438  if ($cacheIdentifier) {
439  // Get TypoScript setup array
440  $cachedData = $this->‪getCacheEntry($cacheIdentifier);
441  if (is_array($cachedData)) {
442  $constantsData = $cachedData['constants'];
443  $setupData = $cachedData['setup'];
444  }
445  }
446  if (!empty($setupData) && !$this->‪context->getPropertyFromAspect('typoscript', 'forcedTemplateParsing')) {
447  // TypoScript constants + setup are found in the cache
448  $this->setup_constants = $constantsData;
449  $this->setup = $setupData;
450  if ($this->‪tt_track) {
451  $this->‪getTimeTracker()->‪setTSlogMessage('Using cached TS template data', LogLevel::INFO);
452  }
453  } else {
454  if ($this->‪tt_track) {
455  $this->‪getTimeTracker()->‪setTSlogMessage('Not using any cached TS data', LogLevel::INFO);
456  }
457 
458  // Make configuration
459  $this->‪generateConfig();
460  // This stores the template hash thing
461  $cc = [];
462  // All sections in the template at this point is found
463  $cc['all'] = $this->sections;
464  // The line of templates is collected
465  $cc['rowSum'] = $this->rowSum;
466  $cc = $this->‪matching($cc);
467  ksort($cc);
468  $cacheIdentifier = md5(serialize($cc));
469  // This stores the data.
470  $this->‪setCacheEntry($cacheIdentifier, ['constants' => $this->setup_constants, 'setup' => $this->setup], 'TS_TEMPLATE');
471  if ($this->‪tt_track) {
472  $this->‪getTimeTracker()->‪setTSlogMessage('TS template size, serialized: ' . strlen(serialize($this->setup)) . ' bytes', LogLevel::INFO);
473  }
474  $rowSumHash = md5('ROWSUM:' . serialize($this->rowSum));
475  $this->‪setCacheEntry($rowSumHash, $cc['all'], 'TMPL_CONDITIONS_ALL');
476  }
477  // Add rootLine
478  $cc['rootLine'] = $this->rootLine;
479  ksort($cc);
480  // If everything OK.
481  if ($this->rootId && $this->rootLine && $this->setup) {
482  $this->loaded = true;
483  }
484  }
485  }
486 
487  /*******************************************************************
488  *
489  * Fetching TypoScript code text for the Template Hierarchy
490  *
491  *******************************************************************/
501  public function ‪runThroughTemplates($theRootLine, $start_template_uid = 0)
502  {
503  if (!self::$deprecationLogged) {
504  trigger_error(__CLASS__ . ' has been marked as deprecated in TYPO3 v12 and will be removed in v13.', E_USER_DEPRECATED);
505  self::$deprecationLogged = true;
506  }
507  $this->constants = [];
508  $this->config = [];
509  $this->rowSum = [];
510  $this->hierarchyInfoToRoot = [];
511  $this->absoluteRootLine = $theRootLine;
512  $this->isDefaultTypoScriptAdded = false;
513 
514  reset($this->absoluteRootLine);
515  $c = count($this->absoluteRootLine);
516  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_template');
517  for ($a = 0; $a < $c; $a++) {
518  $where = [
519  $queryBuilder->expr()->eq(
520  'pid',
521  $queryBuilder->createNamedParameter($this->absoluteRootLine[$a]['uid'], ‪Connection::PARAM_INT)
522  ),
523  ];
524  // If first loop AND there is set an alternative template uid, use that
525  if ($a === $c - 1 && $start_template_uid) {
526  $where[] = $queryBuilder->expr()->eq(
527  'uid',
528  $queryBuilder->createNamedParameter($start_template_uid, ‪Connection::PARAM_INT)
529  );
530  }
531  $queryBuilder->setRestrictions($this->queryBuilderRestrictions);
532  $queryResult = $queryBuilder
533  ->select('*')
534  ->from('sys_template')
535  ->where(...$where)
536  ->orderBy('root', 'DESC')
537  ->addOrderBy('sorting')
538  ->setMaxResults(1)
539  ->executeQuery();
540  if ($row = $queryResult->fetchAssociative()) {
541  $this->‪processTemplate($row, 'sys_' . $row['uid'], $this->absoluteRootLine[$a]['uid'], 'sys_' . $row['uid']);
542  }
543  $this->rootLine[] = $this->absoluteRootLine[$a];
544  }
545 
546  // Hook into the default TypoScript to add custom typoscript logic
547  $hookParameters = [
548  'extensionStaticsProcessed' => &$this->extensionStaticsProcessed,
549  'isDefaultTypoScriptAdded' => &$this->isDefaultTypoScriptAdded,
550  'absoluteRootLine' => &$this->absoluteRootLine,
551  'rootLine' => &$this->rootLine,
552  'startTemplateUid' => $start_template_uid,
553  'rowSum' => &$this->rowSum,
554  ];
555  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['Core/TypoScript/TemplateService']['runThroughTemplatesPostProcessing'] ?? [] as $listener) {
556  GeneralUtility::callUserFunction($listener, $hookParameters, $this);
557  }
558 
559  // Process extension static files if not done yet, but explicitly requested
560  if (!$this->extensionStaticsProcessed && $this->processExtensionStatics) {
561  $this->‪addExtensionStatics('sys_0', 'sys_0', 0);
562  }
563 
564  // Add the global default TypoScript from the TYPO3_CONF_VARS
565  $this->‪addDefaultTypoScript();
566 
567  $this->‪processIncludes();
568  }
569 
582  public function ‪processTemplate($row, $idList, $pid, $templateID = '', $templateParent = '', $includePath = '')
583  {
584  if (!self::$deprecationLogged) {
585  trigger_error(__CLASS__ . ' has been marked as deprecated in TYPO3 v12 and will be removed in v13.', E_USER_DEPRECATED);
586  self::$deprecationLogged = true;
587  }
588  // Adding basic template record information to rowSum array
589  $this->rowSum[] = [$row['uid'] ?? null, $row['title'] ?? null, $row['tstamp'] ?? null];
590  // Processing "Clear"-flags
591  $clConst = 0;
592  $clConf = 0;
593  if (!empty($row['clear'])) {
594  $clConst = $row['clear'] & 1;
595  $clConf = $row['clear'] & 2;
596  if ($clConst) {
597  // Keep amount of items to stay in sync with $this->templateIncludePaths so processIncludes() does not break
598  foreach ($this->constants as &$constantConfiguration) {
599  $constantConfiguration = '';
600  }
601  unset($constantConfiguration);
602  $this->clearList_const = [];
603  }
604  if ($clConf) {
605  // Keep amount of items to stay in sync with $this->templateIncludePaths so processIncludes() does not break
606  foreach ($this->config as &$configConfiguration) {
607  $configConfiguration = '';
608  }
609  unset($configConfiguration);
610  $this->hierarchyInfoToRoot = [];
611  $this->clearList_setup = [];
612  }
613  }
614  // Include files (from extensions) (#1/2)
615  // NORMAL inclusion, The EXACT same code is found below the basedOn inclusion!!!
616  if (!isset($row['includeStaticAfterBasedOn']) || !$row['includeStaticAfterBasedOn']) {
617  $this->‪includeStaticTypoScriptSources($idList, $templateID, $pid, $row);
618  }
619  // Include "Based On" sys_templates:
620  // 'basedOn' is a list of templates to include
621  $basedOn = trim($row['basedOn'] ?? '');
622  if ($basedOn !== '') {
623  // Normal Operation, which is to include the "based-on" sys_templates,
624  // if they are not already included, and maintaining the sorting of the templates
625  $basedOnIds = ‪GeneralUtility::intExplode(',', $basedOn, true);
626  // skip template if it's already included
627  foreach ($basedOnIds as $key => $basedOnId) {
628  if (‪GeneralUtility::inList($idList, 'sys_' . $basedOnId)) {
629  unset($basedOnIds[$key]);
630  }
631  }
632  if (!empty($basedOnIds)) {
633  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_template');
634  $queryBuilder->setRestrictions($this->queryBuilderRestrictions);
635  $queryResult = $queryBuilder
636  ->select('*')
637  ->from('sys_template')
638  ->where(
639  $queryBuilder->expr()->in(
640  'uid',
641  $queryBuilder->createNamedParameter($basedOnIds, Connection::PARAM_INT_ARRAY)
642  )
643  )
644  ->executeQuery();
645  // make it an associative array with the UID as key
646  $subTemplates = [];
647  while ($rowItem = $queryResult->fetchAssociative()) {
648  $subTemplates[(int)$rowItem['uid']] = $rowItem;
649  }
650  // Traversing list again to ensure the sorting of the templates
651  foreach ($basedOnIds as $id) {
652  if (is_array($subTemplates[$id] ?? false)) {
653  $this->‪processTemplate($subTemplates[$id], $idList . ',sys_' . $id, $pid, 'sys_' . $id, $templateID);
654  }
655  }
656  }
657  }
658  // Include files (from extensions) (#2/2)
659  if (!empty($row['includeStaticAfterBasedOn'])) {
660  $this->‪includeStaticTypoScriptSources($idList, $templateID, $pid, $row);
661  }
662  // Creating hierarchy information; Used by backend analysis tools
663  $this->hierarchyInfo[] = ($this->hierarchyInfoToRoot[] = [
664  'root' => trim($row['root'] ?? ''),
665  'clConst' => $clConst,
666  'clConf' => $clConf,
667  'templateID' => $templateID,
668  'templateParent' => $templateParent,
669  'title' => $row['title'],
670  'uid' => $row['uid'],
671  'pid' => $row['pid'] ?? null,
672  'configLines' => substr_count((string)$row['config'], LF) + 1,
673  ]);
674  // Adding the content of the fields constants (Constants) and config (Setup)
675  $this->constants[] = $row['constants'];
676  $this->config[] = $row['config'];
677  $this->templateIncludePaths[] = $includePath;
678  // For backend analysis (Template Analyzer) provide the order of added constants/config template IDs
679  $this->clearList_const[] = $templateID;
680  $this->clearList_setup[] = $templateID;
681  // If the template record is a Rootlevel record, set the flag and clear the template rootLine (so it starts over from this point)
682  if (trim($row['root'] ?? '')) {
683  $this->rootId = $pid;
684  $this->rootLine = [];
685  }
686  }
687 
698  public function ‪includeStaticTypoScriptSources($idList, $templateID, $pid, $row)
699  {
700  // Call function for link rendering:
701  $_params = [
702  'idList' => &$idList,
703  'templateId' => &$templateID,
704  'pid' => &$pid,
705  'row' => &$row,
706  ];
707  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tstemplate.php']['includeStaticTypoScriptSources'] ?? [] as $_funcRef) {
708  GeneralUtility::callUserFunction($_funcRef, $_params, $this);
709  }
710  // If "Include before all static templates if root-flag is set" is set:
711  $staticFileMode = (int)($row['static_file_mode'] ?? null);
712  if ($staticFileMode === 3 && str_starts_with($templateID, 'sys_') && $row['root']) {
713  $this->‪addExtensionStatics($idList, $templateID, $pid);
714  }
715  // Static Template Files (Text files from extensions): include_static_file is a list of static files to include (from extensions)
716  if (trim($row['include_static_file'] ?? '')) {
717  $include_static_fileArr = ‪GeneralUtility::trimExplode(',', $row['include_static_file'], true);
718  // Traversing list
719  foreach ($include_static_fileArr as $ISF_file) {
720  if (‪PathUtility::isExtensionPath($ISF_file)) {
721  [$ISF_extKey, $ISF_localPath] = explode('/', substr($ISF_file, 4), 2);
722  if ($ISF_extKey !== '' && $ISF_localPath !== '' && ‪ExtensionManagementUtility::isLoaded($ISF_extKey)) {
723  $ISF_localPath = rtrim($ISF_localPath, '/') . '/';
724  $ISF_filePath = ‪ExtensionManagementUtility::extPath($ISF_extKey) . $ISF_localPath;
725  if (@is_dir($ISF_filePath)) {
726  $mExtKey = str_replace('_', '', $ISF_extKey . '/' . $ISF_localPath);
727  $includeStaticFileTxtPath = $ISF_filePath . 'include_static_file.txt';
728  $includeStaticFileTxtContents = '';
729  if (@file_exists($includeStaticFileTxtPath)) {
730  $includeStaticFileTxtContents = (string)file_get_contents($includeStaticFileTxtPath);
731  $includeStaticFileTxtContents = implode(',', array_unique(‪GeneralUtility::trimExplode(',', $includeStaticFileTxtContents)));
732  }
733  $subrow = [
734  'constants' => $this->‪getTypoScriptSourceFileContent($ISF_filePath, 'constants'),
735  'config' => $this->‪getTypoScriptSourceFileContent($ISF_filePath, 'setup'),
736  'include_static_file' => $includeStaticFileTxtContents,
737  'title' => $ISF_file,
738  'uid' => $mExtKey,
739  ];
740  $subrow = $this->‪prependStaticExtra($subrow);
741  $this->‪processTemplate($subrow, $idList . ',ext_' . $mExtKey, $pid, 'ext_' . $mExtKey, $templateID, $ISF_filePath);
742  }
743  }
744  }
745  }
746  }
747  // If "Default (include before if root flag is set)" is set OR
748  // "Always include before this typoscript record" AND root-flag are set
749  if ($staticFileMode === 1 || ($staticFileMode === 0 && str_starts_with($templateID, 'sys_') && $row['root'])) {
750  $this->‪addExtensionStatics($idList, $templateID, $pid);
751  }
752  // Include Static Template Records after all other TypoScript has been included.
753  $_params = [
754  'idList' => &$idList,
755  'templateId' => &$templateID,
756  'pid' => &$pid,
757  'row' => &$row,
758  ];
759  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tstemplate.php']['includeStaticTypoScriptSourcesAtEnd'] ?? [] as $_funcRef) {
760  GeneralUtility::callUserFunction($_funcRef, $_params, $this);
761  }
762  }
763 
772  protected function ‪getTypoScriptSourceFileContent($filePath, $baseName)
773  {
774  $extensions = ['.typoscript', '.ts', '.txt'];
775  foreach ($extensions as $extension) {
776  $fileName = $filePath . $baseName . $extension;
777  if (@file_exists($fileName)) {
778  return file_get_contents($fileName);
779  }
780  }
781  return '';
782  }
783 
793  protected function ‪addExtensionStatics($idList, $templateID, $pid)
794  {
795  $this->extensionStaticsProcessed = true;
796 
797  foreach ($this->‪packageManager->getActivePackages() as $package) {
798  $extKey = $package->getPackageKey();
799  $packagePath = $package->getPackagePath();
800  $filesToCheck = [
801  'ext_typoscript_constants.typoscript',
802  'ext_typoscript_setup.typoscript',
803  ];
804  $files = [];
805  $hasExtensionStatics = false;
806  foreach ($filesToCheck as $file) {
807  $path = $packagePath . $file;
808  if (@file_exists($path)) {
809  $files[$file] = $path;
810  $hasExtensionStatics = true;
811  } else {
812  $files[$file] = null;
813  }
814  }
815 
816  if ($hasExtensionStatics) {
817  $mExtKey = str_replace('_', '', $extKey);
818  ‪$constants = '';
819  ‪$config = '';
820 
821  if (!empty($files['ext_typoscript_constants.typoscript'])) {
822  ‪$constants = @file_get_contents($files['ext_typoscript_constants.typoscript']);
823  }
824 
825  if (!empty($files['ext_typoscript_setup.typoscript'])) {
826  ‪$config = @file_get_contents($files['ext_typoscript_setup.typoscript']);
827  }
828 
829  $this->‪processTemplate(
830  $this->‪prependStaticExtra([
831  'constants' => $constants,
832  'config' => ‪$config,
833  'title' => $extKey,
834  'uid' => $mExtKey,
835  ]),
836  $idList . ',ext_' . $mExtKey,
837  $pid,
838  'ext_' . $mExtKey,
839  $templateID,
840  $packagePath
841  );
842  }
843  }
844  }
845 
855  protected function ‪prependStaticExtra($subrow)
856  {
857  // the identifier can be "43" if coming from "static template" extension or a path like "cssstyledcontent/static/"
858  ‪$identifier = $subrow['uid'];
859  $subrow['config'] .= ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_setup.'][‪$identifier] ?? '';
860  $subrow['constants'] .= ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_constants.'][‪$identifier] ?? '';
861  // if this is a template of type "default content rendering", also see if other extensions have added their TypoScript that should be included after the content definitions
862  if (in_array(‪$identifier, ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['contentRenderingTemplates'], true)) {
863  $subrow['config'] .= ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_setup.']['defaultContentRendering'] ?? '';
864  $subrow['constants'] .= ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_constants.']['defaultContentRendering'] ?? '';
865  }
866  return $subrow;
867  }
868 
869  /*******************************************************************
870  *
871  * Parsing TypoScript code text from Template Records into PHP array
872  *
873  *******************************************************************/
881  public function ‪generateConfig()
882  {
883  if (!self::$deprecationLogged) {
884  trigger_error(__CLASS__ . ' has been marked as deprecated in TYPO3 v12 and will be removed in v13.', E_USER_DEPRECATED);
885  self::$deprecationLogged = true;
886  }
887  // Add default TS for all code types
888  $this->‪addDefaultTypoScript();
889 
890  // Parse the TypoScript code text for include-instructions!
891  $this->‪processIncludes();
892  // ****************************
893  // Parse TypoScript Constants
894  // ****************************
895  // Initialize parser and match-condition classes:
896  $constants = GeneralUtility::makeInstance(TypoScriptParser::class);
897  $matchObj = GeneralUtility::makeInstance(ConditionMatcher::class, null, null, $this->rootLine, $this->absoluteRootLine);
898  $matchObj->setSimulateMatchConditions($this->matchAlternative);
899  $matchObj->setSimulateMatchResult((bool)$this->matchAll);
900  // Traverse constants text fields and parse them
901  foreach ($this->constants as $str) {
902  ‪$constants->parse($str, $matchObj);
903  }
904  // Read out parse errors if any
905  $this->parserErrors['constants'] = ‪$constants->errors;
906  // Then flatten the structure from a multi-dim array to a single dim array with all constants listed as key/value pairs (ready for substitution)
907  $this->flatSetup = ‪ArrayUtility::flatten(‪$constants->setup, '', true);
908  // ***********************************************
909  // Parse TypoScript Setup (here called "config")
910  // ***********************************************
911  // Initialize parser and match-condition classes:
912  ‪$config = GeneralUtility::makeInstance(TypoScriptParser::class);
913  ‪$config->regLinenumbers = ‪$this->ext_regLinenumbers;
914  ‪$config->regComments = ‪$this->ext_regComments;
915  ‪$config->setup = ‪$this->setup;
916  // Transfer information about conditions found in "Constants" and which of them returned TRUE.
917  ‪$config->sections = ‪$constants->sections;
918  ‪$config->sectionsMatch = ‪$constants->sectionsMatch;
919  // Traverse setup text fields and concatenate them into one, single string separated by a [GLOBAL] condition
920  $all = '';
921  foreach ($this->config as $str) {
922  $all .= '
923 [GLOBAL]
924 ' . $str;
925  }
926  // Substitute constants in the Setup code:
927  if ($this->‪tt_track) {
928  $this->‪getTimeTracker()->‪push('Substitute Constants (' . count($this->flatSetup) . ')');
929  }
930  $all = $this->‪substituteConstants($all);
931  if ($this->‪tt_track) {
932  $this->‪getTimeTracker()->‪pull();
933  }
934 
935  // Searching for possible unsubstituted constants left (only for information)
936  if ($this->verbose) {
937  if (preg_match_all('/\\{\\$.[^}]*\\}/', $all, $constantList) > 0) {
938  if ($this->‪tt_track) {
939  $this->‪getTimeTracker()->‪setTSlogMessage(implode(', ', $constantList[0]) . ': Constants may remain un-substituted!!', LogLevel::WARNING);
940  }
941  }
942  }
943 
944  // Logging the textual size of the TypoScript Setup field text with all constants substituted:
945  if ($this->‪tt_track) {
946  $this->‪getTimeTracker()->‪setTSlogMessage('TypoScript template size as textfile: ' . strlen($all) . ' bytes', LogLevel::INFO);
947  }
948  // Finally parse the Setup field TypoScript code (where constants are now substituted)
949  ‪$config->parse($all, $matchObj);
950  // Read out parse errors if any
951  $this->parserErrors['config'] = ‪$config->errors;
952  // Transfer the TypoScript array from the parser object to the internal $this->setup array:
953  $this->setup = ‪$config->setup;
954  // Do the same for the constants
955  $this->setup_constants = ‪$constants->setup;
956  // ****************************************************************
957  // Final processing of the $this->setup TypoScript Template array
958  // Basically: This is unsetting/setting of certain reserved keys.
959  // ****************************************************************
960  // These vars are already set after 'processTemplate', but because $config->setup overrides them (in the line above!), we set them again. They are not changed compared to the value they had in the top of the page!
961  unset($this->setup['types.']);
962  unset($this->setup['types']);
963  if (is_array($this->setup)) {
964  foreach ($this->setup as $key => $value) {
965  if ($value === 'PAGE') {
966  // Set the typeNum of the current page object:
967  if (isset($this->setup[$key . '.']['typeNum'])) {
968  $typeNum = $this->setup[$key . '.']['typeNum'];
969  $this->setup['types.'][$typeNum] = $key;
970  } elseif (!isset($this->setup['types.'][0]) || !$this->setup['types.'][0]) {
971  $this->setup['types.'][0] = $key;
972  }
973  }
974  }
975  }
976  unset($this->setup['temp.']);
977  unset(‪$constants);
978  // Storing the conditions found/matched information:
979  $this->sections = ‪$config->sections;
980  $this->sectionsMatch = ‪$config->sectionsMatch;
981  }
982 
991  protected function ‪processIncludes()
992  {
993  if ($this->processIncludesHasBeenRun) {
994  return;
995  }
996 
998  $files = [];
999  foreach ($this->constants as &$value) {
1000  $includeData = ‪TypoScriptParser::checkIncludeLines($value, 1, true, array_shift($paths));
1001  $files = array_merge($files, $includeData['files']);
1002  $value = $includeData['typoscript'];
1003  }
1004  unset($value);
1006  foreach ($this->config as &$value) {
1007  $includeData = ‪TypoScriptParser::checkIncludeLines($value, 1, true, array_shift($paths));
1008  $files = array_merge($files, $includeData['files']);
1009  $value = $includeData['typoscript'];
1010  }
1011  unset($value);
1012 
1013  if (!empty($files)) {
1014  $files = array_unique($files);
1015  foreach ($files as $file) {
1016  $this->rowSum[] = [$file, filemtime($file)];
1017  }
1018  }
1019 
1020  $this->processIncludesHasBeenRun = true;
1021  }
1030  protected function ‪substituteConstants($all)
1031  {
1032  if ($this->‪tt_track) {
1033  $this->‪getTimeTracker()->‪setTSlogMessage('Constants to substitute: ' . count($this->flatSetup), LogLevel::INFO);
1034  }
1035  $noChange = false;
1036  // Recursive substitution of constants (up to 10 nested levels)
1037  for ($i = 0; $i < 10 && !$noChange; $i++) {
1038  $old_all = $all;
1039  $all = preg_replace_callback('/\\{\\$(.[^}]*)\\}/', [$this, 'substituteConstantsCallBack'], $all) ?? '';
1040  if ($old_all == $all) {
1041  $noChange = true;
1042  }
1043  }
1044  return $all;
1045  }
1046 
1054  public function ‪substituteConstantsCallBack($matches)
1055  {
1056  // Replace {$CONST} if found in $this->flatSetup, else leave unchanged
1057  return isset($this->flatSetup[$matches[1]]) && !is_array($this->flatSetup[$matches[1]]) ? $this->flatSetup[$matches[1]] : $matches[0];
1058  }
1060  /*******************************************************************
1061  *
1062  * Various API functions, used from elsewhere in the frontend classes
1063  *
1064  *******************************************************************/
1065 
1072  public function ‪getRootlineLevel($list)
1073  {
1074  if (!self::$deprecationLogged) {
1075  trigger_error(__CLASS__ . ' has been marked as deprecated in TYPO3 v12 and will be removed in v13.', E_USER_DEPRECATED);
1076  self::$deprecationLogged = true;
1077  }
1078  $idx = 0;
1079  foreach ($this->rootLine as $page) {
1080  if (‪GeneralUtility::inList($list, $page['uid'])) {
1081  return $idx;
1082  }
1083  $idx++;
1084  }
1085  return false;
1086  }
1087 
1091  public function ‪getRootId(): int
1092  {
1093  if (!self::$deprecationLogged) {
1094  trigger_error(__CLASS__ . ' has been marked as deprecated in TYPO3 v12 and will be removed in v13.', E_USER_DEPRECATED);
1095  self::$deprecationLogged = true;
1096  }
1097  return (int)‪$this->rootId;
1098  }
1099 
1100  /*******************************************************************
1101  *
1102  * Functions for creating links
1103  *
1104  *******************************************************************/
1112  protected function ‪addDefaultTypoScript()
1113  {
1114  // Add default TS for all code types, if not done already
1115  if (!$this->isDefaultTypoScriptAdded) {
1116  $rootTemplateId = $this->hierarchyInfo[count($this->hierarchyInfo) - 1]['templateID'] ?? null;
1117 
1118  // adding constants from site settings
1119  $siteConstants = '';
1120  if ($this->‪getTypoScriptFrontendController() instanceof TypoScriptFrontendController) {
1121  $site = $this->‪getTypoScriptFrontendController()->‪getSite();
1122  } else {
1123  $possibleRoots = array_filter($this->absoluteRootLine, static function (array $page) {
1124  return $page['is_siteroot'] === 1;
1125  });
1126  $possibleRoots[] = end($this->absoluteRootLine);
1127  $site = null;
1128  foreach ($possibleRoots as $possibleRoot) {
1129  try {
1130  $site = GeneralUtility::makeInstance(SiteFinder::class)->getSiteByPageId((int)($possibleRoot['uid'] ?? 0));
1131  break;
1132  } catch (SiteNotFoundException $exception) {
1133  // continue
1134  }
1135  }
1136  }
1137  if ($site instanceof Site) {
1138  $siteSettings = $site->getSettings();
1139  if (!$siteSettings->isEmpty()) {
1140  $siteSettings = $siteSettings->getAllFlat();
1141  foreach ($siteSettings as $k => $v) {
1142  $siteConstants .= $k . ' = ' . $v . LF;
1143  }
1144  }
1145  }
1146 
1147  if ($siteConstants !== '') {
1148  // the count of elements in ->constants, ->config and ->templateIncludePaths have to be in sync
1149  array_unshift($this->constants, $siteConstants);
1150  array_unshift($this->config, '');
1151  array_unshift($this->templateIncludePaths, '');
1152  // prepare a proper entry to hierachyInfo (used by TemplateAnalyzer in BE)
1153  $defaultTemplateInfo = [
1154  'root' => '',
1155  'clConst' => '',
1156  'clConf' => '',
1157  'templateID' => '_siteConstants_',
1158  'templateParent' => $rootTemplateId,
1159  'title' => 'Site settings',
1160  'uid' => '_siteConstants_',
1161  'pid' => '',
1162  'configLines' => 0,
1163  ];
1164  // push info to information arrays used in BE by TemplateTools (Analyzer)
1165  array_unshift($this->clearList_const, $defaultTemplateInfo['uid']);
1166  array_unshift($this->clearList_setup, $defaultTemplateInfo['uid']);
1167  array_unshift($this->hierarchyInfo, $defaultTemplateInfo);
1168  }
1169 
1170  // adding default setup and constants
1171  // defaultTypoScript_setup is *very* unlikely to be empty
1172  // the count of elements in ->constants, ->config and ->templateIncludePaths have to be in sync
1173  array_unshift($this->constants, (string)‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_constants']);
1174  array_unshift($this->config, (string)‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_setup']);
1175  array_unshift($this->templateIncludePaths, '');
1176  // prepare a proper entry to hierachyInfo (used by TemplateAnalyzer in BE)
1177  $defaultTemplateInfo = [
1178  'root' => '',
1179  'clConst' => '',
1180  'clConf' => '',
1181  'templateID' => '_defaultTypoScript_',
1182  'templateParent' => $rootTemplateId,
1183  'title' => 'SYS:TYPO3_CONF_VARS:FE:defaultTypoScript',
1184  'uid' => '_defaultTypoScript_',
1185  'pid' => '',
1186  'configLines' => substr_count((string)‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_setup'], LF) + 1,
1187  ];
1188  // push info to information arrays used in BE by TemplateTools (Analyzer)
1189  array_unshift($this->clearList_const, $defaultTemplateInfo['uid']);
1190  array_unshift($this->clearList_setup, $defaultTemplateInfo['uid']);
1191  array_unshift($this->hierarchyInfo, $defaultTemplateInfo);
1192 
1193  $this->isDefaultTypoScriptAdded = true;
1194  }
1195  }
1196 
1201  {
1202  return $this->‪frontendController ?? ‪$GLOBALS['TSFE'] ?? null;
1203  }
1204 
1208  protected function ‪getTimeTracker()
1209  {
1210  return GeneralUtility::makeInstance(TimeTracker::class);
1211  }
1212 
1220  protected function ‪getCacheEntry(‪$identifier)
1221  {
1222  return GeneralUtility::makeInstance(CacheManager::class)->getCache('hash')->get(‪$identifier);
1223  }
1224 
1232  protected function ‪setCacheEntry(‪$identifier, $data, $tag)
1233  {
1234  GeneralUtility::makeInstance(CacheManager::class)->getCache('hash')->set(‪$identifier, $data, ['ident_' . $tag], 0);
1235  }
1236 }
‪TYPO3\CMS\Core\TypoScript\TemplateService\processIncludes
‪processIncludes()
Definition: TemplateService.php:959
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static list< string > trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
Definition: GeneralUtility.php:916
‪TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction
Definition: HiddenRestriction.php:27
‪TYPO3\CMS\Core\TypoScript\TemplateService\$constants
‪array $constants
Definition: TemplateService.php:116
‪TYPO3\CMS\Core\TypoScript\TemplateService\addDefaultTypoScript
‪addDefaultTypoScript()
Definition: TemplateService.php:1080
‪TYPO3\CMS\Core\Utility\PathUtility\isExtensionPath
‪static isExtensionPath(string $path)
Definition: PathUtility.php:117
‪TYPO3\CMS\Core\Utility\PathUtility
Definition: PathUtility.php:27
‪TYPO3\CMS\Core\Database\Connection\PARAM_INT
‪const PARAM_INT
Definition: Connection.php:47
‪TYPO3\CMS\Core\TypoScript\TemplateService\setVerbose
‪setVerbose($verbose)
Definition: TemplateService.php:328
‪TYPO3\CMS\Core\TypoScript\TemplateService\frontendController
‪$this frontendController
Definition: TemplateService.php:291
‪TYPO3\CMS\Core\TypoScript\TemplateService\substituteConstants
‪string substituteConstants($all)
Definition: TemplateService.php:998
‪TYPO3\CMS\Core\TypoScript\TemplateService\packageManager
‪$this packageManager
Definition: TemplateService.php:290
‪TYPO3\CMS\Core\TypoScript\TemplateService\substituteConstantsCallBack
‪string substituteConstantsCallBack($matches)
Definition: TemplateService.php:1022
‪TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser
Definition: TypoScriptParser.php:38
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController\getSite
‪getSite()
Definition: TypoScriptFrontendController.php:2763
‪TYPO3\CMS\Core\TypoScript\TemplateService\$flatSetup
‪array $flatSetup
Definition: TemplateService.php:102
‪TYPO3\CMS\Core\TypoScript\TemplateService\prependStaticExtra
‪array prependStaticExtra($subrow)
Definition: TemplateService.php:823
‪TYPO3\CMS\Core\Exception\SiteNotFoundException
Definition: SiteNotFoundException.php:26
‪TYPO3\CMS\Core\Site\SiteFinder
Definition: SiteFinder.php:31
‪TYPO3\CMS\Core\TypoScript\TemplateService\$tt_track
‪bool $tt_track
Definition: TemplateService.php:59
‪TYPO3\CMS\Core\TypoScript\TemplateService\$hierarchyInfo
‪array $hierarchyInfo
Definition: TemplateService.php:128
‪TYPO3\CMS\Core\TypoScript\TemplateService\$matchAll
‪bool $matchAll
Definition: TemplateService.php:74
‪TYPO3\CMS\Core\TypoScript\TemplateService\getCacheEntry
‪mixed getCacheEntry($identifier)
Definition: TemplateService.php:1188
‪TYPO3\CMS\Core\TypoScript\TemplateService\getProcessExtensionStatics
‪bool getProcessExtensionStatics()
Definition: TemplateService.php:303
‪TYPO3\CMS\Core\Context\Context
Definition: Context.php:55
‪TYPO3\CMS\Core\TypoScript\TemplateService\runThroughTemplates
‪runThroughTemplates($theRootLine, $start_template_uid=0)
Definition: TemplateService.php:469
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\isLoaded
‪static isLoaded(string $key)
Definition: ExtensionManagementUtility.php:93
‪TYPO3\CMS\Core\TypoScript\TemplateService\includeStaticTypoScriptSources
‪includeStaticTypoScriptSources($idList, $templateID, $pid, $row)
Definition: TemplateService.php:666
‪TYPO3\CMS\Core\TypoScript\TemplateService\getTypoScriptSourceFileContent
‪string getTypoScriptSourceFileContent($filePath, $baseName)
Definition: TemplateService.php:740
‪TYPO3\CMS\Core\Site\Entity\Site
Definition: Site.php:42
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility
Definition: ExtensionManagementUtility.php:40
‪TYPO3\CMS\Core\TypoScript\TemplateService\processTemplate
‪processTemplate($row, $idList, $pid, $templateID='', $templateParent='', $includePath='')
Definition: TemplateService.php:550
‪TYPO3\CMS\Core\Utility\ArrayUtility\flatten
‪static flatten(array $array, string $prefix='', bool $keepDots=false)
Definition: ArrayUtility.php:469
‪TYPO3\CMS\Core\TypoScript
‪TYPO3\CMS\Core\TypoScript\TemplateService\$simulationHiddenOrTime
‪bool $simulationHiddenOrTime
Definition: TemplateService.php:88
‪TYPO3\CMS\Core\TypoScript\TemplateService\setCacheEntry
‪setCacheEntry($identifier, $data, $tag)
Definition: TemplateService.php:1200
‪TYPO3\CMS\Core\TypoScript\TemplateService\$hierarchyInfoToRoot
‪array $hierarchyInfoToRoot
Definition: TemplateService.php:134
‪TYPO3\CMS\Core\TimeTracker\TimeTracker\pull
‪pull(string $content='')
Definition: TimeTracker.php:153
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\extPath
‪static extPath(string $key, string $script='')
Definition: ExtensionManagementUtility.php:120
‪TYPO3\CMS\Core\TypoScript\TemplateService\$ext_regComments
‪bool $ext_regComments
Definition: TemplateService.php:82
‪TYPO3\CMS\Core\TypoScript\TemplateService\addExtensionStatics
‪addExtensionStatics($idList, $templateID, $pid)
Definition: TemplateService.php:761
‪TYPO3\CMS\Core\TypoScript\TemplateService\$ext_regLinenumbers
‪bool $ext_regLinenumbers
Definition: TemplateService.php:78
‪TYPO3\CMS\Core\TypoScript\TemplateService\matching
‪array matching($cc)
Definition: TemplateService.php:355
‪TYPO3\CMS\Core\TypoScript\TemplateService\$matchAlternative
‪array $matchAlternative
Definition: TemplateService.php:68
‪TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser\checkIncludeLines
‪static string array checkIncludeLines($string, $cycle_counter=1, $returnFiles=false, $parentFilenameOrPath='')
Definition: TypoScriptParser.php:677
‪TYPO3\CMS\Core\Cache\CacheManager
Definition: CacheManager.php:36
‪TYPO3\CMS\Core\TypoScript\TemplateService\getRootId
‪getRootId()
Definition: TemplateService.php:1059
‪TYPO3\CMS\Core\TypoScript\TemplateService\initializeDatabaseQueryRestrictions
‪initializeDatabaseQueryRestrictions()
Definition: TemplateService.php:340
‪TYPO3\CMS\Core\TypoScript\TemplateService\$config
‪array $config
Definition: TemplateService.php:110
‪TYPO3\CMS\Core\TypoScript\TemplateService\$templateIncludePaths
‪array $templateIncludePaths
Definition: TemplateService.php:122
‪TYPO3\CMS\Frontend\Configuration\TypoScript\ConditionMatching\ConditionMatcher
Definition: ConditionMatcher.php:34
‪TYPO3\CMS\Core\TypoScript\TemplateService\$setup
‪array $setup
Definition: TemplateService.php:98
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:36
‪TYPO3\CMS\Core\TypoScript\TemplateService\setProcessExtensionStatics
‪setProcessExtensionStatics($processExtensionStatics)
Definition: TemplateService.php:315
‪TYPO3\CMS\Core\TypoScript\TemplateService
Definition: TemplateService.php:46
‪TYPO3\CMS\Core\Database\Query\Restriction\AbstractRestrictionContainer
Definition: AbstractRestrictionContainer.php:28
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController
Definition: TypoScriptFrontendController.php:105
‪TYPO3\CMS\Core\TimeTracker\TimeTracker\setTSlogMessage
‪setTSlogMessage(string $content, string $logLevel=LogLevel::INFO)
Definition: TimeTracker.php:173
‪TYPO3\CMS\Core\Utility\ArrayUtility
Definition: ArrayUtility.php:26
‪TYPO3\CMS\Core\TypoScript\TemplateService\context
‪array< int, $rootLine;protected array $absoluteRootLine=[];protected array $rowSum;public array|null $sections;protected array $sectionsMatch;public string[] $clearList_const=array();public array $clearList_setup=array();public array $parserErrors=array();public array $setup_constants=array();protected bool $extensionStaticsProcessed=false;protected bool $processExtensionStatics=false;protected bool $isDefaultTypoScriptAdded=false;protected bool $processIncludesHasBeenRun=false;protected AbstractRestrictionContainer $queryBuilderRestrictions;protected Context $context;protected PackageManager $packageManager;protected TypoScriptFrontendController|null $frontendController;private static bool $deprecationLogged=false;public function __construct(Context $context=null, PackageManager $packageManager=null, TypoScriptFrontendController $frontendController=null) { $this-> context
Definition: TemplateService.php:289
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Utility\GeneralUtility\intExplode
‪static int[] intExplode($delimiter, $string, $removeEmptyValues=false, $limit=0)
Definition: GeneralUtility.php:842
‪TYPO3\CMS\Core\TypoScript\TemplateService\$loaded
‪bool $loaded
Definition: TemplateService.php:94
‪TYPO3\CMS\Core\Utility\GeneralUtility\inList
‪static bool inList($list, $item)
Definition: GeneralUtility.php:532
‪TYPO3\CMS\Core\TypoScript\TemplateService\tt_track
‪if($this->context->getPropertyFromAspect('visibility', 'includeHiddenContent', false)|| $GLOBALS['SIM_ACCESS_TIME'] !==$GLOBALS['ACCESS_TIME']) $this tt_track
Definition: TemplateService.php:297
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:51
‪TYPO3\CMS\Core\TypoScript\TemplateService\$verbose
‪bool $verbose
Definition: TemplateService.php:53
‪TYPO3\CMS\Core\TypoScript\TemplateService\$rootId
‪int $rootId
Definition: TemplateService.php:140
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:51
‪TYPO3\CMS\Core\TypoScript\TemplateService\getRootlineLevel
‪int getRootlineLevel($list)
Definition: TemplateService.php:1040
‪TYPO3\CMS\Core\TimeTracker\TimeTracker
Definition: TimeTracker.php:32
‪TYPO3\CMS\Core\TypoScript\TemplateService\start
‪start($theRootLine)
Definition: TemplateService.php:382
‪TYPO3\CMS\Core\TypoScript\TemplateService\getTypoScriptFrontendController
‪TypoScriptFrontendController null getTypoScriptFrontendController()
Definition: TemplateService.php:1168
‪TYPO3\CMS\Core\TypoScript\TemplateService\getTimeTracker
‪TimeTracker getTimeTracker()
Definition: TemplateService.php:1176
‪TYPO3\CMS\Core\TimeTracker\TimeTracker\push
‪push(string $tslabel, string $value='')
Definition: TimeTracker.php:126
‪TYPO3\CMS\Webhooks\Message\$identifier
‪identifier readonly string $identifier
Definition: FileAddedMessage.php:37
‪TYPO3\CMS\Core\Database\Query\Restriction\DefaultRestrictionContainer
Definition: DefaultRestrictionContainer.php:24
‪TYPO3\CMS\Core\TypoScript\TemplateService\generateConfig
‪generateConfig()
Definition: TemplateService.php:849