‪TYPO3CMS  10.4
ExtensionConfiguration.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 
22 use TYPO3\CMS\Core\Package\PackageManager;
26 
45 {
82  public function get(string $extension, string $path = '')
83  {
84  $hasBeenSynchronized = false;
85  if (!$this->‪hasConfiguration($extension)) {
86  // This if() should not be hit at "casual" runtime, but only in early setup phases
88  $hasBeenSynchronized = true;
89  if (!$this->‪hasConfiguration($extension)) {
90  // If there is still no such entry, even after sync -> throw
92  'No extension configuration for extension ' . $extension . ' found. Either this extension'
93  . ' has no extension configuration or the configuration is not up to date. Execute the'
94  . ' install tool to update configuration.',
95  1509654728
96  );
97  }
98  }
99  if (empty($path)) {
100  return ‪$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS'][$extension];
101  }
102  if (!‪ArrayUtility::isValidPath(‪$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS'], $extension . '/' . $path)) {
103  // This if() should not be hit at "casual" runtime, but only in early setup phases
104  if (!$hasBeenSynchronized) {
106  }
107  // If there is still no such entry, even after sync -> throw
108  if (!‪ArrayUtility::isValidPath(‪$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS'], $extension . '/' . $path)) {
110  'Path ' . $path . ' does not exist in extension configuration',
111  1509977699
112  );
113  }
114  }
115  return ‪ArrayUtility::getValueByPath(‪$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS'], $extension . '/' . $path);
116  }
117 
149  public function set(string $extension, string $path = '', $value = null): void
150  {
151  if (empty($extension)) {
152  throw new \RuntimeException('extension name must not be empty', 1509715852);
153  }
154  if (!empty($path)) {
155  // @todo: this functionality can be removed once EXT:bootstrap_package is adapted to the new API.
156  $extensionConfiguration = $this->get($extension);
157  $value = ‪ArrayUtility::setValueByPath($extensionConfiguration, $path, $value);
158  }
159  $configurationManager = GeneralUtility::makeInstance(ConfigurationManager::class);
160  if ($value === null) {
161  // Remove whole extension config
162  $configurationManager->removeLocalConfigurationKeysByPath(['EXTENSIONS/' . $extension]);
163  if (isset(‪$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS'][$extension])) {
164  unset(‪$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS'][$extension]);
165  }
166  } else {
167  // Set full extension config
168  $configurationManager->setLocalConfigurationValueByPath('EXTENSIONS/' . $extension, $value);
169  ‪$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS'][$extension] = $value;
170  }
171  }
172 
181  public function ‪setAll(array $configuration): void
182  {
183  $configurationManager = GeneralUtility::makeInstance(ConfigurationManager::class);
184  $configurationManager->setLocalConfigurationValueByPath('EXTENSIONS', $configuration);
185  ‪$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS'] = $configuration;
186  }
187 
198  {
199  $activePackages = GeneralUtility::makeInstance(PackageManager::class)->getActivePackages();
200  $fullConfiguration = [];
201  $currentLocalConfiguration = ‪$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS'] ?? [];
202  foreach ($activePackages as $package) {
203  if (!@is_file($package->getPackagePath() . 'ext_conf_template.txt')) {
204  continue;
205  }
206  $extensionKey = $package->getPackageKey();
207  $currentExtensionConfig = $currentLocalConfiguration[$extensionKey] ?? [];
208  $extConfTemplateConfiguration = $this->‪getExtConfTablesWithoutCommentsAsNestedArrayWithoutDots($extensionKey);
209  ‪ArrayUtility::mergeRecursiveWithOverrule($extConfTemplateConfiguration, $currentExtensionConfig);
210  if (!empty($extConfTemplateConfiguration)) {
211  $fullConfiguration[$extensionKey] = $extConfTemplateConfiguration;
212  }
213  }
214  // Write new config if changed. Loose array comparison to not write if only array key order is different
215  if ($fullConfiguration != $currentLocalConfiguration) {
216  $this->‪setAll($fullConfiguration);
217  }
218  }
219 
229  public function ‪synchronizeExtConfTemplateWithLocalConfiguration(string $extensionKey): void
230  {
231  $package = GeneralUtility::makeInstance(PackageManager::class)->getPackage($extensionKey);
232  if (!@is_file($package->getPackagePath() . 'ext_conf_template.txt')) {
233  return;
234  }
235  $currentLocalConfiguration = ‪$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS'][$extensionKey] ?? [];
236  $extConfTemplateConfiguration = $this->‪getExtConfTablesWithoutCommentsAsNestedArrayWithoutDots($extensionKey);
237  ‪ArrayUtility::mergeRecursiveWithOverrule($extConfTemplateConfiguration, $currentLocalConfiguration);
238  // Write new config if changed. Loose array comparison to not write if only array key order is different
239  if ($extConfTemplateConfiguration != $currentLocalConfiguration) {
240  $this->set($extensionKey, '', $extConfTemplateConfiguration);
241  }
242  }
243 
253  protected function ‪getExtConfTablesWithoutCommentsAsNestedArrayWithoutDots(string $extensionKey): array
254  {
255  $rawConfigurationString = $this->‪getDefaultConfigurationRawString($extensionKey);
256  $typoScriptParser = GeneralUtility::makeInstance(TypoScriptParser::class);
257  // we are parsing constants, so we need the instructions from comments
258  $typoScriptParser->regComments = true;
259  $typoScriptParser->parse($rawConfigurationString);
260  // setup contains the parsed constants string
261  $parsedTemplate = $typoScriptParser->setup;
262  return $this->‪removeCommentsAndDotsRecursive($parsedTemplate);
263  }
264 
274  public function ‪getDefaultConfigurationRawString(string $extensionKey): string
275  {
276  $rawString = '';
277  $extConfTemplateFileLocation = GeneralUtility::getFileAbsFileName(
278  'EXT:' . $extensionKey . '/ext_conf_template.txt'
279  );
280  if (file_exists($extConfTemplateFileLocation)) {
281  $rawString = (string)file_get_contents($extConfTemplateFileLocation);
282  }
283  return $rawString;
284  }
285 
290  protected function ‪hasConfiguration(string $extension): bool
291  {
292  return isset(‪$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS'][$extension]) && is_array(‪$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS'][$extension]);
293  }
294 
320  protected function ‪removeCommentsAndDotsRecursive(array $config): array
321  {
322  $cleanedConfig = [];
323  foreach ($config as $key => $value) {
324  if (substr($key, -2) === '..') {
325  continue;
326  }
327  if (substr($key, -1) === '.') {
328  $cleanedConfig[rtrim($key, '.')] = $this->‪removeCommentsAndDotsRecursive($value);
329  } else {
330  $cleanedConfig[$key] = $value;
331  }
332  }
333  return $cleanedConfig;
334  }
335 }
‪TYPO3\CMS\Core\Configuration\Exception\ExtensionConfigurationPathDoesNotExistException
Definition: ExtensionConfigurationPathDoesNotExistException.php:27
‪TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser
Definition: TypoScriptParser.php:37
‪TYPO3\CMS\Core\Configuration\ExtensionConfiguration
Definition: ExtensionConfiguration.php:45
‪TYPO3\CMS\Core\Utility\ArrayUtility\isValidPath
‪static bool isValidPath(array $array, $path, $delimiter='/')
Definition: ArrayUtility.php:144
‪TYPO3\CMS\Core\Utility\ArrayUtility\mergeRecursiveWithOverrule
‪static mergeRecursiveWithOverrule(array &$original, array $overrule, $addKeys=true, $includeEmptyValues=true, $enableUnsetFeature=true)
Definition: ArrayUtility.php:654
‪TYPO3\CMS\Core\Utility\ArrayUtility\getValueByPath
‪static mixed getValueByPath(array $array, $path, $delimiter='/')
Definition: ArrayUtility.php:180
‪TYPO3\CMS\Core\Configuration\ExtensionConfiguration\getExtConfTablesWithoutCommentsAsNestedArrayWithoutDots
‪array getExtConfTablesWithoutCommentsAsNestedArrayWithoutDots(string $extensionKey)
Definition: ExtensionConfiguration.php:253
‪TYPO3\CMS\Core\Configuration\ExtensionConfiguration\removeCommentsAndDotsRecursive
‪array removeCommentsAndDotsRecursive(array $config)
Definition: ExtensionConfiguration.php:320
‪TYPO3\CMS\Core\Configuration\ExtensionConfiguration\setAll
‪setAll(array $configuration)
Definition: ExtensionConfiguration.php:181
‪TYPO3\CMS\Core\Configuration\ExtensionConfiguration\synchronizeExtConfTemplateWithLocalConfiguration
‪synchronizeExtConfTemplateWithLocalConfiguration(string $extensionKey)
Definition: ExtensionConfiguration.php:229
‪TYPO3\CMS\Core\Configuration\ExtensionConfiguration\hasConfiguration
‪bool hasConfiguration(string $extension)
Definition: ExtensionConfiguration.php:290
‪TYPO3\CMS\Core\Utility\ArrayUtility\setValueByPath
‪static array setValueByPath(array $array, $path, $value, $delimiter='/')
Definition: ArrayUtility.php:272
‪TYPO3\CMS\Core\Utility\ArrayUtility
Definition: ArrayUtility.php:24
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Configuration
Definition: ConfigurationManager.php:16
‪TYPO3\CMS\Core\Configuration\Exception\ExtensionConfigurationExtensionNotConfiguredException
Definition: ExtensionConfigurationExtensionNotConfiguredException.php:27
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46
‪TYPO3\CMS\Core\Configuration\ExtensionConfiguration\getDefaultConfigurationRawString
‪string getDefaultConfigurationRawString(string $extensionKey)
Definition: ExtensionConfiguration.php:274
‪TYPO3\CMS\Core\Configuration\ExtensionConfiguration\synchronizeExtConfTemplateWithLocalConfigurationOfAllExtensions
‪synchronizeExtConfTemplateWithLocalConfigurationOfAllExtensions()
Definition: ExtensionConfiguration.php:197