‪TYPO3CMS  ‪main
FrontendConfigurationManager.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\Http\Message\ServerRequestInterface;
30 
38 {
44  protected ‪$configuration = [];
45 
51  protected ‪$extensionName;
52 
58  protected ‪$pluginName;
59 
65  protected ‪$configurationCache = [];
66 
70  private ?ServerRequestInterface ‪$request = null;
71 
72  public function ‪__construct(
73  protected ‪TypoScriptService $typoScriptService,
74  protected ‪FlexFormService $flexFormService,
75  protected ‪PageRepository $pageRepository,
76  protected ‪EventDispatcher $eventDispatcher
77  ) {}
78 
79  public function ‪setRequest(ServerRequestInterface ‪$request): void
80  {
81  $this->request = ‪$request;
82  }
83 
90  public function ‪setConfiguration(array ‪$configuration = []): void
91  {
92  // reset 1st level cache
93  $this->configurationCache = [];
94  $this->extensionName = ‪$configuration['extensionName'] ?? null;
95  $this->pluginName = ‪$configuration['pluginName'] ?? null;
96  $this->configuration = $this->typoScriptService->convertTypoScriptArrayToPlainArray(‪$configuration);
97  }
98 
109  public function ‪getConfiguration(?string ‪$extensionName = null, ?string ‪$pluginName = null): array
110  {
111  // 1st level cache
112  $configurationCacheKey = strtolower((‪$extensionName ?: $this->extensionName) . '_' . (‪$pluginName ?: $this->pluginName));
113  if (isset($this->configurationCache[$configurationCacheKey])) {
114  return $this->configurationCache[$configurationCacheKey];
115  }
116  $frameworkConfiguration = $this->‪getExtbaseConfiguration();
117  if (!isset($frameworkConfiguration['persistence']['storagePid'])) {
118  $frameworkConfiguration['persistence']['storagePid'] = 0;
119  }
120  // only merge $this->configuration and override controller configuration when retrieving configuration of the current plugin
121  if (‪$extensionName === null || ‪$extensionName === $this->extensionName && ‪$pluginName === $this->pluginName) {
122  $pluginConfiguration = $this->‪getPluginConfiguration((string)$this->extensionName, (string)$this->pluginName);
123  ArrayUtility::mergeRecursiveWithOverrule($pluginConfiguration, $this->configuration);
124  $pluginConfiguration['controllerConfiguration'] = $this->‪getControllerConfiguration((string)$this->extensionName, (string)$this->pluginName);
125  } else {
126  $pluginConfiguration = $this->‪getPluginConfiguration((string)‪$extensionName, (string)‪$pluginName);
127  $pluginConfiguration['controllerConfiguration'] = $this->‪getControllerConfiguration((string)$extensionName, (string)‪$pluginName);
128  }
129  ArrayUtility::mergeRecursiveWithOverrule($frameworkConfiguration, $pluginConfiguration);
130  // only load context specific configuration when retrieving configuration of the current plugin
131  if (‪$extensionName === null || ‪$extensionName === $this->extensionName && ‪$pluginName === $this->pluginName) {
132  $frameworkConfiguration = $this->‪getContextSpecificFrameworkConfiguration($frameworkConfiguration);
133  }
134 
135  if (!empty($frameworkConfiguration['persistence']['storagePid'])) {
136  if (is_array($frameworkConfiguration['persistence']['storagePid'])) {
137  $conf = $this->typoScriptService->convertPlainArrayToTypoScriptArray($frameworkConfiguration['persistence']);
138  $frameworkConfiguration['persistence']['storagePid'] = ‪$GLOBALS['TSFE']->cObj->stdWrapValue('storagePid', $conf);
139  }
140  if (!empty($frameworkConfiguration['persistence']['recursive'])) {
141  $storagePids = $this->‪getRecursiveStoragePids(
142  ‪GeneralUtility::intExplode(',', (string)($frameworkConfiguration['persistence']['storagePid'] ?? '')),
143  (int)$frameworkConfiguration['persistence']['recursive']
144  );
145  $frameworkConfiguration['persistence']['storagePid'] = implode(',', $storagePids);
146  }
147  }
148  // 1st level cache
149  $this->configurationCache[$configurationCacheKey] = $frameworkConfiguration;
150  return $frameworkConfiguration;
151  }
152 
156  protected function ‪getExtbaseConfiguration(): array
157  {
158  $setup = $this->‪getTypoScriptSetup();
159  $extbaseConfiguration = [];
160  if (isset($setup['config.']['tx_extbase.'])) {
161  $extbaseConfiguration = $this->typoScriptService->convertTypoScriptArrayToPlainArray($setup['config.']['tx_extbase.']);
162  }
163  return $extbaseConfiguration;
164  }
165 
169  public function ‪getTypoScriptSetup(): array
170  {
171  // @todo: Avoid $GLOBALS['TYPO3_REQUEST'] in v13.
173  ‪$request = $this->request ?? ‪$GLOBALS['TYPO3_REQUEST'];
174  $frontendTypoScript = ‪$request->getAttribute('frontend.typoscript');
175  if (!($frontendTypoScript instanceof ‪FrontendTypoScript)) {
176  throw new \RuntimeException(
177  'Setup array has not been initialized. This happens in cached Frontend scope where full TypoScript' .
178  ' is not needed by the system.',
179  1700841298
180  );
181  }
182  return $frontendTypoScript->getSetupArray();
183  }
184 
191  protected function ‪getPluginConfiguration(string ‪$extensionName, string ‪$pluginName = null): array
192  {
193  $setup = $this->‪getTypoScriptSetup();
194  $pluginConfiguration = [];
195  if (isset($setup['plugin.']['tx_' . strtolower(‪$extensionName) . '.']) && is_array($setup['plugin.']['tx_' . strtolower(‪$extensionName) . '.'])) {
196  $pluginConfiguration = $this->typoScriptService->convertTypoScriptArrayToPlainArray($setup['plugin.']['tx_' . strtolower(‪$extensionName) . '.']);
197  }
198  if (‪$pluginName !== null) {
199  $pluginSignature = strtolower(‪$extensionName . '_' . ‪$pluginName);
200  if (isset($setup['plugin.']['tx_' . $pluginSignature . '.']) && is_array($setup['plugin.']['tx_' . $pluginSignature . '.'])) {
201  ArrayUtility::mergeRecursiveWithOverrule(
202  $pluginConfiguration,
203  $this->typoScriptService->convertTypoScriptArrayToPlainArray($setup['plugin.']['tx_' . $pluginSignature . '.'])
204  );
205  }
206  }
207  return $pluginConfiguration;
208  }
209 
219  protected function ‪getControllerConfiguration(string ‪$extensionName, string ‪$pluginName): array
220  {
221  $controllerConfiguration = ‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions'][‪$extensionName]['plugins'][‪$pluginName]['controllers'] ?? [];
222  if (!is_array($controllerConfiguration)) {
223  $controllerConfiguration = [];
224  }
225  return $controllerConfiguration;
226  }
227 
236  protected function ‪getContextSpecificFrameworkConfiguration(array $frameworkConfiguration): array
237  {
238  $frameworkConfiguration = $this->‪overrideStoragePidIfStartingPointIsSet($frameworkConfiguration);
239  $frameworkConfiguration = $this->‪overrideConfigurationFromPlugin($frameworkConfiguration);
240  $frameworkConfiguration = $this->‪overrideConfigurationFromFlexForm($frameworkConfiguration);
241  return $frameworkConfiguration;
242  }
243 
251  protected function ‪overrideStoragePidIfStartingPointIsSet(array $frameworkConfiguration): array
252  {
253  $contentObject = $this->request?->getAttribute('currentContentObject');
254  $pages = (string)($contentObject?->data['pages'] ?? '');
255  if ($pages !== '') {
256  $storagePids = ‪GeneralUtility::intExplode(',', $pages, true);
257  $recursionDepth = (int)($contentObject?->data['recursive'] ?? 0);
258  $recursiveStoragePids = $this->pageRepository->getPageIdsRecursive($storagePids, $recursionDepth);
259  $pages = implode(',', $recursiveStoragePids);
260  ArrayUtility::mergeRecursiveWithOverrule($frameworkConfiguration, [
261  'persistence' => [
262  'storagePid' => $pages,
263  ],
264  ]);
265  }
266  return $frameworkConfiguration;
267  }
268 
275  protected function ‪overrideConfigurationFromPlugin(array $frameworkConfiguration): array
276  {
277  if (!isset($frameworkConfiguration['extensionName']) || !isset($frameworkConfiguration['pluginName'])) {
278  return $frameworkConfiguration;
279  }
280 
281  $setup = $this->‪getTypoScriptSetup();
282  $pluginSignature = strtolower($frameworkConfiguration['extensionName'] . '_' . $frameworkConfiguration['pluginName']);
283  $pluginConfiguration = $setup['plugin.']['tx_' . $pluginSignature . '.'] ?? null;
284  if (is_array($pluginConfiguration)) {
285  $pluginConfiguration = $this->typoScriptService->convertTypoScriptArrayToPlainArray($pluginConfiguration);
286  $frameworkConfiguration = $this->‪mergeConfigurationIntoFrameworkConfiguration($frameworkConfiguration, $pluginConfiguration, 'settings');
287  $frameworkConfiguration = $this->‪mergeConfigurationIntoFrameworkConfiguration($frameworkConfiguration, $pluginConfiguration, 'persistence');
288  $frameworkConfiguration = $this->‪mergeConfigurationIntoFrameworkConfiguration($frameworkConfiguration, $pluginConfiguration, 'view');
289  }
290  return $frameworkConfiguration;
291  }
292 
299  protected function ‪overrideConfigurationFromFlexForm(array $frameworkConfiguration): array
300  {
301  $contentObject = $this->request?->getAttribute('currentContentObject');
302  $flexFormConfiguration = $contentObject?->data['pi_flexform'] ?? [];
303  if (is_string($flexFormConfiguration)) {
304  if ($flexFormConfiguration !== '') {
305  $flexFormConfiguration = $this->flexFormService->convertFlexFormContentToArray($flexFormConfiguration);
306  } else {
307  $flexFormConfiguration = [];
308  }
309  }
310 
311  // Early return, if flexForm configuration is empty
312  if (!is_array($flexFormConfiguration) || empty($flexFormConfiguration)) {
313  return $frameworkConfiguration;
314  }
315 
316  // Remove flexForm settings if empty for fields defined in `ignoreFlexFormSettingsIfEmpty`
317  $originalFlexFormConfiguration = $flexFormConfiguration;
318  $ignoredSettingsConfig = (string)($frameworkConfiguration['ignoreFlexFormSettingsIfEmpty'] ?? '');
319  if ($ignoredSettingsConfig !== '') {
320  $ignoredSettings = ‪GeneralUtility::trimExplode(',', $ignoredSettingsConfig, true);
321  $flexFormConfiguration = $this->‪removeIgnoredFlexFormSettingsIfEmpty($flexFormConfiguration, $ignoredSettings);
322  }
323 
324  // PSR-14 event for extension authors to modify flexForm configuration before the merge process
325  $event = new BeforeFlexFormConfigurationOverrideEvent($frameworkConfiguration, $originalFlexFormConfiguration, $flexFormConfiguration);
326  $this->eventDispatcher->dispatch($event);
327  $flexFormConfiguration = $event->getFlexFormConfiguration();
328 
329  $frameworkConfiguration = $this->‪mergeConfigurationIntoFrameworkConfiguration($frameworkConfiguration, $flexFormConfiguration, 'settings');
330  $frameworkConfiguration = $this->‪mergeConfigurationIntoFrameworkConfiguration($frameworkConfiguration, $flexFormConfiguration, 'persistence');
331  $frameworkConfiguration = $this->‪mergeConfigurationIntoFrameworkConfiguration($frameworkConfiguration, $flexFormConfiguration, 'view');
332 
333  return $frameworkConfiguration;
334  }
335 
344  protected function ‪mergeConfigurationIntoFrameworkConfiguration(array $frameworkConfiguration, array ‪$configuration, string $configurationPartName): array
345  {
346  if (isset(‪$configuration[$configurationPartName]) && is_array(‪$configuration[$configurationPartName])) {
347  if (isset($frameworkConfiguration[$configurationPartName]) && is_array($frameworkConfiguration[$configurationPartName])) {
348  ArrayUtility::mergeRecursiveWithOverrule($frameworkConfiguration[$configurationPartName], ‪$configuration[$configurationPartName]);
349  } else {
350  $frameworkConfiguration[$configurationPartName] = ‪$configuration[$configurationPartName];
351  }
352  }
353  return $frameworkConfiguration;
354  }
355 
363  protected function ‪getRecursiveStoragePids(array $storagePids, int $recursionDepth = 0): array
364  {
365  return $this->pageRepository->getPageIdsRecursive($storagePids, $recursionDepth);
366  }
367 
368  protected function ‪removeIgnoredFlexFormSettingsIfEmpty(array $flexFormConfiguration, array $ignoredSettings): array
369  {
370  foreach ($ignoredSettings as $ignoredSetting) {
371  $ignoredSettingName = 'settings.' . $ignoredSetting;
372  if (!‪ArrayUtility::isValidPath($flexFormConfiguration, $ignoredSettingName, '.')) {
373  continue;
374  }
375 
376  $fieldValue = ‪ArrayUtility::getValueByPath($flexFormConfiguration, $ignoredSettingName, '.');
377  if ($fieldValue === '' || $fieldValue === '0') {
378  $flexFormConfiguration = ‪ArrayUtility::removeByPath($flexFormConfiguration, $ignoredSettingName, '.');
379  }
380  }
381 
382  return $flexFormConfiguration;
383  }
384 }
‪TYPO3\CMS\Core\Utility\ArrayUtility\removeByPath
‪static array removeByPath(array $array, string $path, string $delimiter='/')
Definition: ArrayUtility.php:303
‪TYPO3\CMS\Extbase\Configuration\FrontendConfigurationManager\getTypoScriptSetup
‪getTypoScriptSetup()
Definition: FrontendConfigurationManager.php:165
‪TYPO3\CMS\Extbase\Configuration\FrontendConfigurationManager\__construct
‪__construct(protected TypoScriptService $typoScriptService, protected FlexFormService $flexFormService, protected PageRepository $pageRepository, protected EventDispatcher $eventDispatcher)
Definition: FrontendConfigurationManager.php:68
‪TYPO3\CMS\Extbase\Configuration\FrontendConfigurationManager\$pluginName
‪string $pluginName
Definition: FrontendConfigurationManager.php:55
‪TYPO3\CMS\Core\Utility\ArrayUtility\isValidPath
‪static bool isValidPath(array $array, array|string $path, string $delimiter='/')
Definition: ArrayUtility.php:141
‪TYPO3\CMS\Extbase\Configuration\FrontendConfigurationManager\$request
‪ServerRequestInterface $request
Definition: FrontendConfigurationManager.php:66
‪TYPO3\CMS\Extbase\Configuration\FrontendConfigurationManager\getControllerConfiguration
‪getControllerConfiguration(string $extensionName, string $pluginName)
Definition: FrontendConfigurationManager.php:215
‪TYPO3\CMS\Extbase\Configuration\FrontendConfigurationManager\$extensionName
‪string $extensionName
Definition: FrontendConfigurationManager.php:49
‪TYPO3\CMS\Extbase\Configuration\FrontendConfigurationManager\getRecursiveStoragePids
‪int[] getRecursiveStoragePids(array $storagePids, int $recursionDepth=0)
Definition: FrontendConfigurationManager.php:359
‪TYPO3\CMS\Core\Service\FlexFormService
Definition: FlexFormService.php:25
‪TYPO3\CMS\Core\Utility\ArrayUtility\getValueByPath
‪static getValueByPath(array $array, array|string $path, string $delimiter='/')
Definition: ArrayUtility.php:176
‪TYPO3\CMS\Extbase\Configuration\FrontendConfigurationManager
Definition: FrontendConfigurationManager.php:38
‪TYPO3\CMS\Core\EventDispatcher\EventDispatcher
Definition: EventDispatcher.php:30
‪TYPO3\CMS\Extbase\Configuration\FrontendConfigurationManager\getContextSpecificFrameworkConfiguration
‪array getContextSpecificFrameworkConfiguration(array $frameworkConfiguration)
Definition: FrontendConfigurationManager.php:232
‪TYPO3\CMS\Extbase\Configuration\FrontendConfigurationManager\getPluginConfiguration
‪getPluginConfiguration(string $extensionName, string $pluginName=null)
Definition: FrontendConfigurationManager.php:187
‪TYPO3\CMS\Extbase\Event\Configuration\BeforeFlexFormConfigurationOverrideEvent
Definition: BeforeFlexFormConfigurationOverrideEvent.php:28
‪TYPO3\CMS\Extbase\Configuration\FrontendConfigurationManager\overrideConfigurationFromPlugin
‪array overrideConfigurationFromPlugin(array $frameworkConfiguration)
Definition: FrontendConfigurationManager.php:271
‪TYPO3\CMS\Extbase\Configuration\FrontendConfigurationManager\removeIgnoredFlexFormSettingsIfEmpty
‪removeIgnoredFlexFormSettingsIfEmpty(array $flexFormConfiguration, array $ignoredSettings)
Definition: FrontendConfigurationManager.php:364
‪TYPO3\CMS\Extbase\Configuration\FrontendConfigurationManager\getConfiguration
‪array getConfiguration(?string $extensionName=null, ?string $pluginName=null)
Definition: FrontendConfigurationManager.php:105
‪TYPO3\CMS\Extbase\Configuration\FrontendConfigurationManager\mergeConfigurationIntoFrameworkConfiguration
‪array mergeConfigurationIntoFrameworkConfiguration(array $frameworkConfiguration, array $configuration, string $configurationPartName)
Definition: FrontendConfigurationManager.php:340
‪TYPO3\CMS\Extbase\Configuration\FrontendConfigurationManager\$configurationCache
‪array $configurationCache
Definition: FrontendConfigurationManager.php:61
‪TYPO3\CMS\Core\TypoScript\TypoScriptService
Definition: TypoScriptService.php:27
‪TYPO3\CMS\Extbase\Configuration\FrontendConfigurationManager\overrideConfigurationFromFlexForm
‪array overrideConfigurationFromFlexForm(array $frameworkConfiguration)
Definition: FrontendConfigurationManager.php:295
‪TYPO3\CMS\Extbase\Configuration\FrontendConfigurationManager\setRequest
‪setRequest(ServerRequestInterface $request)
Definition: FrontendConfigurationManager.php:75
‪TYPO3\CMS\Core\Utility\ArrayUtility
Definition: ArrayUtility.php:26
‪TYPO3\CMS\Extbase\Configuration\FrontendConfigurationManager\overrideStoragePidIfStartingPointIsSet
‪array overrideStoragePidIfStartingPointIsSet(array $frameworkConfiguration)
Definition: FrontendConfigurationManager.php:247
‪TYPO3\CMS\Core\SingletonInterface
Definition: SingletonInterface.php:22
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Domain\Repository\PageRepository
Definition: PageRepository.php:69
‪TYPO3\CMS\Core\TypoScript\FrontendTypoScript
Definition: FrontendTypoScript.php:30
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Extbase\Configuration
Definition: BackendConfigurationManager.php:18
‪TYPO3\CMS\Extbase\Configuration\FrontendConfigurationManager\$configuration
‪array $configuration
Definition: FrontendConfigurationManager.php:43
‪TYPO3\CMS\Core\Utility\GeneralUtility\intExplode
‪static list< int > intExplode(string $delimiter, string $string, bool $removeEmptyValues=false)
Definition: GeneralUtility.php:756
‪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\Extbase\Configuration\FrontendConfigurationManager\getExtbaseConfiguration
‪getExtbaseConfiguration()
Definition: FrontendConfigurationManager.php:152
‪TYPO3\CMS\Extbase\Configuration\FrontendConfigurationManager\setConfiguration
‪setConfiguration(array $configuration=[])
Definition: FrontendConfigurationManager.php:86