‪TYPO3CMS  ‪main
SiteConfiguration.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 
20 use Psr\EventDispatcher\EventDispatcherInterface;
21 use Symfony\Component\DependencyInjection\Attribute\Autowire;
22 use Symfony\Component\Finder\Finder;
23 use Symfony\Component\Yaml\Yaml;
38 
47 {
53  protected string ‪$configFileName = 'config.yaml';
54 
60  protected string ‪$typoScriptSetupFileName = 'setup.typoscript';
61 
67  protected string ‪$typoScriptConstantsFileName = 'constants.typoscript';
68 
74  protected string ‪$pageTSconfigFileName = 'page.tsconfig';
75 
81  protected string ‪$contentSecurityFileName = 'csp.yaml';
82 
88  protected string ‪$cacheIdentifier = 'sites-configuration';
89 
96  protected ‪$firstLevelCache;
97 
98  public function ‪__construct(
99  #[Autowire('%env(TYPO3:configPath)%/sites')]
100  protected string $configPath,
101  protected ‪SiteSettingsFactory $siteSettingsFactory,
102  protected EventDispatcherInterface $eventDispatcher,
103  #[Autowire(service: 'cache.core')]
104  protected ‪PhpFrontend $cache
105  ) {}
106 
112  public function ‪getAllExistingSites(bool $useCache = true): array
113  {
114  if ($useCache && $this->firstLevelCache !== null) {
116  }
117  return $this->‪resolveAllExistingSites($useCache);
118  }
119 
125  public function ‪resolveAllExistingSites(bool $useCache = true): array
126  {
127  $sites = [];
128  $siteConfiguration = $this->‪getAllSiteConfigurationFromFiles($useCache);
129  foreach ($siteConfiguration as ‪$identifier => $configuration) {
130  // cast $identifier to string, as the identifier can potentially only consist of (int) digit numbers
131  ‪$identifier = (string)‪$identifier;
132  $siteSettings = $this->siteSettingsFactory->getSettings(‪$identifier, $configuration);
133  $siteTypoScript = $this->‪getSiteTypoScript(‪$identifier);
134  $siteTSconfig = $this->‪getSiteTSconfig(‪$identifier);
135  $configuration['contentSecurityPolicies'] = $this->‪getContentSecurityPolicies(‪$identifier);
136 
137  $rootPageId = (int)($configuration['rootPageId'] ?? 0);
138  if ($rootPageId > 0) {
139  $sites[‪$identifier] = new Site(‪$identifier, $rootPageId, $configuration, $siteSettings, $siteTypoScript, $siteTSconfig);
140  }
141  }
142  $this->firstLevelCache = $sites;
143  return $sites;
144  }
145 
153  public function ‪resolveAllExistingSitesRaw(): array
154  {
155  $sites = [];
156  $siteConfiguration = $this->‪getAllSiteConfigurationFromFiles(false);
157  foreach ($siteConfiguration as ‪$identifier => $configuration) {
158  // cast $identifier to string, as the identifier can potentially only consist of (int) digit numbers
159  ‪$identifier = (string)‪$identifier;
160  $siteSettings = new SiteSettings($configuration['settings'] ?? []);
161  $siteTypoScript = $this->‪getSiteTypoScript(‪$identifier);
162 
163  $rootPageId = (int)($configuration['rootPageId'] ?? 0);
164  if ($rootPageId > 0) {
165  $sites[‪$identifier] = new Site(‪$identifier, $rootPageId, $configuration, $siteSettings, $siteTypoScript);
166  }
167  }
168  return $sites;
169  }
170 
176  public function ‪getAllSiteConfigurationPaths(): array
177  {
178  ‪$finder = new Finder();
179  $paths = [];
180  try {
181  ‪$finder->files()->depth(0)->name($this->configFileName)->in($this->configPath . '/*');
182  } catch (\InvalidArgumentException $e) {
183  ‪$finder = [];
184  }
185 
186  foreach (‪$finder as $fileInfo) {
187  $path = $fileInfo->getPath();
188  $paths[basename($path)] = $path;
189  }
190  return $paths;
191  }
192 
198  protected function ‪getAllSiteConfigurationFromFiles(bool $useCache = true): array
199  {
200  // Check if the data is already cached
201  $siteConfiguration = $useCache ? $this->cache->require($this->cacheIdentifier) : false;
202  if ($siteConfiguration !== false) {
203  return $siteConfiguration;
204  }
205  ‪$finder = new Finder();
206  try {
207  ‪$finder->files()->depth(0)->name($this->configFileName)->in($this->configPath . '/*');
208  } catch (\InvalidArgumentException $e) {
209  // Directory $this->configPath does not exist yet
210  ‪$finder = [];
211  }
212  $loader = GeneralUtility::makeInstance(YamlFileLoader::class);
213  $siteConfiguration = [];
214  foreach (‪$finder as $fileInfo) {
215  $configuration = $loader->load(GeneralUtility::fixWindowsFilePath((string)$fileInfo));
216  ‪$identifier = basename($fileInfo->getPath());
217  $event = $this->eventDispatcher->dispatch(new SiteConfigurationLoadedEvent(‪$identifier, $configuration));
218  $siteConfiguration[‪$identifier] = $event->getConfiguration();
219  }
220  $this->cache->set($this->cacheIdentifier, 'return ' . var_export($siteConfiguration, true) . ';');
221 
222  return $siteConfiguration;
223  }
224 
235  public function ‪load(string ‪$siteIdentifier): array
236  {
237  $fileName = $this->configPath . '/' . ‪$siteIdentifier . '/' . ‪$this->configFileName;
238  $loader = GeneralUtility::makeInstance(YamlFileLoader::class);
239  return $loader->load(GeneralUtility::fixWindowsFilePath($fileName), ‪YamlFileLoader::PROCESS_IMPORTS);
240  }
241 
242  protected function ‪getSiteTypoScript(string ‪$siteIdentifier): ?‪SiteTypoScript
243  {
244  $data = [
247  ];
248  $definitions = [];
249  foreach ($data as $type => $fileName) {
250  $path = $this->configPath . '/' . ‪$siteIdentifier . '/' . $fileName;
251  if (file_exists($path)) {
252  $contents = @file_get_contents(GeneralUtility::fixWindowsFilePath($path));
253  if ($contents !== false) {
254  $definitions[$type] = $contents;
255  }
256  }
257  }
258  if ($definitions === []) {
259  return null;
260  }
261  return new ‪SiteTypoScript(...$definitions);
262  }
263 
264  protected function ‪getSiteTSconfig(string ‪$siteIdentifier): ?‪SiteTSconfig
265  {
266  $pageTSconfig = null;
267  $path = $this->configPath . '/' . ‪$siteIdentifier . '/' . ‪$this->pageTSconfigFileName;
268  if (file_exists($path)) {
269  $contents = @file_get_contents(GeneralUtility::fixWindowsFilePath($path));
270  if ($contents !== false) {
271  $pageTSconfig = $contents;
272  }
273  }
274  if ($pageTSconfig === null) {
275  return null;
276  }
277 
278  return new ‪SiteTSconfig(
279  pageTSconfig: $pageTSconfig
280  );
281  }
282 
283  protected function ‪getContentSecurityPolicies(string ‪$siteIdentifier): array
284  {
285  $fileName = $this->configPath . '/' . ‪$siteIdentifier . '/' . ‪$this->contentSecurityFileName;
286  if (file_exists($fileName)) {
287  $loader = GeneralUtility::makeInstance(YamlFileLoader::class);
288  return $loader->load(GeneralUtility::fixWindowsFilePath($fileName), ‪YamlFileLoader::PROCESS_IMPORTS);
289  }
290  return [];
291  }
292 
293  #[AsEventListener(event: SiteConfigurationChangedEvent::class)]
294  public function ‪siteConfigurationChanged()
295  {
296  $this->firstLevelCache = null;
297  }
298 
299  #[AsEventListener('typo3-core/site-configuration')]
300  public function ‪warmupCaches(‪CacheWarmupEvent $event): void
301  {
302  if ($event->‪hasGroup('system')) {
304  }
305  }
306 }
‪TYPO3\CMS\Core\Configuration\Loader\YamlFileLoader\PROCESS_IMPORTS
‪const PROCESS_IMPORTS
Definition: YamlFileLoader.php:52
‪TYPO3\CMS\Core\Configuration\SiteConfiguration\__construct
‪__construct(#[Autowire('%env(TYPO3:configPath)%/sites')] protected string $configPath, protected SiteSettingsFactory $siteSettingsFactory, protected EventDispatcherInterface $eventDispatcher, #[Autowire(service:'cache.core')] protected PhpFrontend $cache)
Definition: SiteConfiguration.php:97
‪TYPO3\CMS\Core\Configuration\SiteConfiguration\getSiteTSconfig
‪getSiteTSconfig(string $siteIdentifier)
Definition: SiteConfiguration.php:263
‪TYPO3\CMS\Core\Configuration\SiteConfiguration\$typoScriptConstantsFileName
‪string $typoScriptConstantsFileName
Definition: SiteConfiguration.php:67
‪$finder
‪if(PHP_SAPI !=='cli') $finder
Definition: header-comment.php:22
‪TYPO3\CMS\Core\Configuration\SiteConfiguration\getAllSiteConfigurationFromFiles
‪getAllSiteConfigurationFromFiles(bool $useCache=true)
Definition: SiteConfiguration.php:197
‪TYPO3\CMS\Core\Site\Entity\SiteTSconfig
Definition: SiteTSconfig.php:24
‪TYPO3\CMS\Core\Attribute\AsEventListener
Definition: AsEventListener.php:25
‪TYPO3\CMS\Core\Configuration\SiteConfiguration\getAllExistingSites
‪Site[] getAllExistingSites(bool $useCache=true)
Definition: SiteConfiguration.php:111
‪TYPO3\CMS\Core\Cache\Frontend\PhpFrontend
Definition: PhpFrontend.php:25
‪TYPO3\CMS\Core\Configuration\SiteConfiguration\warmupCaches
‪warmupCaches(CacheWarmupEvent $event)
Definition: SiteConfiguration.php:299
‪TYPO3\CMS\Core\Cache\Event\CacheWarmupEvent
Definition: CacheWarmupEvent.php:24
‪TYPO3\CMS\Core\Configuration\SiteConfiguration
Definition: SiteConfiguration.php:47
‪TYPO3\CMS\Core\Configuration\SiteConfiguration\load
‪load(string $siteIdentifier)
Definition: SiteConfiguration.php:234
‪TYPO3\CMS\Core\Site\Entity\Site
Definition: Site.php:42
‪TYPO3\CMS\Core\Configuration\SiteConfiguration\getAllSiteConfigurationPaths
‪getAllSiteConfigurationPaths()
Definition: SiteConfiguration.php:175
‪TYPO3\CMS\Core\Configuration\SiteConfiguration\getSiteTypoScript
‪getSiteTypoScript(string $siteIdentifier)
Definition: SiteConfiguration.php:241
‪TYPO3\CMS\Core\Configuration\SiteConfiguration\resolveAllExistingSites
‪Site[] resolveAllExistingSites(bool $useCache=true)
Definition: SiteConfiguration.php:124
‪TYPO3\CMS\Core\Configuration\SiteConfiguration\resolveAllExistingSitesRaw
‪Site[] resolveAllExistingSitesRaw()
Definition: SiteConfiguration.php:152
‪TYPO3\CMS\Core\Configuration\Event\SiteConfigurationChangedEvent
Definition: SiteConfigurationChangedEvent.php:24
‪TYPO3\CMS\Core\Configuration\SiteConfiguration\$firstLevelCache
‪array null $firstLevelCache
Definition: SiteConfiguration.php:95
‪TYPO3\CMS\Core\Cache\Exception\InvalidDataException
Definition: InvalidDataException.php:23
‪TYPO3\CMS\Core\Configuration\SiteConfiguration\$configFileName
‪string $configFileName
Definition: SiteConfiguration.php:53
‪TYPO3\CMS\Core\Configuration\Event\SiteConfigurationLoadedEvent
Definition: SiteConfigurationLoadedEvent.php:25
‪TYPO3\CMS\Core\Configuration\SiteConfiguration\$pageTSconfigFileName
‪string $pageTSconfigFileName
Definition: SiteConfiguration.php:74
‪TYPO3\CMS\Core\Configuration\SiteConfiguration\$cacheIdentifier
‪string $cacheIdentifier
Definition: SiteConfiguration.php:88
‪TYPO3\CMS\Core\Configuration\Loader\YamlFileLoader
Definition: YamlFileLoader.php:47
‪TYPO3\CMS\Core\Site\Entity\SiteTypoScript
Definition: SiteTypoScript.php:21
‪TYPO3\CMS\Core\Configuration\SiteConfiguration\getContentSecurityPolicies
‪getContentSecurityPolicies(string $siteIdentifier)
Definition: SiteConfiguration.php:282
‪TYPO3\CMS\Core\SingletonInterface
Definition: SingletonInterface.php:22
‪TYPO3\CMS\Core\Configuration
Definition: CKEditor5Migrator.php:18
‪TYPO3\CMS\Core\Configuration\SiteConfiguration\$contentSecurityFileName
‪string $contentSecurityFileName
Definition: SiteConfiguration.php:81
‪TYPO3\CMS\Webhooks\Message\$siteIdentifier
‪identifier readonly int readonly array readonly string readonly string $siteIdentifier
Definition: PageModificationMessage.php:38
‪TYPO3\CMS\Core\Configuration\SiteConfiguration\siteConfigurationChanged
‪siteConfigurationChanged()
Definition: SiteConfiguration.php:293
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Core\Site\Entity\SiteSettings
Definition: SiteSettings.php:29
‪TYPO3\CMS\Core\Configuration\SiteConfiguration\$typoScriptSetupFileName
‪string $typoScriptSetupFileName
Definition: SiteConfiguration.php:60
‪TYPO3\CMS\Webhooks\Message\$identifier
‪identifier readonly string $identifier
Definition: FileAddedMessage.php:37
‪TYPO3\CMS\Core\Cache\Event\CacheWarmupEvent\hasGroup
‪hasGroup(string $group)
Definition: CacheWarmupEvent.php:34
‪TYPO3\CMS\Core\Site\SiteSettingsFactory
Definition: SiteSettingsFactory.php:34