‪TYPO3CMS  ‪main
PageTsConfigParser.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 
24 
35 {
38 
40  {
41  trigger_error('Class ' . __CLASS__ . ' will be removed with TYPO3 v13.0. Use PageTsConfigFactory instead.', E_USER_DEPRECATED);
42  $this->typoScriptParser = ‪$typoScriptParser;
43  $this->cache = ‪$cache;
44  }
45 
59  public function ‪parse(string $content, ‪ConditionMatcherInterface $matcher, ?‪Site $site = null): array
60  {
61  if ($site) {
62  $siteSettings = $site->getSettings();
63  if (!$siteSettings->isEmpty()) {
64  $siteSettings = $siteSettings->getAllFlat();
65  // Recursive substitution of site settings (up to 10 nested levels)
66  for ($i = 0; $i < 10; $i++) {
67  $beforeSubstitution = $content;
68  $content = preg_replace_callback(
69  '/\\{\\$(.[^}]*)\\}/',
70  static function (array $matches) use ($siteSettings): string {
71  return isset($siteSettings[$matches[1]]) && !is_array($siteSettings[$matches[1]])
72  ? (string)$siteSettings[$matches[1]] : $matches[0];
73  },
74  $content
75  );
76  if ($beforeSubstitution === $content) {
77  break;
78  }
79  }
80  }
81  }
82 
83  $hashOfContent = md5('PAGES:' . $content);
84  $cachedContent = $this->cache->get($hashOfContent);
85  // Something about this content has been cached before, lets verify the matchings, if they also apply
86  if (is_array($cachedContent) && is_array($cachedContent[0])) {
87  // Cache entry found, see if the "matching" section matches with the matcher
88  $storedData = $cachedContent[0];
89  $storedMD5 = $cachedContent[1];
90  $storedData['match'] = $this->‪matching($storedData['sections'] ?? [], $matcher);
91  $hashOfDataWithMatches = md5(json_encode($storedData));
92  // The matches are the same, so nothing to do here
93  if ($hashOfDataWithMatches === $storedMD5) {
94  $result = $storedData['TSconfig'];
95  } else {
96  // Create a hash out of the content-hash PLUS the matching information and try again
97  $shash = md5($hashOfDataWithMatches . $hashOfContent);
98  $storedData = $this->cache->get($shash);
99  if (is_array($storedData)) {
100  $result = $storedData['TSconfig'];
101  } else {
102  // Create a new content with the matcher, and cache it as a new entry
103  $parsedAndMatchedData = $this->‪parseAndMatch($content, $matcher);
104  // Now store the full data from the parser (with matches)
105  $this->cache->set($shash, $parsedAndMatchedData, ['pageTSconfig'], 0);
106  $result = $parsedAndMatchedData['TSconfig'];
107  }
108  }
109  return $result;
110  }
111 
112  // Nothing found in cache for this content string, let's do everything.
113  $parsedAndMatchedData = $this->‪parseAndMatch($content, $matcher);
114  // ALL parts, including the matching part is cached.
115  $md5 = md5(json_encode($parsedAndMatchedData));
116  $this->cache->set($hashOfContent, [$parsedAndMatchedData, $md5], ['pageTSconfig'], 0);
117  return $parsedAndMatchedData['TSconfig'];
118  }
119 
126  protected function ‪parseAndMatch(string $content, ‪ConditionMatcherInterface $matcher): array
127  {
128  $this->typoScriptParser->parse($content, $matcher);
129  return [
130  'TSconfig' => $this->typoScriptParser->setup,
131  'sections' => $this->typoScriptParser->sections,
132  'match' => $this->typoScriptParser->sectionsMatch,
133  ];
134  }
135 
142  protected function ‪matching(array $sectionsToMatch, ‪ConditionMatcherInterface $matcher): array
143  {
144  $matches = [];
145  foreach ($sectionsToMatch ?? [] as $key => $pre) {
146  if ($matcher->‪match($pre)) {
147  $matches[$key] = $pre;
148  }
149  }
150  return $matches;
151  }
152 }
‪TYPO3\CMS\Core\Configuration\Parser\PageTsConfigParser\parse
‪array parse(string $content, ConditionMatcherInterface $matcher, ?Site $site=null)
Definition: PageTsConfigParser.php:59
‪TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser
Definition: TypoScriptParser.php:38
‪TYPO3\CMS\Core\Configuration\Parser\PageTsConfigParser\$typoScriptParser
‪TypoScriptParser $typoScriptParser
Definition: PageTsConfigParser.php:36
‪TYPO3\CMS\Core\Site\Entity\Site
Definition: Site.php:42
‪TYPO3\CMS\Core\Configuration\Parser\PageTsConfigParser\$cache
‪FrontendInterface $cache
Definition: PageTsConfigParser.php:37
‪TYPO3\CMS\Core\Configuration\Parser\PageTsConfigParser\matching
‪array matching(array $sectionsToMatch, ConditionMatcherInterface $matcher)
Definition: PageTsConfigParser.php:142
‪TYPO3\CMS\Core\Configuration\TypoScript\ConditionMatching\ConditionMatcherInterface
Definition: ConditionMatcherInterface.php:26
‪TYPO3\CMS\Core\Configuration\TypoScript\ConditionMatching\ConditionMatcherInterface\match
‪bool match($expression)
‪TYPO3\CMS\Core\Configuration\Parser\PageTsConfigParser\parseAndMatch
‪array parseAndMatch(string $content, ConditionMatcherInterface $matcher)
Definition: PageTsConfigParser.php:126
‪TYPO3\CMS\Core\Configuration\Parser\PageTsConfigParser
Definition: PageTsConfigParser.php:35
‪TYPO3\CMS\Core\Configuration\Parser\PageTsConfigParser\__construct
‪__construct(TypoScriptParser $typoScriptParser, FrontendInterface $cache)
Definition: PageTsConfigParser.php:39
‪TYPO3\CMS\Core\Cache\Frontend\FrontendInterface
Definition: FrontendInterface.php:22
‪TYPO3\CMS\Core\Configuration\Parser
Definition: PageTsConfigParser.php:18