Total Complexity | 49 |
Total Lines | 352 |
Duplicated Lines | 0 % |
Changes | 0 |
Complex classes like SystemConfigService often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use SystemConfigService, and based on these observations, apply Extract Interface, too.
1 | <?php declare(strict_types=1); |
||
25 | class SystemConfigService |
||
26 | { |
||
27 | /** |
||
28 | * @var Connection |
||
29 | */ |
||
30 | private $connection; |
||
31 | |||
32 | /** |
||
33 | * @var EntityRepositoryInterface |
||
34 | */ |
||
35 | private $systemConfigRepository; |
||
36 | |||
37 | /** |
||
38 | * @var array[] |
||
39 | */ |
||
40 | private $configs = []; |
||
41 | |||
42 | /** |
||
43 | * @var ConfigReader |
||
44 | */ |
||
45 | private $configReader; |
||
46 | |||
47 | public function __construct( |
||
55 | } |
||
56 | |||
57 | /** |
||
58 | * @return array|bool|float|int|string|null |
||
59 | */ |
||
60 | public function get(string $key, ?string $salesChannelId = null) |
||
83 | } |
||
84 | |||
85 | public function getString(string $key, ?string $salesChannelId = null): string |
||
93 | } |
||
94 | |||
95 | public function getInt(string $key, ?string $salesChannelId = null): int |
||
96 | { |
||
97 | $value = $this->get($key, $salesChannelId); |
||
98 | if (!\is_array($value)) { |
||
99 | return (int) $value; |
||
100 | } |
||
101 | |||
102 | throw new InvalidSettingValueException($key, 'int', \gettype($value)); |
||
103 | } |
||
104 | |||
105 | public function getFloat(string $key, ?string $salesChannelId = null): float |
||
106 | { |
||
107 | $value = $this->get($key, $salesChannelId); |
||
108 | if (!\is_array($value)) { |
||
109 | return (float) $value; |
||
110 | } |
||
111 | |||
112 | throw new InvalidSettingValueException($key, 'float', \gettype($value)); |
||
113 | } |
||
114 | |||
115 | public function getBool(string $key, ?string $salesChannelId = null): bool |
||
118 | } |
||
119 | |||
120 | /** |
||
121 | * gets all available shop configs and returns them as an array |
||
122 | */ |
||
123 | public function all(?string $salesChannelId = null): array |
||
126 | } |
||
127 | |||
128 | /** |
||
129 | * @throws InvalidDomainException |
||
130 | * @throws InvalidUuidException |
||
131 | * @throws InconsistentCriteriaIdsException |
||
132 | */ |
||
133 | public function getDomain(string $domain, ?string $salesChannelId = null, bool $inherit = false): array |
||
134 | { |
||
135 | $domain = trim($domain); |
||
136 | if ($domain === '') { |
||
137 | throw new InvalidDomainException('Empty domain'); |
||
138 | } |
||
139 | |||
140 | $queryBuilder = $this->connection->createQueryBuilder() |
||
141 | ->select('LOWER(HEX(id))') |
||
142 | ->from('system_config'); |
||
143 | |||
144 | if ($inherit) { |
||
145 | $queryBuilder->where('sales_channel_id IS NULL OR sales_channel_id = :salesChannelId'); |
||
146 | } elseif ($salesChannelId === null) { |
||
147 | $queryBuilder->where('sales_channel_id IS NULL'); |
||
148 | } else { |
||
149 | $queryBuilder->where('sales_channel_id = :salesChannelId'); |
||
150 | } |
||
151 | |||
152 | $domain = rtrim($domain, '.') . '.'; |
||
153 | $escapedDomain = str_replace('%', '\\%', $domain); |
||
154 | |||
155 | $salesChannelId = $salesChannelId ? Uuid::fromHexToBytes($salesChannelId) : null; |
||
156 | |||
157 | $queryBuilder->andWhere('configuration_key LIKE :prefix') |
||
158 | ->orderBy('configuration_key', 'ASC') |
||
159 | ->addOrderBy('sales_channel_id', 'ASC') |
||
160 | ->setParameter('prefix', $escapedDomain . '%') |
||
161 | ->setParameter('salesChannelId', $salesChannelId); |
||
162 | $ids = $queryBuilder->execute()->fetchAll(FetchMode::COLUMN); |
||
163 | |||
164 | if (empty($ids)) { |
||
165 | return []; |
||
166 | } |
||
167 | |||
168 | $criteria = new Criteria($ids); |
||
169 | /** @var SystemConfigCollection $collection */ |
||
170 | $collection = $this->systemConfigRepository |
||
171 | ->search($criteria, Context::createDefaultContext()) |
||
172 | ->getEntities(); |
||
173 | |||
174 | $collection->sortByIdArray($ids); |
||
175 | $merged = []; |
||
176 | |||
177 | foreach ($collection as $cur) { |
||
178 | $key = $cur->getConfigurationKey(); |
||
179 | $value = $cur->getConfigurationValue(); |
||
180 | |||
181 | $inheritedValuePresent = array_key_exists($key, $merged); |
||
182 | $valueConsideredEmpty = !is_bool($value) && empty($value); |
||
183 | |||
184 | if ($inheritedValuePresent && $valueConsideredEmpty) { |
||
185 | continue; |
||
186 | } |
||
187 | |||
188 | $merged[$key] = $value; |
||
189 | } |
||
190 | |||
191 | return $merged; |
||
192 | } |
||
193 | |||
194 | /** |
||
195 | * @param array|bool|float|int|string|null $value |
||
196 | */ |
||
197 | public function set(string $key, $value, ?string $salesChannelId = null): void |
||
221 | } |
||
222 | |||
223 | public function delete(string $key, ?string $salesChannel = null): void |
||
226 | } |
||
227 | |||
228 | /** |
||
229 | * Fetches default values from bundle configuration and saves it to database |
||
230 | */ |
||
231 | public function savePluginConfiguration(Bundle $bundle, bool $override = false): void |
||
232 | { |
||
233 | try { |
||
234 | $config = $this->configReader->getConfigFromBundle($bundle); |
||
235 | } catch (BundleConfigNotFoundException $e) { |
||
236 | return; |
||
237 | } |
||
238 | |||
239 | $prefix = $bundle->getName() . '.config.'; |
||
240 | |||
241 | $this->saveConfig($config, $prefix, $override); |
||
242 | } |
||
243 | |||
244 | public function saveConfig(array $config, string $prefix, bool $override): void |
||
245 | { |
||
246 | foreach ($config as $card) { |
||
247 | foreach ($card['elements'] as $element) { |
||
248 | $key = $prefix . $element['name']; |
||
249 | if (!isset($element['defaultValue'])) { |
||
250 | continue; |
||
251 | } |
||
252 | |||
253 | $value = XmlUtils::phpize($element['defaultValue']); |
||
254 | if ($override || $this->get($key) === null) { |
||
255 | $this->set($key, $value); |
||
256 | } |
||
257 | } |
||
258 | } |
||
259 | } |
||
260 | |||
261 | private function load(?string $salesChannelId): array |
||
302 | } |
||
303 | |||
304 | /** |
||
305 | * The keys of the system configs look like `core.loginRegistration.showPhoneNumberField`. |
||
306 | * This method splits those strings and builds an array structure |
||
307 | * |
||
308 | * ``` |
||
309 | * Array |
||
310 | * ( |
||
311 | * [core] => Array |
||
312 | * ( |
||
313 | * [loginRegistration] => Array |
||
314 | * ( |
||
315 | * [showPhoneNumberField] => 'someValue' |
||
316 | * ) |
||
317 | * ) |
||
318 | * ) |
||
319 | * ``` |
||
320 | */ |
||
321 | private function buildSystemConfigArray(SystemConfigCollection $systemConfigs): array |
||
322 | { |
||
323 | $configValues = []; |
||
324 | |||
325 | foreach ($systemConfigs as $systemConfig) { |
||
326 | $keys = explode('.', $systemConfig->getConfigurationKey()); |
||
327 | |||
328 | $configValues = $this->getSubArray($configValues, $keys, $systemConfig->getConfigurationValue()); |
||
329 | } |
||
330 | |||
331 | return $configValues; |
||
332 | } |
||
333 | |||
334 | private function getSubArray(array $configValues, array $keys, $value): array |
||
335 | { |
||
336 | $key = array_shift($keys); |
||
337 | |||
338 | if (empty($keys)) { |
||
339 | $configValues[$key] = $value; |
||
340 | } else { |
||
341 | if (!\array_key_exists($key, $configValues)) { |
||
342 | $configValues[$key] = []; |
||
343 | } |
||
344 | |||
345 | $configValues[$key] = $this->getSubArray($configValues[$key], $keys, $value); |
||
346 | } |
||
347 | |||
348 | return $configValues; |
||
349 | } |
||
350 | |||
351 | /** |
||
352 | * @throws InvalidKeyException |
||
353 | * @throws InvalidUuidException |
||
354 | */ |
||
355 | private function validate(string $key, ?string $salesChannelId): void |
||
356 | { |
||
357 | $key = trim($key); |
||
358 | if ($key === '') { |
||
359 | throw new InvalidKeyException('key may not be empty'); |
||
360 | } |
||
361 | if ($salesChannelId && !Uuid::isValid($salesChannelId)) { |
||
362 | throw new InvalidUuidException($salesChannelId); |
||
363 | } |
||
364 | } |
||
365 | |||
366 | private function getId(string $key, ?string $salesChannelId = null): ?string |
||
377 | } |
||
378 | } |
||
379 |