‪TYPO3CMS  ‪main
TsConfigTreeBuilder.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 
23 use TYPO3\CMS\Core\Package\PackageManager;
33 
41 {
42  public function ‪__construct(
43  private readonly ‪TreeFromLineStreamBuilder $treeFromTokenStreamBuilder,
44  private readonly PackageManager $packageManager,
45  private readonly ‪EventDispatcher $eventDispatcher,
46  ) {}
47 
48  public function ‪getUserTsConfigTree(
49  ‪BackendUserAuthentication $backendUser,
50  ‪TokenizerInterface $tokenizer,
51  ?‪PhpFrontend $cache = null
52  ): ‪RootInclude {
53  $includeTree = new ‪RootInclude();
54 
55  $collectedUserTsConfigArray = [];
56  $gotPackagesUserTsConfigFromCache = false;
57  if ($cache) {
58  $collectedUserTsConfigArrayFromCache = $cache->require('usertsconfig-packages-strings');
59  if ($collectedUserTsConfigArrayFromCache) {
60  $gotPackagesUserTsConfigFromCache = true;
61  $collectedUserTsConfigArray = $collectedUserTsConfigArrayFromCache;
62  }
63  }
64  if (!$gotPackagesUserTsConfigFromCache) {
65  $event = $this->eventDispatcher->dispatch(new ‪BeforeLoadedUserTsConfigEvent());
66  $collectedUserTsConfigArray = $event->getTsConfig();
67  foreach ($this->packageManager->getActivePackages() as $package) {
68  $packagePath = $package->getPackagePath();
69  $tsConfigFile = null;
70  if (file_exists($packagePath . 'Configuration/user.tsconfig')) {
71  $tsConfigFile = $packagePath . 'Configuration/user.tsconfig';
72  } elseif (file_exists($packagePath . 'Configuration/User.tsconfig')) {
73  $tsConfigFile = $packagePath . 'Configuration/User.tsconfig';
74  }
75  if ($tsConfigFile) {
76  $typoScriptString = @file_get_contents($tsConfigFile);
77  if (!empty($typoScriptString)) {
78  $collectedUserTsConfigArray['userTsConfig-package-' . $package->getPackageKey()] = $typoScriptString;
79  }
80  }
81  }
82  $cache?->set('usertsconfig-packages-strings', 'return unserialize(\'' . addcslashes(serialize($collectedUserTsConfigArray), '\'\\') . '\');');
83  }
84  foreach ($collectedUserTsConfigArray as $key => $typoScriptString) {
85  $includeTree->addChild($this->‪getTreeFromString((string)$key, $typoScriptString, $tokenizer, $cache));
86  }
87 
88  // @deprecated since TYPO3 v13. Remove in v14 along with defaultUserTSconfig and EMU::addUserTSConfig
89  if (!empty(‪$GLOBALS['TYPO3_CONF_VARS']['BE']['defaultUserTSconfig'] ?? '')) {
90  $includeTree->addChild($this->‪getTreeFromString('userTsConfig-globals', ‪$GLOBALS['TYPO3_CONF_VARS']['BE']['defaultUserTSconfig'], $tokenizer, $cache));
91  }
92 
93  foreach ($backendUser->userGroupsUID as $groupId) {
94  // Loop through all groups and add their 'TSconfig' fields
95  if (!empty($backendUser->userGroups[$groupId]['TSconfig'] ?? '')) {
96  $includeTree->addChild($this->getTreeFromString('userTsConfig-group-' . $groupId, $backendUser->userGroups[$groupId]['TSconfig'], $tokenizer, $cache));
97  }
98  }
99  if (!empty($backendUser->user['TSconfig'] ?? '')) {
100  $includeTree->addChild($this->getTreeFromString('userTsConfig-user', $backendUser->user['TSconfig'], $tokenizer, $cache));
101  }
102 
103  return $includeTree;
104  }
105 
106  public function ‪getPagesTsConfigTree(
107  array $rootLine,
108  ‪TokenizerInterface $tokenizer,
109  ?‪PhpFrontend $cache = null
110  ): ‪RootInclude {
111  $collectedPagesTsConfigArray = [];
112  $gotPackagesPagesTsConfigFromCache = false;
113  if ($cache) {
114  $collectedPagesTsConfigArrayFromCache = $cache->require('pagestsconfig-packages-strings');
115  if ($collectedPagesTsConfigArrayFromCache) {
116  $gotPackagesPagesTsConfigFromCache = true;
117  $collectedPagesTsConfigArray = $collectedPagesTsConfigArrayFromCache;
118  }
119  }
120  if (!$gotPackagesPagesTsConfigFromCache) {
121  $event = $this->eventDispatcher->dispatch(new ‪BeforeLoadedPageTsConfigEvent());
122  $collectedPagesTsConfigArray = $event->getTsConfig();
123  foreach ($this->packageManager->getActivePackages() as $package) {
124  $packagePath = $package->getPackagePath();
125  $tsConfigFile = null;
126  if (file_exists($packagePath . 'Configuration/page.tsconfig')) {
127  $tsConfigFile = $packagePath . 'Configuration/page.tsconfig';
128  } elseif (file_exists($packagePath . 'Configuration/Page.tsconfig')) {
129  $tsConfigFile = $packagePath . 'Configuration/Page.tsconfig';
130  }
131  if ($tsConfigFile) {
132  $typoScriptString = @file_get_contents($tsConfigFile);
133  if (!empty($typoScriptString)) {
134  $collectedPagesTsConfigArray['pagesTsConfig-package-' . $package->getPackageKey()] = $typoScriptString;
135  }
136  }
137  }
138  $cache?->set('pagestsconfig-packages-strings', 'return unserialize(\'' . addcslashes(serialize($collectedPagesTsConfigArray), '\'\\') . '\');');
139  }
140 
141  // @deprecated since TYPO3 v13. Remove in v14 along with defaultPageTSconfig and EMU::addPageTSConfig
142  if (!empty(‪$GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPageTSconfig'] ?? '')) {
143  $collectedPagesTsConfigArray['pagesTsConfig-globals-defaultPageTSconfig'] = ‪$GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPageTSconfig'];
144  }
145 
146  foreach ($rootLine as $page) {
147  if (empty($page['uid'])) {
148  // Page 0 can happen when the rootline is given from BE context. It has not TSconfig. Skip this.
149  continue;
150  }
151  if (trim($page['tsconfig_includes'] ?? '')) {
152  $includeTsConfigFileList = ‪GeneralUtility::trimExplode(',', $page['tsconfig_includes'], true);
153  foreach ($includeTsConfigFileList as $key => $includeTsConfigFile) {
154  if (‪PathUtility::isExtensionPath($includeTsConfigFile)) {
155  [$includeTsConfigFileExtensionKey, $includeTsConfigFilename] = explode('/', substr($includeTsConfigFile, 4), 2);
156  if ($includeTsConfigFileExtensionKey !== ''
157  && ‪ExtensionManagementUtility::isLoaded($includeTsConfigFileExtensionKey)
158  && $includeTsConfigFilename !== ''
159  ) {
160  $extensionPath = ‪ExtensionManagementUtility::extPath($includeTsConfigFileExtensionKey);
161  $includeTsConfigFileAndPath = ‪PathUtility::getCanonicalPath($extensionPath . $includeTsConfigFilename);
162  if (str_starts_with($includeTsConfigFileAndPath, $extensionPath) && file_exists($includeTsConfigFileAndPath)) {
163  $typoScriptString = (string)file_get_contents($includeTsConfigFileAndPath);
164  if (!empty($typoScriptString)) {
165  $collectedPagesTsConfigArray['pagesTsConfig-page-' . $page['uid'] . '-includes-' . $key] = (string)file_get_contents($includeTsConfigFileAndPath);
166  }
167  }
168  }
169  }
170  }
171  }
172  if (!empty($page['TSconfig'])) {
173  $collectedPagesTsConfigArray['pagesTsConfig-page-' . $page['uid'] . '-tsConfig'] = $page['TSconfig'];
174  }
175  }
176 
177  $event = $this->eventDispatcher->dispatch(new ‪ModifyLoadedPageTsConfigEvent($collectedPagesTsConfigArray, $rootLine));
178  $collectedPagesTsConfigArray = $event->getTsConfig();
179 
180  $includeTree = new ‪RootInclude();
181  foreach ($collectedPagesTsConfigArray as $key => $typoScriptString) {
182  $includeTree->addChild($this->getTreeFromString((string)$key, $typoScriptString, $tokenizer, $cache));
183  }
184  return $includeTree;
185  }
186 
187  private function ‪getTreeFromString(
188  string $name,
189  string $typoScriptString,
190  ‪TokenizerInterface $tokenizer,
191  ?‪PhpFrontend $cache = null
192  ): ‪TsConfigInclude {
193  $lowercaseName = mb_strtolower($name);
194  ‪$identifier = $lowercaseName . '-' . hash('xxh3', $typoScriptString);
195  if ($cache) {
196  $includeNode = $cache->require(‪$identifier);
197  if ($includeNode instanceof ‪TsConfigInclude) {
198  return $includeNode;
199  }
200  }
201  $includeNode = new ‪TsConfigInclude();
202  $includeNode->setName($name);
203  $includeNode->setLineStream($tokenizer->‪tokenize($typoScriptString));
204  $this->treeFromTokenStreamBuilder->buildTree($includeNode, 'tsconfig', $tokenizer);
205  $cache?->set(‪$identifier, 'return unserialize(\'' . addcslashes(serialize($includeNode), '\'\\') . '\');');
206  return $includeNode;
207  }
208 }
‪TYPO3\CMS\Core\Utility\PathUtility\getCanonicalPath
‪static string getCanonicalPath(string $path)
Definition: PathUtility.php:364
‪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\TypoScript\IncludeTree\TsConfigTreeBuilder\__construct
‪__construct(private readonly TreeFromLineStreamBuilder $treeFromTokenStreamBuilder, private readonly PackageManager $packageManager, private readonly EventDispatcher $eventDispatcher,)
Definition: TsConfigTreeBuilder.php:42
‪TYPO3\CMS\Core\TypoScript\IncludeTree
‪TYPO3\CMS\Core\Cache\Frontend\PhpFrontend
Definition: PhpFrontend.php:25
‪TYPO3\CMS\Core\TypoScript\IncludeTree\TsConfigTreeBuilder\getUserTsConfigTree
‪getUserTsConfigTree(BackendUserAuthentication $backendUser, TokenizerInterface $tokenizer, ?PhpFrontend $cache=null)
Definition: TsConfigTreeBuilder.php:48
‪TYPO3\CMS\Core\TypoScript\IncludeTree\TreeFromLineStreamBuilder
Definition: TreeFromLineStreamBuilder.php:58
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\isLoaded
‪static isLoaded(string $key)
Definition: ExtensionManagementUtility.php:55
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility
Definition: ExtensionManagementUtility.php:32
‪TYPO3\CMS\Core\TypoScript\IncludeTree\TsConfigTreeBuilder\getTreeFromString
‪getTreeFromString(string $name, string $typoScriptString, TokenizerInterface $tokenizer, ?PhpFrontend $cache=null)
Definition: TsConfigTreeBuilder.php:187
‪TYPO3\CMS\Core\EventDispatcher\EventDispatcher
Definition: EventDispatcher.php:30
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\extPath
‪static extPath(string $key, string $script='')
Definition: ExtensionManagementUtility.php:82
‪TYPO3\CMS\Core\TypoScript\IncludeTree\TsConfigTreeBuilder\getPagesTsConfigTree
‪getPagesTsConfigTree(array $rootLine, TokenizerInterface $tokenizer, ?PhpFrontend $cache=null)
Definition: TsConfigTreeBuilder.php:106
‪TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\TsConfigInclude
Definition: TsConfigInclude.php:25
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:61
‪TYPO3\CMS\Core\TypoScript\IncludeTree\Event\BeforeLoadedPageTsConfigEvent
Definition: BeforeLoadedPageTsConfigEvent.php:28
‪TYPO3\CMS\Core\TypoScript\IncludeTree\Event\ModifyLoadedPageTsConfigEvent
Definition: ModifyLoadedPageTsConfigEvent.php:24
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\RootInclude
Definition: RootInclude.php:27
‪TYPO3\CMS\Core\TypoScript\Tokenizer\TokenizerInterface
Definition: TokenizerInterface.php:40
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Core\TypoScript\Tokenizer\TokenizerInterface\tokenize
‪tokenize(string $source)
‪TYPO3\CMS\Core\TypoScript\IncludeTree\Event\BeforeLoadedUserTsConfigEvent
Definition: BeforeLoadedUserTsConfigEvent.php:28
‪TYPO3\CMS\Core\TypoScript\IncludeTree\TsConfigTreeBuilder
Definition: TsConfigTreeBuilder.php:41
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static list< string > trimExplode(string $delim, string $string, bool $removeEmptyValues=false, int $limit=0)
Definition: GeneralUtility.php:817
‪TYPO3\CMS\Webhooks\Message\$identifier
‪identifier readonly string $identifier
Definition: FileAddedMessage.php:37