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