[CLEANUP] Replace count with empty in EXT:extensionmanager
[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 * @author Susanne Moog <typo3@susannemoog.de>
24 */
25 class ConfigurationItemRepository {
26
27 /**
28 * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
29 * @inject
30 */
31 protected $objectManager;
32
33 /**
34 * Find configuration options by extension
35 *
36 * @param string $extensionKey Extension key
37 * @return \SplObjectStorage
38 */
39 public function findByExtensionKey($extensionKey) {
40 $configurationArray = $this->getConfigurationArrayFromExtensionKey($extensionKey);
41 return $this->convertHierarchicArrayToObject($configurationArray);
42 }
43
44 /**
45 * Converts the raw configuration file content to an configuration object storage
46 *
47 * @param string $extensionKey Extension key
48 * @return array
49 */
50 protected function getConfigurationArrayFromExtensionKey($extensionKey) {
51 /** @var $configurationUtility \TYPO3\CMS\Extensionmanager\Utility\ConfigurationUtility */
52 $configurationUtility = $this->objectManager->get(\TYPO3\CMS\Extensionmanager\Utility\ConfigurationUtility::class);
53 $defaultConfiguration = $configurationUtility->getDefaultConfigurationFromExtConfTemplateAsValuedArray($extensionKey);
54
55 $resultArray = array();
56 if (!empty($defaultConfiguration)) {
57 $metaInformation = $this->addMetaInformation($defaultConfiguration);
58 $configuration = $this->mergeWithExistingConfiguration($defaultConfiguration, $extensionKey);
59 $hierarchicConfiguration = array();
60 foreach ($configuration as $configurationOption) {
61 $originalConfiguration = $this->buildConfigurationArray($configurationOption, $extensionKey);
62 ArrayUtility::mergeRecursiveWithOverrule($originalConfiguration, $hierarchicConfiguration);
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 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 (GeneralUtility::isFirstPartOfStr($configurationOption['type'], 'user')) {
97 $configurationOption = $this->extractInformationForConfigFieldsOfTypeUser($configurationOption);
98 } elseif (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'] = 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 = GeneralUtility::trimExplode(',', $typeMatches[1]);
120 foreach ($optionItems as $optionItem) {
121 $optionPair = 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 if (!is_array($currentExtensionConfig)) {
173 $currentExtensionConfig = array();
174 }
175 } catch (\RuntimeException $e) {
176 $currentExtensionConfig = array();
177 }
178 $flatExtensionConfig = ArrayUtility::flatten($currentExtensionConfig);
179 $valuedCurrentExtensionConfig = array();
180 foreach ($flatExtensionConfig as $key => $value) {
181 $valuedCurrentExtensionConfig[$key]['value'] = $value;
182 }
183 ArrayUtility::mergeRecursiveWithOverrule($defaultConfiguration, $valuedCurrentExtensionConfig);
184 return $defaultConfiguration;
185 }
186
187 /**
188 * Converts a hierarchic configuration array to an
189 * hierarchic object storage structure
190 *
191 * @param array $configuration
192 * @return \SplObjectStorage
193 */
194 protected function convertHierarchicArrayToObject(array $configuration) {
195 $configurationObjectStorage = new \SplObjectStorage();
196 foreach ($configuration as $category => $subcategory) {
197 /** @var $configurationCategoryObject \TYPO3\CMS\Extensionmanager\Domain\Model\ConfigurationCategory */
198 $configurationCategoryObject = $this->objectManager->get(\TYPO3\CMS\Extensionmanager\Domain\Model\ConfigurationCategory::class);
199 $configurationCategoryObject->setName($category);
200 if ($subcategory['highlightText']) {
201 $configurationCategoryObject->setHighlightText($subcategory['highlightText']);
202 unset($subcategory['highlightText']);
203 }
204 foreach ($subcategory as $subcatName => $configurationItems) {
205 /** @var $configurationSubcategoryObject \TYPO3\CMS\Extensionmanager\Domain\Model\ConfigurationSubcategory */
206 $configurationSubcategoryObject = $this->objectManager->get(\TYPO3\CMS\Extensionmanager\Domain\Model\ConfigurationSubcategory::class);
207 $configurationSubcategoryObject->setName($subcatName);
208 foreach ($configurationItems as $configurationItem) {
209 // Set sub category label if configuration item contains a subcat label.
210 // The sub category label is set multiple times if there is more than one item
211 // in a sub category, but that is ok since all items of one sub category
212 // share the same label.
213 if (array_key_exists('subcat_label', $configurationItem)) {
214 $configurationSubcategoryObject->setLabel($configurationItem['subcat_label']);
215 }
216
217 /** @var $configurationObject \TYPO3\CMS\Extensionmanager\Domain\Model\ConfigurationItem */
218 $configurationObject = $this->objectManager->get(\TYPO3\CMS\Extensionmanager\Domain\Model\ConfigurationItem::class);
219 if (isset($configurationItem['generic'])) {
220 $configurationObject->setGeneric($configurationItem['generic']);
221 }
222 if (isset($configurationItem['cat'])) {
223 $configurationObject->setCategory($configurationItem['cat']);
224 }
225 if (isset($configurationItem['subcat_name'])) {
226 $configurationObject->setSubCategory($configurationItem['subcat_name']);
227 }
228 if (isset($configurationItem['labels']) && isset($configurationItem['labels'][0])) {
229 $configurationObject->setLabelHeadline($configurationItem['labels'][0]);
230 }
231 if (isset($configurationItem['labels']) && isset($configurationItem['labels'][1])) {
232 $configurationObject->setLabelText($configurationItem['labels'][1]);
233 }
234 if (isset($configurationItem['type'])) {
235 $configurationObject->setType($configurationItem['type']);
236 }
237 if (isset($configurationItem['name'])) {
238 $configurationObject->setName($configurationItem['name']);
239 }
240 if (isset($configurationItem['value'])) {
241 $configurationObject->setValue($configurationItem['value']);
242 }
243 if (isset($configurationItem['highlight'])) {
244 $configurationObject->setHighlight($configurationItem['highlight']);
245 }
246 $configurationSubcategoryObject->addItem($configurationObject);
247 }
248 $configurationCategoryObject->addSubcategory($configurationSubcategoryObject);
249 }
250 $configurationObjectStorage->attach($configurationCategoryObject);
251 }
252 return $configurationObjectStorage;
253 }
254
255 /**
256 * Returns the localized label of the LOCAL_LANG key, $key.
257 * Wrapper for the static call.
258 *
259 * @param string $key The key from the LOCAL_LANG array for which to return the value.
260 * @param string $extensionName The name of the extension
261 * @return string|NULL The value from LOCAL_LANG or NULL if no translation was found.
262 */
263 protected function translate($key, $extensionName) {
264 $translation = \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate($key, $extensionName);
265 if ($translation) {
266 return $translation;
267 }
268 return NULL;
269 }
270
271 }