Revert "[FEATURE] EXT:form - introduce YAML "imports""
[Packages/TYPO3.CMS.git] / typo3 / sysext / form / Classes / Mvc / Configuration / ConfigurationManager.php
1 <?php
2 declare(strict_types = 1);
3 namespace TYPO3\CMS\Form\Mvc\Configuration;
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
18 use TYPO3\CMS\Core\Cache\CacheManager;
19 use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
20 use TYPO3\CMS\Core\Utility\ArrayUtility;
21 use TYPO3\CMS\Core\Utility\GeneralUtility;
22 use TYPO3\CMS\Extbase\Configuration\ConfigurationManager as ExtbaseConfigurationManager;
23 use TYPO3\CMS\Form\Mvc\Configuration\Exception\ExtensionNameRequiredException;
24
25 /**
26 * Extend the ExtbaseConfigurationManager to read YAML configurations.
27 *
28 * Scope: frontend / backend
29 * @internal
30 */
31 class ConfigurationManager extends ExtbaseConfigurationManager implements ConfigurationManagerInterface
32 {
33
34 /**
35 * @var \TYPO3\CMS\Core\Cache\Frontend\FrontendInterface
36 */
37 protected $cache;
38
39 /**
40 * @var \TYPO3\CMS\Form\Mvc\Configuration\YamlSource
41 */
42 protected $yamlSource;
43
44 /**
45 * @param \TYPO3\CMS\Form\Mvc\Configuration\YamlSource $yamlSource
46 * @internal
47 */
48 public function injectYamlSource(\TYPO3\CMS\Form\Mvc\Configuration\YamlSource $yamlSource)
49 {
50 $this->yamlSource = $yamlSource;
51 }
52
53 /**
54 * @param string $configurationType The kind of configuration to fetch - must be one of the CONFIGURATION_TYPE_* constants
55 * @param string $extensionName if specified, the configuration for the given extension will be returned.
56 * @param string $pluginName if specified, the configuration for the given plugin will be returned.
57 * @return array The configuration
58 * @internal
59 */
60 public function getConfiguration($configurationType, $extensionName = null, $pluginName = null)
61 {
62 switch ($configurationType) {
63 case self::CONFIGURATION_TYPE_YAML_SETTINGS:
64 return $this->getConfigurationFromYamlFile($extensionName);
65 default:
66 return parent::getConfiguration($configurationType, $extensionName, $pluginName);
67 }
68 }
69
70 /**
71 * Load and parse YAML files which are configured within the TypoScript
72 * path plugin.tx_extensionkey.settings.yamlConfigurations
73 *
74 * The following steps will be done:
75 *
76 * * Convert each singe YAML file into an array
77 * * merge this arrays together
78 * * resolve all declared inheritances
79 * * remove all keys if their values are NULL
80 * * return all configuration paths within TYPO3.CMS
81 * * sort by array keys, if all keys within the current nesting level are numerical keys
82 * * resolve possible TypoScript settings in FE mode
83 *
84 * @param string $extensionName
85 * @return array
86 * @throws ExtensionNameRequiredException
87 */
88 protected function getConfigurationFromYamlFile(string $extensionName): array
89 {
90 if (empty($extensionName)) {
91 throw new ExtensionNameRequiredException(
92 'Please specify an extension key to load a YAML configuration',
93 1471473377
94 );
95 }
96 $ucFirstExtensioName = ucfirst($extensionName);
97
98 $typoscriptSettings = $this->getTypoScriptSettings($extensionName);
99
100 $yamlSettingsFilePaths = isset($typoscriptSettings['yamlConfigurations'])
101 ? ArrayUtility::sortArrayWithIntegerKeys($typoscriptSettings['yamlConfigurations'])
102 : [];
103
104 $cacheKeySuffix = $extensionName . md5(json_encode($yamlSettingsFilePaths));
105
106 $yamlSettings = $this->getYamlSettingsFromCache($cacheKeySuffix);
107 if (!empty($yamlSettings)) {
108 return $this->overrideConfigurationByTypoScript($yamlSettings, $extensionName);
109 }
110
111 $yamlSettings = InheritancesResolverService::create($this->yamlSource->load($yamlSettingsFilePaths))
112 ->getResolvedConfiguration();
113
114 $yamlSettings = ArrayUtility::removeNullValuesRecursive($yamlSettings);
115 $yamlSettings = is_array($yamlSettings['TYPO3']['CMS'][$ucFirstExtensioName])
116 ? $yamlSettings['TYPO3']['CMS'][$ucFirstExtensioName]
117 : [];
118 $yamlSettings = ArrayUtility::sortArrayWithIntegerKeysRecursive($yamlSettings);
119 $this->setYamlSettingsIntoCache($cacheKeySuffix, $yamlSettings);
120
121 return $this->overrideConfigurationByTypoScript($yamlSettings, $extensionName);
122 }
123
124 /**
125 * @param array $yamlSettings
126 * @param string $extensionName
127 * @return array
128 */
129 protected function overrideConfigurationByTypoScript(array $yamlSettings, string $extensionName): array
130 {
131 $typoScript = parent::getConfiguration(self::CONFIGURATION_TYPE_SETTINGS, $extensionName);
132 if (is_array($typoScript['yamlSettingsOverrides']) && !empty($typoScript['yamlSettingsOverrides'])) {
133 ArrayUtility::mergeRecursiveWithOverrule(
134 $yamlSettings,
135 $typoScript['yamlSettingsOverrides']
136 );
137
138 if ($this->environmentService->isEnvironmentInFrontendMode()) {
139 $yamlSettings = $this->objectManager->get(TypoScriptService::class)
140 ->resolvePossibleTypoScriptConfiguration($yamlSettings);
141 }
142 }
143 return $yamlSettings;
144 }
145
146 /**
147 * @return \TYPO3\CMS\Core\Cache\Frontend\FrontendInterface
148 */
149 protected function getCacheFrontend(): FrontendInterface
150 {
151 if ($this->cache === null) {
152 $this->cache = GeneralUtility::makeInstance(CacheManager::class)->getCache('assets');
153 }
154 return $this->cache;
155 }
156
157 /**
158 * @param string $cacheKeySuffix
159 * @return string
160 */
161 protected function getConfigurationCacheKey(string $cacheKeySuffix): string
162 {
163 return strtolower(self::CONFIGURATION_TYPE_YAML_SETTINGS . '_' . $cacheKeySuffix);
164 }
165
166 /**
167 * @param string $cacheKeySuffix
168 * @return mixed
169 */
170 protected function getYamlSettingsFromCache(string $cacheKeySuffix)
171 {
172 return $this->getCacheFrontend()->get(
173 $this->getConfigurationCacheKey($cacheKeySuffix)
174 );
175 }
176
177 /**
178 * @param string $cacheKeySuffix
179 * @param array $yamlSettings
180 */
181 protected function setYamlSettingsIntoCache(
182 string $cacheKeySuffix,
183 array $yamlSettings
184 ) {
185 $this->getCacheFrontend()->set(
186 $this->getConfigurationCacheKey($cacheKeySuffix),
187 $yamlSettings
188 );
189 }
190
191 /**
192 * @param string $extensionName
193 * @return null|[]
194 */
195 protected function getTypoScriptSettings(string $extensionName)
196 {
197 return parent::getConfiguration(
198 ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS,
199 $extensionName
200 );
201 }
202 }