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