‪TYPO3CMS  ‪main
TreeFromLineStreamBuilder.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 
41 
58 {
60  private string ‪$type;
62  private bool ‪$enableMagicIncludes = false;
63 
71  private array ‪$atImportTypeToSuffixMap = [
72  'constants' => ['typoscript'],
73  'setup' => ['typoscript'],
74  'other' => ['typoscript'],
75  'tsconfig' => ['typoscript', 'tsconfig'],
76  ];
77 
78  public function ‪__construct(
79  private readonly ‪FileNameValidator $fileNameValidator,
80  ) {}
81 
83  {
84  if (!in_array(‪$type, ['constants', 'setup', 'tsconfig', 'other'], true)) {
85  // Type "constants" and "setup" trigger the weird addStaticMagicFromGlobals() resolving, while "other" ignores it.
86  throw new \RuntimeException('type must be either "constants", "setup", "tsconfig" or "other"', 1652741356);
87  }
88  $this->type = ‪$type;
89  $this->tokenizer = ‪$tokenizer;
90  $this->enableMagicIncludes = ‪$enableMagicIncludes;
91  $this->‪buildTreeInternal($node);
92  }
93 
116  private function ‪buildTreeInternal(‪IncludeInterface $node): void
117  {
118  $parentNode = $node;
119  $givenTokenLineStream = $node->‪getLineStream();
120  $lineStream = new ‪LineStream();
121  $childNode = new ‪SegmentInclude();
122  $childNode->setName($node->‪getName());
123  $childNode->setPath($node->‪getPath());
124 
125  foreach ($givenTokenLineStream->getNextLine() as $line) {
126  if ($line instanceof ‪ConditionLine && $node instanceof ‪ConditionInclude) {
127  // Finish current condition when this line is another condition
128  $node->‪setSplit();
129  if (!$lineStream->isEmpty()) {
130  $childNode->setLineStream($lineStream);
131  $node->‪addChild($childNode);
132  $lineStream = new ‪LineStream();
133  }
134  $node = $parentNode;
135  }
136 
137  if ($line instanceof ‪ConditionLine) {
138  // A new condition not yet in condition context
139  $node->‪setSplit();
140  $conditionValueToken = $line->getTokenValue();
141  if (!$lineStream->isEmpty()) {
142  $childNode->setLineStream($lineStream);
143  $node->‪addChild($childNode);
144  $lineStream = new ‪LineStream();
145  }
146  $childNode = new ‪ConditionInclude();
147  $childNode->setSplit();
148  $childNode->setName($node->‪getName());
149  $childNode->setPath($node->‪getPath());
150  $childNode->setConditionToken($conditionValueToken);
151  $lineStream->append($line);
152  $childNode->setLineStream($lineStream);
153  $node->‪addChild($childNode);
154  $parentNode = $node;
155  $node = $childNode;
156  $childNode = new ‪SegmentInclude();
157  $childNode->setName($node->‪getName());
158  $childNode->setPath($node->‪getPath());
159  $lineStream = new ‪LineStream();
160  continue;
161  }
162 
163  if (($node instanceof ‪ConditionInclude || $node instanceof ‪ConditionElseInclude)
164  && $line instanceof ‪ConditionStopLine
165  ) {
166  // Finish condition segment due to [end] or [global] line
167  $node->‪setSplit();
168  $lineStream->append($line);
169  $childNode->setLineStream($lineStream);
170  $node->‪addChild($childNode);
171  $node = $parentNode;
172  $childNode = new ‪SegmentInclude();
173  $childNode->setName($node->‪getName());
174  $childNode->setPath($node->‪getPath());
175  $lineStream = new ‪LineStream();
176  continue;
177  }
178 
179  if ($node instanceof ‪ConditionInclude && $line instanceof ‪ConditionElseLine) {
180  // Active condition into [else] condition
181  $node->‪setSplit();
182  if (!$lineStream->isEmpty()) {
183  $childNode->setLineStream($lineStream);
184  $node->‪addChild($childNode);
185  }
186  $conditionToken = $node->getConditionToken();
187  $node = $parentNode;
188  $childNode = new ‪ConditionElseInclude();
189  $childNode->setSplit();
190  $childNode->setName($node->‪getName());
191  $childNode->setPath($node->‪getPath());
192  $childNode->setConditionToken($conditionToken);
193  $lineStream = new ‪LineStream();
194  $lineStream->append($line);
195  $childNode->setLineStream($lineStream);
196  $node->‪addChild($childNode);
197  $parentNode = $node;
198  $node = $childNode;
199  $childNode = new ‪SegmentInclude();
200  $childNode->setName($node->‪getName());
201  $childNode->setPath($node->‪getPath());
202  $lineStream = new ‪LineStream();
203  continue;
204  }
205 
206  if ($line instanceof ‪ImportLine) {
207  $node->‪setSplit();
208  $atImportValueToken = $line->getValueToken();
209  if (!$lineStream->isEmpty()) {
210  $childNode->setLineStream($lineStream);
211  $node->‪addChild($childNode);
212  $lineStream = new ‪LineStream();
213  }
214  $childNode = new ‪SegmentInclude();
215  $childNode->setName($node->‪getName());
216  $childNode->setPath($node->‪getPath());
217  $allowedSuffixes = $this->atImportTypeToSuffixMap[‪$this->type];
218  foreach ($allowedSuffixes as $allowedSuffix) {
219  $this->‪processAtImport($allowedSuffix, $node, $atImportValueToken, $line);
220  }
221  continue;
222  }
223 
224  if ($line instanceof ‪ImportOldLine) {
225  $node->‪setSplit();
226  $includeTypoScriptValueToken = $line->getValueToken();
227  if (!$lineStream->isEmpty()) {
228  $childNode->setLineStream($lineStream);
229  $node->‪addChild($childNode);
230  $lineStream = new ‪LineStream();
231  }
232  $childNode = new ‪SegmentInclude();
233  $childNode->setName($node->‪getName());
234  $childNode->setPath($node->‪getPath());
235  $this->‪processIncludeTyposcript($node, $includeTypoScriptValueToken, $line);
236  continue;
237  }
238 
239  $lineStream->append($line);
240  }
241 
242  if ($node->‪isSplit() && !$lineStream->isEmpty()) {
243  $childNode->setLineStream($lineStream);
244  $node->‪addChild($childNode);
245  }
246  }
247 
253  private function ‪processAtImport(string $fileSuffix, ‪IncludeInterface $node, ‪Token $atImportValueToken, ‪LineInterface $atImportLine, bool $tryRelative = false): void
254  {
255  $atImportValue = $atImportValueToken->‪getValue();
256  $atImportName = $atImportValue;
257  if ($tryRelative) {
258  if (empty($node->‪getPath())) {
259  return;
260  }
261  $parentPath = rtrim(dirname($node->‪getPath()), '/') . '/';
262  $atImportValue = ltrim($atImportValue, './');
263  $atImportName = preg_replace('#([:/])[^:/]+$#', '$1', $node->‪getName()) . $atImportValue;
264  $atImportValue = $parentPath . $atImportValue;
265  }
266  $absoluteFileName = rtrim(GeneralUtility::getFileAbsFileName($atImportValue), '/');
267  if ($absoluteFileName === '') {
268  return;
269  }
270  if (str_ends_with($absoluteFileName, '.' . $fileSuffix) && is_file($absoluteFileName)) {
271  // Simple file with allowed file suffix
272  if ($this->fileNameValidator->isValid($absoluteFileName)) {
273  $this->‪addSingleAtImportFile($node, $absoluteFileName, $atImportValue, $atImportName, $atImportLine);
274  $this->‪addStaticMagicFromGlobals($node, $atImportValue);
275  }
276  } elseif (is_dir($absoluteFileName)) {
277  // Directories with and without ending /
278  $filesAndDirs = scandir($absoluteFileName);
279  foreach ($filesAndDirs as $potentialInclude) {
280  if (!str_ends_with($potentialInclude, '.' . $fileSuffix)
281  || is_dir($absoluteFileName . '/' . $potentialInclude)
282  || !$this->fileNameValidator->isValid($absoluteFileName . '/' . $potentialInclude)
283  ) {
284  continue;
285  }
286  $singleAbsoluteFileName = $absoluteFileName . '/' . $potentialInclude;
287  ‪$identifier = rtrim($atImportValue, '/') . '/' . $potentialInclude;
288  $this->‪addSingleAtImportFile($node, $singleAbsoluteFileName, ‪$identifier, ‪$identifier, $atImportLine);
290  }
291  } elseif (is_file($absoluteFileName . '.' . $fileSuffix)) {
292  // File without .typoscript / .tsconfig suffix, but exists when suffix is added
293  if ($this->fileNameValidator->isValid($absoluteFileName . '.' . $fileSuffix)) {
294  $singleAbsoluteFileName = $absoluteFileName . '.' . $fileSuffix;
295  ‪$identifier = $atImportValue . '.' . $fileSuffix;
296  $this->‪addSingleAtImportFile($node, $singleAbsoluteFileName, ‪$identifier, ‪$identifier, $atImportLine);
298  }
299  } elseif (str_contains($absoluteFileName, '*')) {
300  // Something with *
301  $directory = rtrim(dirname($absoluteFileName) . '/');
302  $directoryExists = is_dir($directory);
303  if (!$directoryExists && str_starts_with($atImportValue, './') && !$tryRelative) {
304  // See if we can import some relative wildcard like "./Setup/*" or "./Setup/*.typoscript"
305  $this->‪processAtImport($fileSuffix, $node, $atImportValueToken, $atImportLine, true);
306  return;
307  }
308  if (!$directoryExists) {
309  // Absolute directory. There is nothing to import if the directory does not exist.
310  return;
311  }
312  $filePattern = basename($absoluteFileName);
313  if (!str_contains($filePattern, '*')) {
314  // The * wildcard must occur in the filename, wildcards in directories are not handled.
315  return;
316  }
317  if (mb_substr_count($filePattern, '*') > 1) {
318  // Only one wildcard character is allowed, foo*.bar*.typoscript is considered an invalid pattern.
319  return;
320  }
321  // Normalize right side, making sure it always ends with $fileSuffix ".typoscript" / ".tsconfig"
322  if (str_ends_with($filePattern, $fileSuffix)) {
323  $filePattern = mb_substr($filePattern, 0, -1 * strlen($fileSuffix));
324  $filePattern = rtrim($filePattern, '.');
325  }
326  $filePattern = $filePattern . '.' . $fileSuffix;
327  $wildcardPosition = mb_strpos($filePattern, '*');
328  $leftPrefix = mb_substr($filePattern, 0, $wildcardPosition);
329  $rightPrefix = mb_substr($filePattern, $wildcardPosition + 1);
330  $filesAndDirs = scandir($directory);
331  foreach ($filesAndDirs as $potentialInclude) {
332  if ($potentialInclude === '.'
333  || $potentialInclude === '..'
334  || !str_starts_with($potentialInclude, $leftPrefix)
335  || !str_ends_with($potentialInclude, $rightPrefix)
336  || is_dir($directory . $potentialInclude)
337  || !$this->fileNameValidator->isValid($directory . $potentialInclude)
338  ) {
339  continue;
340  }
341  $singleAbsoluteFileName = $directory . $potentialInclude;
342  ‪$identifier = rtrim(dirname($atImportValue), '/') . '/' . $potentialInclude;
343  $this->‪addSingleAtImportFile($node, $singleAbsoluteFileName, ‪$identifier, ‪$identifier, $atImportLine);
345  }
346  } elseif (!$tryRelative) {
347  // See if we can import relative "./foo.typoscript" or "foo.typoscript"
348  $this->‪processAtImport($fileSuffix, $node, $atImportValueToken, $atImportLine, true);
349  }
350  }
351 
357  private function ‪addSingleAtImportFile(
358  ‪IncludeInterface $parentNode,
359  string $absoluteFileName,
360  string $path,
361  string $name,
362  ‪LineInterface $atImportLine
363  ): void {
364  $content = file_get_contents($absoluteFileName);
365  $newNode = new ‪AtImportInclude();
366  $newNode->setName($name);
367  $newNode->setPath($path);
368  $newNode->setLineStream($this->tokenizer->tokenize($content));
369  $newNode->setOriginalLine($atImportLine);
370  $this->‪buildTreeInternal($newNode);
371  $parentNode->‪addChild($newNode);
372  }
373 
374  private function ‪processIncludeTyposcript(‪IncludeInterface $node, ‪Token $includeTyposcriptValueToken, ‪LineInterface $importKeywordOldLine): void
375  {
376  $fullString = $includeTyposcriptValueToken->‪getValue();
377  $potentialSourceArray = preg_split('#.*(source="[^"]*").*|>#', $fullString, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
378  $source = '';
379  foreach ($potentialSourceArray as $candidate) {
380  $candidate = trim($candidate);
381  if (str_starts_with($candidate, 'source="')) {
382  $source = rtrim(substr($candidate, 8), '"');
383  $source = str_replace([' ', "\t"], '', $source);
384  break;
385  }
386  }
387  if (empty($source)) {
388  // No 'source="..."'
389  return;
390  }
391  $potentialConditionArray = preg_split('#.*(condition="(?:\\\\\\\\|\\\\"|[^\"])*").*|>#', $fullString, 2, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
392  $condition = '';
393  foreach ($potentialConditionArray as $candidate) {
394  $candidate = trim($candidate);
395  if (str_starts_with($candidate, 'condition="')) {
396  $candidate = trim(substr($candidate, 10), '"');
397  if (str_starts_with($candidate, '[') && str_ends_with($candidate, ']')) {
398  // Cut off '[' and ']' if exist.
399  $candidate = mb_substr($candidate, 1, -1);
400  }
401  $condition = stripslashes($candidate);
402  break;
403  }
404  }
405  $potentialExtensionsArray = preg_split('#.*(extensions*="[^"]*").*|>#', $fullString, 2, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
406  $extensions = [];
407  foreach ($potentialExtensionsArray as $candidate) {
408  $candidate = trim($candidate);
409  if (str_starts_with($candidate, 'extensions="')) {
410  $extensions = ‪GeneralUtility::trimExplode(',', rtrim(substr($candidate, 12), '"'), true);
411  break;
412  }
413  }
414 
415  if (str_starts_with($source, 'FILE:./')) {
416  // Single relative file include
417  $fileName = dirname($node->‪getPath()) . '/' . substr($source, 7);
418  $absoluteFileName = rtrim(GeneralUtility::getFileAbsFileName($fileName), '/');
419  if ($absoluteFileName === '') {
420  return;
421  }
422  if ($this->fileNameValidator->isValid($absoluteFileName) && is_file($absoluteFileName)) {
423  $nodeToAddTo = $this->‪processConditionalIncludeTyposcript($node, $condition, $fileName);
424  $this->‪addSingleIncludeTyposcriptFile($nodeToAddTo, $absoluteFileName, $fileName, $importKeywordOldLine);
425  }
426  } elseif (str_starts_with($source, 'FILE:')) {
427  // Single file include, either prefixed with EXT:, or relative to public dir
428  // Throw away FILE:, then resolve EXT: or public dir relative
429  $fileName = substr($source, 5);
430  $absoluteFileName = rtrim(GeneralUtility::getFileAbsFileName($fileName), '/');
431  if ($absoluteFileName === '') {
432  return;
433  }
434  if ($this->fileNameValidator->isValid($absoluteFileName) && is_file($absoluteFileName)) {
435  $nodeToAddTo = $this->‪processConditionalIncludeTyposcript($node, $condition, $fileName);
436  $this->‪addSingleIncludeTyposcriptFile($nodeToAddTo, $absoluteFileName, $fileName, $importKeywordOldLine);
437  $this->‪addStaticMagicFromGlobals($nodeToAddTo, $fileName);
438  }
439  } elseif (str_starts_with($source, 'DIR:')) {
440  // Single file include, either prefixed with EXT:, or relative to public dir
441  // Throw away FILE:, then resolve EXT: or public dir relative
442  $dirName = substr($source, 4);
443  $absoluteDirName = rtrim(GeneralUtility::getFileAbsFileName($dirName), '/');
444  if ($absoluteDirName === '' || !is_dir($absoluteDirName)) {
445  return;
446  }
447  $nodeToAddTo = $this->‪processConditionalIncludeTyposcript($node, $condition, $dirName);
448  $this->‪importIncludeTyposcriptDirectoryRecursive($nodeToAddTo, $importKeywordOldLine, $dirName, $absoluteDirName, $extensions);
449  }
450  }
451 
458  private function ‪processConditionalIncludeTyposcript(‪IncludeInterface $parentNode, ?string $condition, string $fileName): ‪IncludeInterface
459  {
460  $nodeToAddTo = $parentNode;
461  if ($condition) {
462  $conditionNode = new ‪ConditionIncludeTyposcriptInclude();
463  $conditionNode->setName($fileName);
464  $conditionNode->setConditionToken(new ‪Token(TokenType::T_VALUE, $condition, 0, 0));
465  $conditionNode->setSplit();
466  $nodeToAddTo->addChild($conditionNode);
467  $nodeToAddTo = $conditionNode;
468  }
469  return $nodeToAddTo;
470  }
471 
473  ‪IncludeInterface $nodeToAddTo,
474  ‪LineInterface $importKeywordOldLine,
475  string $dirName,
476  string $absoluteDirName,
477  array $extensions
478  ): void {
479  $filesAndDirs = scandir($absoluteDirName);
480  $subDirs = [];
481  foreach ($filesAndDirs as $potentialInclude) {
482  // Handle files in this dir and remember possible sub-dirs
483  if ($potentialInclude === '.' || $potentialInclude === '..') {
484  continue;
485  }
486  if (is_dir($absoluteDirName . '/' . $potentialInclude)) {
487  $subDirs[] = $potentialInclude;
488  continue;
489  }
490  if (!$this->fileNameValidator->isValid($absoluteDirName . '/' . $potentialInclude)) {
491  continue;
492  }
493  if (!empty($extensions)) {
494  // Check if file is allowed by allowed 'extensions' setting if given
495  $fileIsAllowed = false;
496  foreach ($extensions as $extension) {
497  if (str_ends_with($potentialInclude, $extension)) {
498  $fileIsAllowed = true;
499  break;
500  }
501  }
502  if (!$fileIsAllowed) {
503  continue;
504  }
505  }
506  ‪$identifier = rtrim($dirName, '/') . '/' . $potentialInclude;
507  $absoluteFileName = $absoluteDirName . '/' . $potentialInclude;
508  $this->‪addSingleIncludeTyposcriptFile($nodeToAddTo, $absoluteFileName, ‪$identifier, $importKeywordOldLine);
509  }
510  foreach ($subDirs as $subDir) {
512  $nodeToAddTo,
513  $importKeywordOldLine,
514  $dirName . '/' . $subDir,
515  $absoluteDirName . '/' . $subDir,
516  $extensions
517  );
518  }
519  }
520 
526  private function ‪addSingleIncludeTyposcriptFile(‪IncludeInterface $parentNode, string $absoluteFileName, string $path, ‪LineInterface $importKeywordOldLine): void
527  {
528  $content = file_get_contents($absoluteFileName);
529  $newNode = new ‪IncludeTyposcriptInclude();
530  $newNode->setName($path);
531  $newNode->setPath($path);
532  $newNode->setLineStream($this->tokenizer->tokenize($content));
533  $newNode->setOriginalLine($importKeywordOldLine);
534  $this->‪buildTreeInternal($newNode);
535  $parentNode->‪addChild($newNode);
536  }
537 
543  private function ‪addStaticMagicFromGlobals(‪IncludeInterface $parentNode, string $path): void
544  {
545  if (!in_array($this->type, ['constants', 'setup'], true) || !str_starts_with($path, 'EXT:')) {
546  // This magic method is relevant for Frontend TypoScript only, indicated by
547  // $this->type being either "constants" or "setup".
548  return;
549  }
550  $includeStaticFileWithoutExt = substr($path, 4);
551  $includeStaticFileExtKeyAndPath = ‪GeneralUtility::trimExplode('/', $includeStaticFileWithoutExt, true, 2);
552  $extensionKey = $includeStaticFileExtKeyAndPath[0];
553  $extensionKeyWithoutUnderscores = str_replace('_', '', $extensionKey);
554  if (!$extensionKeyWithoutUnderscores || !‪ExtensionManagementUtility::isLoaded($extensionKey)) {
555  return;
556  }
557  // example: 'Configuration/TypoScript/MyStaticInclude/'
558  $pathSegmentWithAppendedSlash = rtrim(dirname($includeStaticFileExtKeyAndPath[1])) . '/';
559  $file = basename($path);
560  ‪$type = ‪GeneralUtility::trimExplode('.', $file, false, 2)[0] ?? '';
561  if (‪$type !== $this->type) {
562  return;
563  }
564  $globalsLookup = $extensionKeyWithoutUnderscores . '/' . $pathSegmentWithAppendedSlash;
565 
566  if (!$this->enableMagicIncludes) {
567  return;
568  }
569  // If this is a template of type "default content rendering", see if other extensions have added their TypoScript that should be included.
570  if (in_array($globalsLookup, ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['contentRenderingTemplates'], true)) {
571  $source = ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_' . ‪$type . '.']['defaultContentRendering'] ?? null;
572  if (!empty($source)) {
574  $node->setName('TYPO3_CONF_VARS defaultContentRendering for ' . $path);
575  $node->setLineStream($this->tokenizer->tokenize($source));
576  $this->‪buildTreeInternal($node);
577  $parentNode->‪addChild($node);
578  }
579  }
580  }
581 }
‪TYPO3\CMS\Core\TypoScript\IncludeTree\TreeFromLineStreamBuilder\$tokenizer
‪TokenizerInterface $tokenizer
Definition: TreeFromLineStreamBuilder.php:61
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Line\LineInterface
Definition: LineInterface.php:32
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Line\ConditionElseLine
Definition: ConditionElseLine.php:25
‪TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\IncludeInterface\getName
‪getName()
‪TYPO3\CMS\Core\TypoScript\IncludeTree\TreeFromLineStreamBuilder\processIncludeTyposcript
‪processIncludeTyposcript(IncludeInterface $node, Token $includeTyposcriptValueToken, LineInterface $importKeywordOldLine)
Definition: TreeFromLineStreamBuilder.php:374
‪TYPO3\CMS\Core\TypoScript\IncludeTree\TreeFromLineStreamBuilder\$type
‪string $type
Definition: TreeFromLineStreamBuilder.php:60
‪TYPO3\CMS\Core\TypoScript\IncludeTree
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Token\Token
Definition: Token.php:29
‪TYPO3\CMS\Core\Resource\Security\FileNameValidator
Definition: FileNameValidator.php:25
‪TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\SegmentInclude
Definition: SegmentInclude.php:32
‪TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\IncludeInterface\getPath
‪getPath()
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Token\TokenType
‪TokenType
Definition: TokenType.php:26
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Line\ImportLine
Definition: ImportLine.php:33
‪TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\IncludeInterface\addChild
‪addChild(IncludeInterface $node)
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Line\ImportOldLine
Definition: ImportOldLine.php:32
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Line\ConditionStopLine
Definition: ConditionStopLine.php:26
‪TYPO3\CMS\Core\TypoScript\IncludeTree\TreeFromLineStreamBuilder\$atImportTypeToSuffixMap
‪array $atImportTypeToSuffixMap
Definition: TreeFromLineStreamBuilder.php:71
‪TYPO3\CMS\Core\TypoScript\IncludeTree\TreeFromLineStreamBuilder
Definition: TreeFromLineStreamBuilder.php:58
‪TYPO3\CMS\Core\TypoScript\IncludeTree\TreeFromLineStreamBuilder\__construct
‪__construct(private readonly FileNameValidator $fileNameValidator,)
Definition: TreeFromLineStreamBuilder.php:78
‪TYPO3\CMS\Core\TypoScript\IncludeTree\TreeFromLineStreamBuilder\$enableMagicIncludes
‪bool $enableMagicIncludes
Definition: TreeFromLineStreamBuilder.php:62
‪TYPO3\CMS\Core\TypoScript\IncludeTree\TreeFromLineStreamBuilder\addStaticMagicFromGlobals
‪addStaticMagicFromGlobals(IncludeInterface $parentNode, string $path)
Definition: TreeFromLineStreamBuilder.php:543
‪TYPO3\CMS\Core\TypoScript\IncludeTree\TreeFromLineStreamBuilder\processConditionalIncludeTyposcript
‪processConditionalIncludeTyposcript(IncludeInterface $parentNode, ?string $condition, string $fileName)
Definition: TreeFromLineStreamBuilder.php:458
‪TYPO3\CMS\Core\TypoScript\IncludeTree\TreeFromLineStreamBuilder\processAtImport
‪processAtImport(string $fileSuffix, IncludeInterface $node, Token $atImportValueToken, LineInterface $atImportLine, bool $tryRelative=false)
Definition: TreeFromLineStreamBuilder.php:253
‪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\TreeFromLineStreamBuilder\addSingleIncludeTyposcriptFile
‪addSingleIncludeTyposcriptFile(IncludeInterface $parentNode, string $absoluteFileName, string $path, LineInterface $importKeywordOldLine)
Definition: TreeFromLineStreamBuilder.php:526
‪TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\IncludeInterface
Definition: IncludeInterface.php:39
‪TYPO3\CMS\Core\TypoScript\IncludeTree\TreeFromLineStreamBuilder\importIncludeTyposcriptDirectoryRecursive
‪importIncludeTyposcriptDirectoryRecursive(IncludeInterface $nodeToAddTo, LineInterface $importKeywordOldLine, string $dirName, string $absoluteDirName, array $extensions)
Definition: TreeFromLineStreamBuilder.php:472
‪TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\DefaultTypoScriptMagicKeyInclude
Definition: DefaultTypoScriptMagicKeyInclude.php:26
‪TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\ConditionInclude
Definition: ConditionInclude.php:29
‪TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\IncludeInterface\isSplit
‪isSplit()
‪TYPO3\CMS\Core\TypoScript\IncludeTree\TreeFromLineStreamBuilder\buildTreeInternal
‪buildTreeInternal(IncludeInterface $node)
Definition: TreeFromLineStreamBuilder.php:116
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Line\ConditionLine
Definition: ConditionLine.php:29
‪TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\IncludeTyposcriptInclude
Definition: IncludeTyposcriptInclude.php:25
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\IncludeInterface\setSplit
‪setSplit()
‪TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\IncludeInterface\getLineStream
‪getLineStream()
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Token\AbstractToken\getValue
‪getValue()
Definition: AbstractToken.php:65
‪TYPO3\CMS\Core\TypoScript\Tokenizer\TokenizerInterface
Definition: TokenizerInterface.php:40
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Core\TypoScript\IncludeTree\TreeFromLineStreamBuilder\buildTree
‪buildTree(IncludeInterface $node, string $type, TokenizerInterface $tokenizer, bool $enableMagicIncludes=true)
Definition: TreeFromLineStreamBuilder.php:82
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Line\LineStream
Definition: LineStream.php:29
‪TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\ConditionIncludeTyposcriptInclude
Definition: ConditionIncludeTyposcriptInclude.php:28
‪TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\ConditionElseInclude
Definition: ConditionElseInclude.php:34
‪TYPO3\CMS\Core\TypoScript\IncludeTree\TreeFromLineStreamBuilder\addSingleAtImportFile
‪addSingleAtImportFile(IncludeInterface $parentNode, string $absoluteFileName, string $path, string $name, LineInterface $atImportLine)
Definition: TreeFromLineStreamBuilder.php:357
‪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\TypoScript\IncludeTree\IncludeNode\AtImportInclude
Definition: AtImportInclude.php:27