‪TYPO3CMS  ‪main
AstConstantCommentVisitor.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 
28 
35 {
36  private array ‪$categories = [
37  'basic' => [
38  'label' => 'Basic',
39  'usageCount' => 0,
40  ],
41  'menu' => [
42  'label' => 'Menu',
43  'usageCount' => 0,
44  ],
45  'content' => [
46  'label' => 'Content',
47  'usageCount' => 0,
48  ],
49  'page' => [
50  'label' => 'Page',
51  'usageCount' => 0,
52  ],
53  'advanced' => [
54  'label' => 'Advanced',
55  'usageCount' => 0,
56  ],
57  'all' => [
58  'label' => 'All',
59  'usageCount' => 0,
60  ],
61  ];
62 
63  private array ‪$subCategories = [
64  'enable' => [
65  'label' => 'Enable features',
66  'sorting' => 'a',
67  ],
68  'dims' => [
69  'label' => 'Dimensions, widths, heights, pixels',
70  'sorting' => 'b',
71  ],
72  'file' => [
73  'label' => 'Files',
74  'sorting' => 'c',
75  ],
76  'typo' => [
77  'label' => 'Typography',
78  'sorting' => 'd',
79  ],
80  'color' => [
81  'label' => 'Colors',
82  'sorting' => 'e',
83  ],
84  'links' => [
85  'label' => 'Links and targets',
86  'sorting' => 'f',
87  ],
88  'language' => [
89  'label' => 'Language specific constants',
90  'sorting' => 'g',
91  ],
92  'cheader' => [
93  'label' => 'Content: \'Header\'',
94  'sorting' => 'ma',
95  ],
96  'cheader_g' => [
97  'label' => 'Content: \'Header\', Graphical',
98  'sorting' => 'ma',
99  ],
100  'ctext' => [
101  'label' => 'Content: \'Text\'',
102  'sorting' => 'mb',
103  ],
104  'cimage' => [
105  'label' => 'Content: \'Image\'',
106  'sorting' => 'md',
107  ],
108  'ctextmedia' => [
109  'label' => 'Content: \'Textmedia\'',
110  'sorting' => 'ml',
111  ],
112  'cbullets' => [
113  'label' => 'Content: \'Bullet list\'',
114  'sorting' => 'me',
115  ],
116  'ctable' => [
117  'label' => 'Content: \'Table\'',
118  'sorting' => 'mf',
119  ],
120  'cuploads' => [
121  'label' => 'Content: \'Filelinks\'',
122  'sorting' => 'mg',
123  ],
124  'cmultimedia' => [
125  'label' => 'Content: \'Multimedia\'',
126  'sorting' => 'mh',
127  ],
128  'cmedia' => [
129  'label' => 'Content: \'Media\'',
130  'sorting' => 'mr',
131  ],
132  'cmailform' => [
133  'label' => 'Content: \'Form\'',
134  'sorting' => 'mi',
135  ],
136  'csearch' => [
137  'label' => 'Content: \'Search\'',
138  'sorting' => 'mj',
139  ],
140  'clogin' => [
141  'label' => 'Content: \'Login\'',
142  'sorting' => 'mk',
143  ],
144  'cmenu' => [
145  'label' => 'Content: \'Menu/Sitemap\'',
146  'sorting' => 'mm',
147  ],
148  'cshortcut' => [
149  'label' => 'Content: \'Insert records\'',
150  'sorting' => 'mn',
151  ],
152  'clist' => [
153  'label' => 'Content: \'List of records\'',
154  'sorting' => 'mo',
155  ],
156  'chtml' => [
157  'label' => 'Content: \'HTML\'',
158  'sorting' => 'mq',
159  ],
160  ];
161 
165  private int ‪$subCategoryCounter = 0;
166 
168 
169  private array ‪$constants = [];
170 
171  public function ‪visitBeforeChildren(‪RootNode $rootNode, ‪NodeInterface $node, ‪CurrentObjectPath $currentObjectPath, int $currentDepth): void
172  {
173  if ($node instanceof ‪RootNode) {
174  $rootNodeComments = $rootNode->‪getComments();
175  foreach ($rootNodeComments as $comment) {
176  $this->subCategoryCounter++;
177  // Additional custom categories are attached as comments to root node
179  }
180  } else {
181  $nodeComments = $node->‪getComments();
182  foreach ($nodeComments as $comment) {
183  $this->subCategoryCounter++;
184  $parsedCommentArray = $this->‪parseNodeComment($comment, $node->‪getName(), $node->‪getValue());
185  if (empty($parsedCommentArray)) {
186  continue;
187  }
188  $currentDottedPath = $currentObjectPath->‪getPathAsString();
189  if (array_key_exists($currentDottedPath, $this->constants)) {
190  // A constant definition can be defined only once. Stop when trying to override.
191  continue;
192  }
193  $parsedCommentArray['name'] = $currentDottedPath;
194  $parsedCommentArray['idName'] = str_replace('.', '-', $currentDottedPath);
195  $parsedCommentArray['value'] = $node->‪getValue();
196  $parsedCommentArray['default_value'] = $node->‪getPreviousValue() ?? $node->‪getValue() ?? '[Empty]';
197  $parsedCommentArray['isInCurrentTemplate'] = false;
198  if (array_key_exists($currentDottedPath, $this->currentTemplateFlatConstants)) {
199  $parsedCommentArray['isInCurrentTemplate'] = true;
200  }
201  $this->constants[$currentDottedPath] = $parsedCommentArray;
202  }
203  }
204  }
205 
207  {
208  $this->currentTemplateFlatConstants = ‪$currentTemplateFlatConstants;
209  }
210 
211  public function ‪getConstants(): array
212  {
213  return ‪$this->constants;
214  }
215 
216  public function ‪getCategories(): array
217  {
218  return ‪$this->categories;
219  }
220 
221  private function ‪parseNodeComment(‪TokenStreamInterface $commentTokenStream, string $nodeName, ?string $currentValue = null): array
222  {
223  $languageService = $this->‪getLanguageService();
224  $parsedCommentArray = [];
225  $commentTokenStream->‪reset();
226  $trimmedTokenStream = new ‪TokenStream();
227  while ($token = $commentTokenStream->‪getNext()) {
228  if ($token->getType() !== TokenType::T_BLANK) {
229  $trimmedTokenStream->append($token);
230  }
231  }
232  $firstTokenType = $trimmedTokenStream->peekNext()->getType();
233  if ($firstTokenType !== TokenType::T_COMMENT_ONELINE_HASH && $firstTokenType !== TokenType::T_COMMENT_ONELINE_DOUBLESLASH) {
234  // Ignore multiline comments, only '#' and '//' allowed here
235  return $parsedCommentArray;
236  }
237  $commentString = trim((string)$trimmedTokenStream);
238  // Get rid of '#' and '//'
239  $commentString = trim(preg_replace('/^[#\\/]*/', '', $commentString));
240  if (empty($commentString)) {
241  return $parsedCommentArray;
242  }
243  // "# cat=my custom: custom1/customsub1; type=string; label=custom1 customsub1 test1"
244  $commentParts = explode(';', $commentString);
245  foreach ($commentParts as $commentPart) {
246  if (!str_contains($commentPart, '=')) {
247  // Whatever it is, we ignore it.
248  continue;
249  }
250  $partArray = explode('=', $commentPart, 2);
251  $partKey = strtolower(trim($partArray[0] ?? ''));
252  $partValue = trim($partArray[1] ?? '');
253  if (empty($partKey) || empty($partValue)) {
254  continue;
255  }
256  if ($partKey === 'type') {
257  if (str_starts_with($partValue, 'int+')) {
258  $parsedCommentArray['type'] = 'int+';
259  $parsedCommentArray['typeIntPlusMin'] = 0;
260  preg_match('/int\+\[(.*)\]/is', $partValue, $typeMatches);
261  if (!empty($typeMatches[1]) && str_contains($typeMatches[1], '-')) {
262  $intPlusExplodedRange = ‪GeneralUtility::intExplode('-', $typeMatches[1]);
263  $parsedCommentArray['typeIntPlusMin'] = $intPlusExplodedRange[0];
264  $parsedCommentArray['typeHint'] = 'Greater than ' . $intPlusExplodedRange[0];
265  if ($intPlusExplodedRange[1] > 0) {
266  $parsedCommentArray['typeIntPlusMax'] = $intPlusExplodedRange[1];
267  $parsedCommentArray['typeHint'] = 'Range ' . $intPlusExplodedRange[0] . ' - ' . $intPlusExplodedRange[1];
268  }
269  }
270  } elseif (str_starts_with($partValue, 'int')) {
271  preg_match('/int\[(.*)\]/is', $partValue, $typeMatches);
272  $parsedCommentArray['type'] = 'int';
273  if (!empty($typeMatches[1]) && str_contains($typeMatches[1], '-')) {
274  $rangeArray = mb_str_split($typeMatches[1]);
275  $negativeStart = false;
276  $negativeStop = false;
277  $gotSeparatorDash = false;
278  $start = null;
279  $stop = null;
280  foreach ($rangeArray as $index => $char) {
281  if ($index === 0 && $char === '-') {
282  $negativeStart = true;
283  } elseif ($char === '-' && !$gotSeparatorDash) {
284  $gotSeparatorDash = true;
285  } elseif (!$gotSeparatorDash) {
286  $start .= $char;
287  } elseif ($stop === '' && $char === '-') {
288  $negativeStop = true;
289  } else {
290  $stop .= $char;
291  }
292  }
293  if ($start !== null) {
294  if ($negativeStart) {
295  $start = (int)$start * -1;
296  }
297  $parsedCommentArray['typeIntMin'] = (string)$start;
298  $parsedCommentArray['typeHint'] = 'Greater than ' . $start;
299  }
300  if ($stop !== null) {
301  if ($negativeStop) {
302  $stop = (int)$stop * -1;
303  }
304  $parsedCommentArray['typeIntMax'] = (string)$stop;
305  $parsedCommentArray['typeHint'] = 'Range ' . $start . ' - ' . $stop;
306  }
307  }
308  } elseif ($partValue === 'wrap') {
309  $parsedCommentArray['type'] = 'wrap';
310  $splitValue = explode('|', $currentValue ?? '');
311  $parsedCommentArray['wrapStart'] = $splitValue[0] ?? '';
312  $parsedCommentArray['wrapEnd'] = $splitValue[1] ?? '';
313  } elseif (str_starts_with($partValue, 'offset')) {
314  $parsedCommentArray['type'] = 'offset';
315  preg_match('/offset\[(.*)\]/is', $partValue, $typeMatches);
316  $labelArray = explode(',', $typeMatches[1] ?? '');
317  $valueArray = explode(',', $currentValue ?? '');
318  $parsedCommentArray['labelValueArray'] = [
319  [
320  'label' => (!empty($labelArray[0])) ? $labelArray[0] : 'x',
321  'value' => (!empty($valueArray[0])) ? $valueArray[0] : '',
322  ],
323  [
324  'label' => $labelArray[1] ?? 'y',
325  'value' => $valueArray[1] ?? '',
326  ],
327  ];
328  for ($i = 2; $i <= 5; $i++) {
329  if (!($labelArray[$i] ?? false)) {
330  break;
331  }
332  $parsedCommentArray['labelValueArray'][] = [
333  'label' => $labelArray[$i],
334  'value' => $valueArray[$i] ?? '',
335  ];
336  }
337  } elseif (str_starts_with($partValue, 'options')) {
338  preg_match('/options\\s*\[(.*)\]/is', $partValue, $typeMatches);
339  if (!empty($typeMatches[1] ?? '')) {
340  $parsedCommentArray['type'] = 'options';
341  $labelValueStringArray = ‪GeneralUtility::trimExplode(',', $typeMatches[1], true);
342  foreach ($labelValueStringArray as $labelValueString) {
343  $labelValueArray = explode('=', $labelValueString, 2);
344  $label = $labelValueArray[0];
345  $value = $labelValueArray[1] ?? $labelValueArray[0];
346  $selected = false;
347  if ($value === $currentValue) {
348  $selected = true;
349  }
350  $parsedCommentArray['labelValueArray'][] = [
351  'label' => $languageService->sL($label),
352  'value' => $value,
353  'selected' => $selected,
354  ];
355  }
356  }
357  } elseif (str_starts_with($partValue, 'boolean')) {
358  $parsedCommentArray['type'] = 'boolean';
359  preg_match('/boolean\\s*\[(.*)\]/is', $partValue, $typeMatches);
360  $parsedCommentArray['trueValue'] = '1';
361  if (!empty($typeMatches[1] ?? '')) {
362  $parsedCommentArray['trueValue'] = $typeMatches[1];
363  }
364  } elseif (str_starts_with($partValue, 'user')) {
365  preg_match('/user\\s*\[(.*)\]/is', $partValue, $typeMatches);
366  if (!empty($typeMatches[1] ?? '')) {
367  $parsedCommentArray['type'] = 'user';
368  $userFunction = $typeMatches[1];
369  $userFunctionParams = [
370  'fieldName' => $nodeName,
371  'fieldValue' => $currentValue,
372  ];
373  $parsedCommentArray['html'] = (string)GeneralUtility::callUserFunction($userFunction, $userFunctionParams);
374  }
375  } elseif ($partValue === 'comment') {
376  $parsedCommentArray['type'] = 'comment';
377  } elseif ($partValue === 'color') {
378  $parsedCommentArray['type'] = 'color';
379  } else {
380  $parsedCommentArray['type'] = 'string';
381  }
382  } elseif ($partKey === 'cat') {
383  $categorySplitArray = explode('/', strtolower($partValue));
384  $mainCategory = strtolower(trim($categorySplitArray[0] ?? ''));
385  if (empty($mainCategory)) {
386  return [];
387  }
388  if (isset($this->categories[$mainCategory])) {
389  $this->categories[$mainCategory]['usageCount']++;
390  } else {
391  $this->categories[$mainCategory] = [
392  'usageCount' => 1,
393  'label' => $mainCategory,
394  ];
395  }
396  $parsedCommentArray['cat'] = $mainCategory;
397  $subCategory = trim($categorySplitArray[1] ?? '');
398  $subCategoryOrder = trim($categorySplitArray[2] ?? '');
399  if ($subCategory && array_key_exists($subCategory, $this->subCategories)) {
400  $parsedCommentArray['subcat_name'] = $subCategory;
401  $parsedCommentArray['subcat_label'] = $languageService->sL($this->subCategories[$subCategory]['label']);
402  $sortIdentifier = empty($subCategoryOrder) ? $this->subCategoryCounter : $subCategoryOrder;
403  $parsedCommentArray['subcat_sorting_first'] = $this->subCategories[$subCategory]['sorting'];
404  $parsedCommentArray['subcat_sorting_second'] = $sortIdentifier . 'z';
405  } elseif ($subCategoryOrder) {
406  $parsedCommentArray['subcat_name'] = 'other';
407  $parsedCommentArray['subcat_label'] = 'Other';
408  $parsedCommentArray['subcat_sorting_first'] = 'o';
409  $parsedCommentArray['subcat_sorting_second'] = $subCategoryOrder . 'z';
410  } else {
411  $parsedCommentArray['subcat_name'] = 'other';
412  $parsedCommentArray['subcat_label'] = 'Other';
413  $parsedCommentArray['subcat_sorting_first'] = 'o';
414  $parsedCommentArray['subcat_sorting_second'] = $this->subCategoryCounter . 'z';
415  }
416  } elseif ($partKey === 'label') {
417  $fullLabel = $languageService->sL($partValue);
418  $splitLabelArray = explode(':', $fullLabel, 2);
419  $parsedCommentArray['label'] = $splitLabelArray[0] ?? '';
420  $parsedCommentArray['description'] = $splitLabelArray[1] ?? '';
421  }
422  }
423  if (!array_key_exists('cat', $parsedCommentArray)) {
424  // At least 'category' must be there, everything else is optional.
425  return [];
426  }
427  $parsedCommentArray['type'] ??= 'string';
428  return $parsedCommentArray;
429  }
430 
435  private function ‪parseCustomCategoryAndSubCategories(‪TokenStreamInterface $commentTokenStream): void
436  {
437  $languageService = $this->‪getLanguageService();
438  $firstTokenType = $commentTokenStream->‪peekNext()->getType();
439  if ($firstTokenType !== TokenType::T_COMMENT_ONELINE_HASH && $firstTokenType !== TokenType::T_COMMENT_ONELINE_DOUBLESLASH) {
440  // Ignore multiline comments, only '#' and '//' allowed here
441  return;
442  }
443  $commentString = trim((string)$commentTokenStream);
444  // Get rid of '#' and '//'
445  $commentString = trim(preg_replace('/^[#\\/]*/', '', $commentString));
446  if (empty($commentString)) {
447  return;
448  }
449  // "# customcategory=myCustomCategoryKey=My custom category label"
450  if (str_contains($commentString, '=') && str_starts_with(strtolower($commentString), 'customcategory')) {
451  $customCategoryArray = explode('=', $commentString, 3);
452  if (strtolower(trim($customCategoryArray[0])) !== 'customcategory'
453  || empty(trim($customCategoryArray[1]))
454  || empty(trim($customCategoryArray[2]))
455  ) {
456  return;
457  }
458  $categoryKey = strtolower($customCategoryArray[1]);
459  $categoryLabel = $customCategoryArray[2];
460  if (!isset($this->categories[$categoryKey])) {
461  $this->categories[$categoryKey] = [
462  'usageCount' => 0,
463  'label' => $languageService->sL($categoryLabel),
464  ];
465  }
466  return;
467  }
468  // "customsubcategory=120=My custom sub category label"
469  if (str_contains($commentString, '=') && str_starts_with(strtolower($commentString), 'customsubcategory')) {
470  $customSubCategoryArray = explode('=', $commentString, 3);
471  if (strtolower(trim($customSubCategoryArray[0])) !== 'customsubcategory'
472  || empty(trim($customSubCategoryArray[1]))
473  || empty(trim($customSubCategoryArray[2]))
474  ) {
475  return;
476  }
477  $subCategoryKey = strtolower($customSubCategoryArray[1]);
478  $subCategoryLabel = $customSubCategoryArray[2];
479  if (!isset($this->subCategories[$subCategoryKey])) {
480  $this->subCategories[$subCategoryKey] = [
481  'label' => $languageService->sL($subCategoryLabel),
482  'sorting' => ‪$this->subCategoryCounter,
483  ];
484  }
485  }
486  }
487 
488  public function ‪visit(‪RootNode $rootNode, ‪NodeInterface $node, ‪CurrentObjectPath $currentObjectPath, int $currentDepth): void
489  {
490  // Implement interface
491  }
492 
493  public function ‪visitAfterChildren(‪RootNode $rootNode, ‪NodeInterface $node, ‪CurrentObjectPath $currentObjectPath, int $currentDepth): void
494  {
495  // Implement interface
496  }
497 
499  {
500  return ‪$GLOBALS['LANG'];
501  }
502 }
‪TYPO3\CMS\Core\TypoScript\AST\Visitor\AstConstantCommentVisitor\$currentTemplateFlatConstants
‪array $currentTemplateFlatConstants
Definition: AstConstantCommentVisitor.php:167
‪TYPO3\CMS\Core\TypoScript\AST\Visitor\AstConstantCommentVisitor\getConstants
‪getConstants()
Definition: AstConstantCommentVisitor.php:211
‪TYPO3\CMS\Core\TypoScript\AST\Visitor\AstConstantCommentVisitor\$subCategories
‪array $subCategories
Definition: AstConstantCommentVisitor.php:63
‪TYPO3\CMS\Core\TypoScript\AST\Visitor\AstConstantCommentVisitor\getCategories
‪getCategories()
Definition: AstConstantCommentVisitor.php:216
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Token\TokenType
‪TokenType
Definition: TokenType.php:26
‪TYPO3\CMS\Core\TypoScript\AST\Visitor\AstConstantCommentVisitor\$subCategoryCounter
‪int $subCategoryCounter
Definition: AstConstantCommentVisitor.php:165
‪TYPO3\CMS\Core\TypoScript\AST\Node\NodeInterface
Definition: NodeInterface.php:35
‪TYPO3\CMS\Core\TypoScript\AST\Visitor\AstVisitorInterface
Definition: AstVisitorInterface.php:30
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Token\TokenStreamInterface\reset
‪reset()
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Token\TokenStreamInterface
Definition: TokenStreamInterface.php:30
‪TYPO3\CMS\Core\TypoScript\AST\Visitor
Definition: AstConstantCommentVisitor.php:18
‪TYPO3\CMS\Core\TypoScript\AST\Node\NodeInterface\getComments
‪TokenStreamInterface[] getComments()
‪TYPO3\CMS\Core\TypoScript\AST\CurrentObjectPath\CurrentObjectPath\getPathAsString
‪getPathAsString()
Definition: CurrentObjectPath.php:64
‪TYPO3\CMS\Core\TypoScript\AST\Visitor\AstConstantCommentVisitor\visitAfterChildren
‪visitAfterChildren(RootNode $rootNode, NodeInterface $node, CurrentObjectPath $currentObjectPath, int $currentDepth)
Definition: AstConstantCommentVisitor.php:493
‪TYPO3\CMS\Core\TypoScript\AST\CurrentObjectPath\CurrentObjectPath
Definition: CurrentObjectPath.php:32
‪TYPO3\CMS\Core\TypoScript\AST\Visitor\AstConstantCommentVisitor\getLanguageService
‪getLanguageService()
Definition: AstConstantCommentVisitor.php:498
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Token\TokenStream
Definition: TokenStream.php:26
‪TYPO3\CMS\Core\TypoScript\AST\Visitor\AstConstantCommentVisitor\parseCustomCategoryAndSubCategories
‪parseCustomCategoryAndSubCategories(TokenStreamInterface $commentTokenStream)
Definition: AstConstantCommentVisitor.php:435
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Token\TokenStreamInterface\getNext
‪getNext()
‪TYPO3\CMS\Core\TypoScript\AST\Node\AbstractNode\getComments
‪TokenStreamInterface[] getComments()
Definition: AbstractNode.php:181
‪TYPO3\CMS\Core\TypoScript\AST\Visitor\AstConstantCommentVisitor\visitBeforeChildren
‪visitBeforeChildren(RootNode $rootNode, NodeInterface $node, CurrentObjectPath $currentObjectPath, int $currentDepth)
Definition: AstConstantCommentVisitor.php:171
‪TYPO3\CMS\Core\TypoScript\AST\Visitor\AstConstantCommentVisitor\setCurrentTemplateFlatConstants
‪setCurrentTemplateFlatConstants(array $currentTemplateFlatConstants)
Definition: AstConstantCommentVisitor.php:206
‪TYPO3\CMS\Core\TypoScript\AST\Node\NodeInterface\getPreviousValue
‪getPreviousValue()
‪TYPO3\CMS\Core\TypoScript\AST\Visitor\AstConstantCommentVisitor\visit
‪visit(RootNode $rootNode, NodeInterface $node, CurrentObjectPath $currentObjectPath, int $currentDepth)
Definition: AstConstantCommentVisitor.php:488
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Token\TokenStreamInterface\peekNext
‪peekNext()
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\TypoScript\AST\Node\RootNode
Definition: RootNode.php:26
‪TYPO3\CMS\Core\TypoScript\AST\Node\NodeInterface\getName
‪getName()
‪TYPO3\CMS\Core\TypoScript\AST\Visitor\AstConstantCommentVisitor\parseNodeComment
‪parseNodeComment(TokenStreamInterface $commentTokenStream, string $nodeName, ?string $currentValue=null)
Definition: AstConstantCommentVisitor.php:221
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:46
‪TYPO3\CMS\Core\TypoScript\AST\Visitor\AstConstantCommentVisitor\$constants
‪array $constants
Definition: AstConstantCommentVisitor.php:169
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Core\Utility\GeneralUtility\intExplode
‪static list< int > intExplode(string $delimiter, string $string, bool $removeEmptyValues=false)
Definition: GeneralUtility.php:756
‪TYPO3\CMS\Core\TypoScript\AST\Visitor\AstConstantCommentVisitor\$categories
‪array $categories
Definition: AstConstantCommentVisitor.php:36
‪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\Core\TypoScript\AST\Node\NodeInterface\getValue
‪getValue()
‪TYPO3\CMS\Core\TypoScript\AST\Visitor\AstConstantCommentVisitor
Definition: AstConstantCommentVisitor.php:35