[CLEANUP] The correct case must be used for standard PHP types in phpdoc
[Packages/TYPO3.CMS.git] / typo3 / sysext / extensionmanager / Classes / Domain / Repository / ConfigurationItemRepository.php
1 <?php
2 namespace TYPO3\CMS\Extensionmanager\Domain\Repository;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Core\Utility\ArrayUtility;
18 use TYPO3\CMS\Core\Utility\GeneralUtility;
19
20 /**
21 * A repository for extension configuration items
22 */
23 class ConfigurationItemRepository
24 {
25 /**
26 * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
27 */
28 protected $objectManager;
29
30 /**
31 * @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
32 */
33 public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager)
34 {
35 $this->objectManager = $objectManager;
36 }
37
38 /**
39 * Find configuration options by extension
40 *
41 * @param string $extensionKey Extension key
42 * @return \SplObjectStorage
43 */
44 public function findByExtensionKey($extensionKey)
45 {
46 $configurationArray = $this->getConfigurationArrayFromExtensionKey($extensionKey);
47 return $this->convertHierarchicArrayToObject($configurationArray);
48 }
49
50 /**
51 * Converts the raw configuration file content to an configuration object storage
52 *
53 * @param string $extensionKey Extension key
54 * @return array
55 */
56 protected function getConfigurationArrayFromExtensionKey($extensionKey)
57 {
58 /** @var $configurationUtility \TYPO3\CMS\Extensionmanager\Utility\ConfigurationUtility */
59 $configurationUtility = $this->objectManager->get(\TYPO3\CMS\Extensionmanager\Utility\ConfigurationUtility::class);
60 $defaultConfiguration = $configurationUtility->getDefaultConfigurationFromExtConfTemplateAsValuedArray($extensionKey);
61
62 $resultArray = [];
63 if (!empty($defaultConfiguration)) {
64 $metaInformation = $this->addMetaInformation($defaultConfiguration);
65 $configuration = $this->mergeWithExistingConfiguration($defaultConfiguration, $extensionKey);
66 $hierarchicConfiguration = [];
67 foreach ($configuration as $configurationOption) {
68 $originalConfiguration = $this->buildConfigurationArray($configurationOption, $extensionKey);
69 ArrayUtility::mergeRecursiveWithOverrule($originalConfiguration, $hierarchicConfiguration);
70 $hierarchicConfiguration = $originalConfiguration;
71 }
72
73 // Flip category array as it was merged the other way around
74 $hierarchicConfiguration = array_reverse($hierarchicConfiguration);
75
76 // Sort configurations of each subcategory
77 foreach ($hierarchicConfiguration as &$catConfigurationArray) {
78 foreach ($catConfigurationArray as &$subcatConfigurationArray) {
79 uasort($subcatConfigurationArray, function ($a, $b) {
80 return strnatcmp($a['subcat'], $b['subcat']);
81 });
82 }
83 unset($subcatConfigurationArray);
84 }
85 unset($tempConfiguration);
86
87 ArrayUtility::mergeRecursiveWithOverrule($hierarchicConfiguration, $metaInformation);
88 $resultArray = $hierarchicConfiguration;
89 }
90
91 return $resultArray;
92 }
93
94 /**
95 * Builds a configuration array from each line (option) of the config file
96 *
97 * @param string $configurationOption config file line representing one setting
98 * @param string $extensionKey Extension key
99 * @return array
100 */
101 protected function buildConfigurationArray($configurationOption, $extensionKey)
102 {
103 $hierarchicConfiguration = [];
104 if (GeneralUtility::isFirstPartOfStr($configurationOption['type'], 'user')) {
105 $configurationOption = $this->extractInformationForConfigFieldsOfTypeUser($configurationOption);
106 } elseif (GeneralUtility::isFirstPartOfStr($configurationOption['type'], 'options')) {
107 $configurationOption = $this->extractInformationForConfigFieldsOfTypeOptions($configurationOption);
108 }
109 if ($this->translate($configurationOption['label'], $extensionKey)) {
110 $configurationOption['label'] = $this->translate($configurationOption['label'], $extensionKey);
111 }
112 $configurationOption['labels'] = GeneralUtility::trimExplode(':', $configurationOption['label'], false, 2);
113 $configurationOption['subcat_name'] = $configurationOption['subcat_name'] ?: '__default';
114 $hierarchicConfiguration[$configurationOption['cat']][$configurationOption['subcat_name']][$configurationOption['name']] = $configurationOption;
115 return $hierarchicConfiguration;
116 }
117
118 /**
119 * Extracts additional information for fields of type "options"
120 * Extracts "type", "label" and values information
121 *
122 * @param array $configurationOption
123 * @return array
124 */
125 protected function extractInformationForConfigFieldsOfTypeOptions(array $configurationOption)
126 {
127 preg_match('/options\[(.*)\]/is', $configurationOption['type'], $typeMatches);
128 $optionItems = GeneralUtility::trimExplode(',', $typeMatches[1]);
129 foreach ($optionItems as $optionItem) {
130 $optionPair = GeneralUtility::trimExplode('=', $optionItem);
131 if (count($optionPair) === 2) {
132 $configurationOption['generic'][$optionPair[0]] = $optionPair[1];
133 } else {
134 $configurationOption['generic'][$optionPair[0]] = $optionPair[0];
135 }
136 }
137 $configurationOption['type'] = 'options';
138 return $configurationOption;
139 }
140
141 /**
142 * Extract additional information for fields of type "user"
143 * Extracts "type" and the function to be called
144 *
145 * @param array $configurationOption
146 * @return array
147 */
148 protected function extractInformationForConfigFieldsOfTypeUser(array $configurationOption)
149 {
150 preg_match('/user\\[(.*)\\]/is', $configurationOption['type'], $matches);
151 $configurationOption['generic'] = $matches[1];
152 $configurationOption['type'] = 'user';
153 return $configurationOption;
154 }
155
156 /**
157 * Gets meta information from configuration array and
158 * returns only the meta information
159 *
160 * @param array $configuration
161 * @return array
162 */
163 protected function addMetaInformation(&$configuration)
164 {
165 $metaInformation = $configuration['__meta__'] ?: [];
166 unset($configuration['__meta__']);
167 return $metaInformation;
168 }
169
170 /**
171 * Merge current local configuration over default configuration
172 *
173 * @param array $defaultConfiguration Default configuration from ext_conf_template.txt
174 * @param string $extensionKey the extension information
175 * @return array
176 */
177 protected function mergeWithExistingConfiguration(array $defaultConfiguration, $extensionKey)
178 {
179 try {
180 $currentExtensionConfig = unserialize(
181 $this->objectManager->get(\TYPO3\CMS\Core\Configuration\ConfigurationManager::class)
182 ->getConfigurationValueByPath('EXT/extConf/' . $extensionKey)
183 );
184 if (!is_array($currentExtensionConfig)) {
185 $currentExtensionConfig = [];
186 }
187 } catch (\RuntimeException $e) {
188 $currentExtensionConfig = [];
189 }
190 $flatExtensionConfig = ArrayUtility::flatten($currentExtensionConfig);
191 $valuedCurrentExtensionConfig = [];
192 foreach ($flatExtensionConfig as $key => $value) {
193 $valuedCurrentExtensionConfig[$key]['value'] = $value;
194 }
195 ArrayUtility::mergeRecursiveWithOverrule($defaultConfiguration, $valuedCurrentExtensionConfig);
196 return $defaultConfiguration;
197 }
198
199 /**
200 * Converts a hierarchic configuration array to an
201 * hierarchic object storage structure
202 *
203 * @param array $configuration
204 * @return \SplObjectStorage
205 */
206 protected function convertHierarchicArrayToObject(array $configuration)
207 {
208 $configurationObjectStorage = new \SplObjectStorage();
209 foreach ($configuration as $category => $subcategory) {
210 /** @var $configurationCategoryObject \TYPO3\CMS\Extensionmanager\Domain\Model\ConfigurationCategory */
211 $configurationCategoryObject = $this->objectManager->get(\TYPO3\CMS\Extensionmanager\Domain\Model\ConfigurationCategory::class);
212 $configurationCategoryObject->setName($category);
213 if ($subcategory['highlightText']) {
214 $configurationCategoryObject->setHighlightText($subcategory['highlightText']);
215 unset($subcategory['highlightText']);
216 }
217 foreach ($subcategory as $subcatName => $configurationItems) {
218 /** @var $configurationSubcategoryObject \TYPO3\CMS\Extensionmanager\Domain\Model\ConfigurationSubcategory */
219 $configurationSubcategoryObject = $this->objectManager->get(\TYPO3\CMS\Extensionmanager\Domain\Model\ConfigurationSubcategory::class);
220 $configurationSubcategoryObject->setName($subcatName);
221 foreach ($configurationItems as $configurationItem) {
222 // Set sub category label if configuration item contains a subcat label.
223 // The sub category label is set multiple times if there is more than one item
224 // in a sub category, but that is ok since all items of one sub category
225 // share the same label.
226 if (array_key_exists('subcat_label', $configurationItem)) {
227 $configurationSubcategoryObject->setLabel($configurationItem['subcat_label']);
228 }
229
230 /** @var $configurationObject \TYPO3\CMS\Extensionmanager\Domain\Model\ConfigurationItem */
231 $configurationObject = $this->objectManager->get(\TYPO3\CMS\Extensionmanager\Domain\Model\ConfigurationItem::class);
232 if (isset($configurationItem['generic'])) {
233 $configurationObject->setGeneric($configurationItem['generic']);
234 }
235 if (isset($configurationItem['cat'])) {
236 $configurationObject->setCategory($configurationItem['cat']);
237 }
238 if (isset($configurationItem['subcat_name'])) {
239 $configurationObject->setSubCategory($configurationItem['subcat_name']);
240 }
241 if (isset($configurationItem['labels']) && isset($configurationItem['labels'][0])) {
242 $configurationObject->setLabelHeadline($configurationItem['labels'][0]);
243 }
244 if (isset($configurationItem['labels']) && isset($configurationItem['labels'][1])) {
245 $configurationObject->setLabelText($configurationItem['labels'][1]);
246 }
247 if (isset($configurationItem['type'])) {
248 $configurationObject->setType($configurationItem['type']);
249 }
250 if (isset($configurationItem['name'])) {
251 $configurationObject->setName($configurationItem['name']);
252 }
253 if (isset($configurationItem['value'])) {
254 $configurationObject->setValue($configurationItem['value']);
255 }
256 if (isset($configurationItem['highlight'])) {
257 $configurationObject->setHighlight($configurationItem['highlight']);
258 }
259 $configurationSubcategoryObject->addItem($configurationObject);
260 }
261 $configurationCategoryObject->addSubcategory($configurationSubcategoryObject);
262 }
263 $configurationObjectStorage->attach($configurationCategoryObject);
264 }
265 return $configurationObjectStorage;
266 }
267
268 /**
269 * Returns the localized label of the LOCAL_LANG key, $key.
270 * Wrapper for the static call.
271 *
272 * @param string $key The key from the LOCAL_LANG array for which to return the value.
273 * @param string $extensionName The name of the extension
274 * @return string|null The value from LOCAL_LANG or NULL if no translation was found.
275 */
276 protected function translate($key, $extensionName)
277 {
278 $translation = \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate($key, $extensionName);
279 if ($translation) {
280 return $translation;
281 }
282 return null;
283 }
284 }