1
|
|
|
<?php declare(strict_types=1); |
2
|
|
|
|
3
|
|
|
namespace Shopware\Storefront\Theme; |
4
|
|
|
|
5
|
|
|
use Shopware\Core\Framework\Context; |
6
|
|
|
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface; |
7
|
|
|
use Shopware\Core\Framework\DataAbstractionLayer\Exception\InconsistentCriteriaIdsException; |
8
|
|
|
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria; |
9
|
|
|
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter; |
10
|
|
|
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MultiFilter; |
11
|
|
|
use Shopware\Core\Framework\Uuid\Uuid; |
12
|
|
|
use Shopware\Storefront\Theme\Exception\InvalidThemeConfigException; |
13
|
|
|
use Shopware\Storefront\Theme\Exception\InvalidThemeException; |
14
|
|
|
use Shopware\Storefront\Theme\StorefrontPluginConfiguration\StorefrontPluginConfiguration; |
15
|
|
|
use Shopware\Storefront\Theme\StorefrontPluginConfiguration\StorefrontPluginConfigurationCollection; |
16
|
|
|
|
17
|
|
|
class ThemeService |
18
|
|
|
{ |
19
|
|
|
/** |
20
|
|
|
* @var StorefrontPluginRegistryInterface |
21
|
|
|
*/ |
22
|
|
|
private $pluginRegistry; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* @var EntityRepositoryInterface |
26
|
|
|
*/ |
27
|
|
|
private $themeRepository; |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* @var EntityRepositoryInterface |
31
|
|
|
*/ |
32
|
|
|
private $themeSalesChannelRepository; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* @var EntityRepositoryInterface |
36
|
|
|
*/ |
37
|
|
|
private $mediaRepository; |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* @var ThemeCompilerInterface |
41
|
|
|
*/ |
42
|
|
|
private $themeCompiler; |
43
|
|
|
|
44
|
|
|
public function __construct( |
45
|
|
|
StorefrontPluginRegistryInterface $pluginRegistry, |
46
|
|
|
EntityRepositoryInterface $themeRepository, |
47
|
|
|
EntityRepositoryInterface $themeSalesChannelRepository, |
48
|
|
|
EntityRepositoryInterface $mediaRepository, |
49
|
|
|
ThemeCompilerInterface $themeCompiler |
50
|
|
|
) { |
51
|
|
|
$this->pluginRegistry = $pluginRegistry; |
52
|
|
|
$this->themeRepository = $themeRepository; |
53
|
|
|
$this->themeSalesChannelRepository = $themeSalesChannelRepository; |
54
|
|
|
$this->mediaRepository = $mediaRepository; |
55
|
|
|
$this->themeCompiler = $themeCompiler; |
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
public function compileTheme( |
59
|
|
|
string $salesChannelId, |
60
|
|
|
string $themeId, |
61
|
|
|
Context $context, |
62
|
|
|
?StorefrontPluginConfigurationCollection $configurationCollection = null, |
63
|
|
|
bool $withAssets = true |
64
|
|
|
): void { |
65
|
|
|
$themePluginConfiguration = $this->getPluginConfiguration($themeId, $context); |
66
|
|
|
|
67
|
|
|
$this->themeCompiler->compileTheme( |
68
|
|
|
$salesChannelId, |
69
|
|
|
$themeId, |
70
|
|
|
$themePluginConfiguration, |
71
|
|
|
$configurationCollection ?? $this->pluginRegistry->getConfigurations(), |
72
|
|
|
$withAssets |
73
|
|
|
); |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
public function updateTheme(string $themeId, ?array $config, ?string $parentThemeId, Context $context): void |
77
|
|
|
{ |
78
|
|
|
$criteria = new Criteria([$themeId]); |
79
|
|
|
$criteria->addAssociation('salesChannels'); |
80
|
|
|
$theme = $this->themeRepository->search($criteria, $context)->get($themeId); |
81
|
|
|
|
82
|
|
|
if (!$theme) { |
83
|
|
|
throw new InvalidThemeException($themeId); |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
$data = ['id' => $themeId]; |
87
|
|
|
if ($config) { |
|
|
|
|
88
|
|
|
foreach ($config as $key => $value) { |
89
|
|
|
$data['configValues'][$key] = $value; |
90
|
|
|
} |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
if ($parentThemeId) { |
94
|
|
|
$data['parentThemeId'] = $parentThemeId; |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
if (array_key_exists('configValues', $data) && $theme->getConfigValues()) { |
98
|
|
|
$data['configValues'] = array_replace_recursive($theme->getConfigValues(), $data['configValues']); |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
$this->themeRepository->update([$data], $context); |
102
|
|
|
|
103
|
|
|
foreach ($theme->getSalesChannels() as $salesChannel) { |
104
|
|
|
$this->compileTheme($salesChannel->getId(), $themeId, $context, null, false); |
105
|
|
|
} |
106
|
|
|
} |
107
|
|
|
|
108
|
|
|
public function assignTheme(string $themeId, string $salesChannelId, Context $context): bool |
109
|
|
|
{ |
110
|
|
|
$this->compileTheme($salesChannelId, $themeId, $context); |
111
|
|
|
|
112
|
|
|
$this->themeSalesChannelRepository->upsert([[ |
113
|
|
|
'themeId' => $themeId, |
114
|
|
|
'salesChannelId' => $salesChannelId, |
115
|
|
|
]], $context); |
116
|
|
|
|
117
|
|
|
return true; |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
public function resetTheme(string $themeId, Context $context): void |
121
|
|
|
{ |
122
|
|
|
$criteria = new Criteria([$themeId]); |
123
|
|
|
$theme = $this->themeRepository->search($criteria, $context)->get($themeId); |
124
|
|
|
|
125
|
|
|
if (!$theme) { |
126
|
|
|
throw new InvalidThemeException($themeId); |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
$data = ['id' => $themeId]; |
130
|
|
|
$data['configValues'] = null; |
131
|
|
|
|
132
|
|
|
$this->themeRepository->update([$data], $context); |
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
/** |
136
|
|
|
* @throws InvalidThemeConfigException |
137
|
|
|
* @throws InvalidThemeException |
138
|
|
|
* @throws InconsistentCriteriaIdsException |
139
|
|
|
*/ |
140
|
|
|
public function getThemeConfiguration(string $themeId, bool $translate, Context $context): array |
141
|
|
|
{ |
142
|
|
|
$criteria = new Criteria(); |
143
|
|
|
$criteria->setTitle('theme-service::load-config'); |
144
|
|
|
|
145
|
|
|
$criteria->addFilter(new MultiFilter( |
146
|
|
|
MultiFilter::CONNECTION_OR, |
147
|
|
|
[ |
148
|
|
|
new EqualsFilter('technicalName', StorefrontPluginRegistry::BASE_THEME_NAME), |
149
|
|
|
new EqualsFilter('id', $themeId), |
150
|
|
|
] |
151
|
|
|
)); |
152
|
|
|
|
153
|
|
|
$themes = $this->themeRepository->search($criteria, $context); |
154
|
|
|
|
155
|
|
|
$theme = $themes->get($themeId); |
156
|
|
|
|
157
|
|
|
/** @var ThemeEntity|null $theme */ |
158
|
|
|
if (!$theme) { |
159
|
|
|
throw new InvalidThemeException($themeId); |
160
|
|
|
} |
161
|
|
|
|
162
|
|
|
/** @var ThemeEntity $baseTheme */ |
163
|
|
|
$baseTheme = $themes->filter(function (ThemeEntity $theme) { |
164
|
|
|
return $theme->getTechnicalName() === StorefrontPluginRegistry::BASE_THEME_NAME; |
165
|
|
|
})->first(); |
166
|
|
|
|
167
|
|
|
$baseThemeConfig = $this->mergeStaticConfig($baseTheme); |
168
|
|
|
|
169
|
|
|
$themeConfigFieldFactory = new ThemeConfigFieldFactory(); |
170
|
|
|
$configFields = []; |
171
|
|
|
|
172
|
|
|
$configuredTheme = $this->mergeStaticConfig($theme); |
173
|
|
|
$themeConfig = array_replace_recursive($baseThemeConfig, $configuredTheme); |
174
|
|
|
|
175
|
|
|
foreach ($themeConfig['fields'] as $name => $item) { |
176
|
|
|
$configFields[$name] = $themeConfigFieldFactory->create($name, $item); |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
$configFields = json_decode((string) json_encode($configFields), true); |
180
|
|
|
|
181
|
|
|
$labels = array_replace_recursive($baseTheme->getLabels() ?? [], $theme->getLabels() ?? []); |
182
|
|
|
if ($translate && !empty($labels)) { |
183
|
|
|
$configFields = $this->translateLabels($configFields, $labels); |
184
|
|
|
} |
185
|
|
|
|
186
|
|
|
$helpTexts = array_replace_recursive($baseTheme->getHelpTexts() ?? [], $theme->getHelpTexts() ?? []); |
187
|
|
|
if ($translate && !empty($helpTexts)) { |
188
|
|
|
$configFields = $this->translateHelpTexts($configFields, $helpTexts); |
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
$themeConfig['fields'] = $configFields; |
192
|
|
|
|
193
|
|
|
return $themeConfig; |
194
|
|
|
} |
195
|
|
|
|
196
|
|
|
public function getResolvedThemeConfiguration(string $themeId, Context $context): array |
197
|
|
|
{ |
198
|
|
|
$config = $this->getThemeConfiguration($themeId, false, $context); |
199
|
|
|
$resolvedConfig = []; |
200
|
|
|
$mediaItems = []; |
201
|
|
|
if (!array_key_exists('fields', $config)) { |
202
|
|
|
return []; |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
foreach ($config['fields'] as $key => $data) { |
206
|
|
|
if ($data['type'] === 'media' && $data['value'] && Uuid::isValid($data['value'])) { |
207
|
|
|
$mediaItems[$data['value']][] = $key; |
208
|
|
|
} |
209
|
|
|
$resolvedConfig[$key] = $data['value']; |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
/** @var string[] $mediaIds */ |
213
|
|
|
$mediaIds = array_keys($mediaItems); |
214
|
|
|
$criteria = new Criteria($mediaIds); |
215
|
|
|
$criteria->setTitle('theme-service::resolve-media'); |
216
|
|
|
$result = $this->mediaRepository->search($criteria, $context); |
217
|
|
|
|
218
|
|
|
foreach ($result as $media) { |
219
|
|
|
if (!\array_key_exists($media->getId(), $mediaItems)) { |
220
|
|
|
continue; |
221
|
|
|
} |
222
|
|
|
|
223
|
|
|
foreach ($mediaItems[$media->getId()] as $key) { |
224
|
|
|
$resolvedConfig[$key] = $media->getUrl(); |
225
|
|
|
} |
226
|
|
|
} |
227
|
|
|
|
228
|
|
|
return $resolvedConfig; |
229
|
|
|
} |
230
|
|
|
|
231
|
|
|
public function getThemeConfigurationStructuredFields(string $themeId, bool $translate, Context $context): array |
232
|
|
|
{ |
233
|
|
|
$mergedConfig = $this->getThemeConfiguration($themeId, $translate, $context)['fields']; |
234
|
|
|
|
235
|
|
|
$translations = []; |
236
|
|
|
if ($translate) { |
237
|
|
|
$translations = $this->getTranslations($themeId, $context); |
238
|
|
|
$mergedConfig = $this->translateLabels($mergedConfig, $translations); |
239
|
|
|
} |
240
|
|
|
|
241
|
|
|
$outputStructure = []; |
242
|
|
|
|
243
|
|
|
foreach ($mergedConfig as $fieldName => $fieldConfig) { |
244
|
|
|
$tab = $this->getTab($fieldConfig); |
245
|
|
|
$tabLabel = $this->getTabLabel($tab, $translations); |
246
|
|
|
$block = $this->getBlock($fieldConfig); |
247
|
|
|
$blockLabel = $this->getBlockLabel($block, $translations); |
248
|
|
|
$section = $this->getSection($fieldConfig); |
249
|
|
|
$sectionLabel = $this->getSectionLabel($section, $translations); |
250
|
|
|
|
251
|
|
|
// set default tab |
252
|
|
|
$outputStructure['tabs']['default']['label'] = ''; |
253
|
|
|
|
254
|
|
|
// set labels |
255
|
|
|
$outputStructure['tabs'][$tab]['label'] = $tabLabel; |
256
|
|
|
$outputStructure['tabs'][$tab]['blocks'][$block]['label'] = $blockLabel; |
257
|
|
|
$outputStructure['tabs'][$tab]['blocks'][$block]['sections'][$section]['label'] = $sectionLabel; |
258
|
|
|
|
259
|
|
|
// add fields to sections |
260
|
|
|
$outputStructure['tabs'][$tab]['blocks'][$block]['sections'][$section]['fields'][$fieldName] = [ |
261
|
|
|
'label' => $fieldConfig['label'], |
262
|
|
|
'helpText' => $fieldConfig['helpText'] ?? null, |
263
|
|
|
'type' => $fieldConfig['type'], |
264
|
|
|
'custom' => $fieldConfig['custom'], |
265
|
|
|
'fullWidth' => $fieldConfig['fullWidth'], |
266
|
|
|
]; |
267
|
|
|
} |
268
|
|
|
|
269
|
|
|
return $outputStructure; |
270
|
|
|
} |
271
|
|
|
|
272
|
|
|
/** |
273
|
|
|
* @deprecated tag:v6.4.0 use getThemeConfigurationStructuredFields instead |
274
|
|
|
* |
275
|
|
|
* @throws InconsistentCriteriaIdsException |
276
|
|
|
* @throws InvalidThemeConfigException |
277
|
|
|
* @throws InvalidThemeException |
278
|
|
|
*/ |
279
|
|
|
public function getThemeConfigurationFields(string $themeId, bool $translate, Context $context): array |
280
|
|
|
{ |
281
|
|
|
$mergedConfig = $this->getThemeConfiguration($themeId, $translate, $context)['fields']; |
282
|
|
|
|
283
|
|
|
$translations = []; |
284
|
|
|
if ($translate) { |
285
|
|
|
$translations = $this->getTranslations($themeId, $context); |
286
|
|
|
$mergedConfig = $this->translateLabels($mergedConfig, $translations); |
287
|
|
|
} |
288
|
|
|
|
289
|
|
|
$blocks = []; |
290
|
|
|
$noblocks = [ |
291
|
|
|
'label' => $this->getBlockLabel('unordered', $translations), |
292
|
|
|
'sections' => [], |
293
|
|
|
]; |
294
|
|
|
|
295
|
|
|
foreach ($mergedConfig as $fieldName => $fieldConfig) { |
296
|
|
|
$section = $this->getSection($fieldConfig); |
297
|
|
|
|
298
|
|
|
if (!isset($fieldConfig['block'])) { |
299
|
|
|
$noblocks['sections'][$section] = [ |
300
|
|
|
'label' => $this->getSectionLabel($section, $translations), |
301
|
|
|
$fieldName => [ |
302
|
|
|
'label' => $fieldConfig['label'], |
303
|
|
|
'helpText' => $fieldConfig['helpText'] ?? null, |
304
|
|
|
'type' => $fieldConfig['type'], |
305
|
|
|
'custom' => $fieldConfig['custom'], |
306
|
|
|
], |
307
|
|
|
]; |
308
|
|
|
} elseif (!isset($blocks[$fieldConfig['block']])) { |
309
|
|
|
$blocks[$fieldConfig['block']] = [ |
310
|
|
|
'label' => $this->getBlockLabel($fieldConfig['block'], $translations), |
311
|
|
|
'sections' => [ |
312
|
|
|
$section => [ |
313
|
|
|
'label' => $this->getSectionLabel($section, $translations), |
314
|
|
|
$fieldName => [ |
315
|
|
|
'label' => $fieldConfig['label'], |
316
|
|
|
'helpText' => $fieldConfig['helpText'] ?? null, |
317
|
|
|
'type' => $fieldConfig['type'], |
318
|
|
|
'custom' => $fieldConfig['custom'], |
319
|
|
|
], |
320
|
|
|
], |
321
|
|
|
], |
322
|
|
|
]; |
323
|
|
|
} elseif (isset($blocks[$fieldConfig['block']]['sections'][$section])) { |
324
|
|
|
$blocks[$fieldConfig['block']]['sections'][$section][$fieldName] = [ |
325
|
|
|
'label' => $fieldConfig['label'], |
326
|
|
|
'helpText' => $fieldConfig['helpText'] ?? null, |
327
|
|
|
'type' => $fieldConfig['type'], |
328
|
|
|
'custom' => $fieldConfig['custom'], |
329
|
|
|
]; |
330
|
|
|
} else { |
331
|
|
|
$blocks[$fieldConfig['block']]['sections'][$section] = [ |
332
|
|
|
'label' => $this->getSectionLabel($section, $translations), |
333
|
|
|
$fieldName => [ |
334
|
|
|
'label' => $fieldConfig['label'], |
335
|
|
|
'helpText' => $fieldConfig['helpText'] ?? null, |
336
|
|
|
'type' => $fieldConfig['type'], |
337
|
|
|
'custom' => $fieldConfig['custom'], |
338
|
|
|
], |
339
|
|
|
]; |
340
|
|
|
} |
341
|
|
|
} |
342
|
|
|
|
343
|
|
|
$blocks['unordered'] = $noblocks; |
344
|
|
|
|
345
|
|
|
return $blocks; |
346
|
|
|
} |
347
|
|
|
|
348
|
|
|
private function loadCompileConfig(string $themeId, Context $context): array |
349
|
|
|
{ |
350
|
|
|
$config = $this->loadRecursiveConfig($themeId, $context); |
351
|
|
|
|
352
|
|
|
$field = new ThemeConfigField(); |
353
|
|
|
|
354
|
|
|
foreach ($config['fields'] as $name => $item) { |
355
|
|
|
$clone = clone $field; |
356
|
|
|
$clone->setName($name); |
357
|
|
|
$clone->assign($item); |
358
|
|
|
$config[$name] = $clone; |
359
|
|
|
} |
360
|
|
|
|
361
|
|
|
return json_decode((string) json_encode($config), true); |
362
|
|
|
} |
363
|
|
|
|
364
|
|
|
private function loadRecursiveConfig(string $themeId, Context $context): array |
365
|
|
|
{ |
366
|
|
|
$criteria = new Criteria([$themeId]); |
367
|
|
|
|
368
|
|
|
$theme = $this->themeRepository |
369
|
|
|
->search($criteria, $context) |
370
|
|
|
->first(); |
371
|
|
|
|
372
|
|
|
if (!$theme instanceof ThemeEntity) { |
373
|
|
|
throw new InvalidThemeException($themeId); |
374
|
|
|
} |
375
|
|
|
|
376
|
|
|
$config = $this->mergeStaticConfig($theme); |
377
|
|
|
|
378
|
|
|
$parentId = $theme->getParentThemeId(); |
379
|
|
|
if ($parentId) { |
380
|
|
|
$parent = $this->loadRecursiveConfig($parentId, $context); |
381
|
|
|
|
382
|
|
|
return array_replace_recursive($parent, $config); |
383
|
|
|
} |
384
|
|
|
|
385
|
|
|
$criteria = new Criteria(); |
386
|
|
|
$criteria->addFilter(new EqualsFilter('technicalName', StorefrontPluginRegistry::BASE_THEME_NAME)); |
387
|
|
|
|
388
|
|
|
$theme = $this->themeRepository |
389
|
|
|
->search($criteria, $context) |
390
|
|
|
->first(); |
391
|
|
|
|
392
|
|
|
if (!$theme instanceof ThemeEntity) { |
393
|
|
|
throw new InvalidThemeException(StorefrontPluginRegistry::BASE_THEME_NAME); |
394
|
|
|
} |
395
|
|
|
|
396
|
|
|
$base = $this->mergeStaticConfig($theme); |
397
|
|
|
|
398
|
|
|
return array_replace_recursive($base, $config); |
399
|
|
|
} |
400
|
|
|
|
401
|
|
|
private function getPluginConfiguration(string $themeId, Context $context): StorefrontPluginConfiguration |
402
|
|
|
{ |
403
|
|
|
$pluginConfig = $this->loadConfigByName($themeId, $context); |
404
|
|
|
|
405
|
|
|
if (!$pluginConfig) { |
406
|
|
|
throw new InvalidThemeException($themeId); |
407
|
|
|
} |
408
|
|
|
|
409
|
|
|
$pluginConfig = clone $pluginConfig; |
410
|
|
|
|
411
|
|
|
$config = $this->loadCompileConfig($themeId, $context); |
412
|
|
|
|
413
|
|
|
$pluginConfig->setThemeConfig($config); |
414
|
|
|
|
415
|
|
|
return $pluginConfig; |
416
|
|
|
} |
417
|
|
|
|
418
|
|
|
private function loadConfigByName(string $themeId, Context $context): ?StorefrontPluginConfiguration |
419
|
|
|
{ |
420
|
|
|
/** @var ThemeEntity|null $theme */ |
421
|
|
|
$theme = $this->themeRepository |
422
|
|
|
->search(new Criteria([$themeId]), $context) |
423
|
|
|
->get($themeId); |
424
|
|
|
|
425
|
|
|
if ($theme === null) { |
426
|
|
|
return $this->pluginRegistry |
427
|
|
|
->getConfigurations() |
428
|
|
|
->getByTechnicalName(StorefrontPluginRegistry::BASE_THEME_NAME); |
429
|
|
|
} |
430
|
|
|
|
431
|
|
|
$pluginConfig = null; |
432
|
|
|
if ($theme->getTechnicalName() !== null) { |
433
|
|
|
$pluginConfig = $this->pluginRegistry |
434
|
|
|
->getConfigurations() |
435
|
|
|
->getByTechnicalName($theme->getTechnicalName()); |
436
|
|
|
} |
437
|
|
|
|
438
|
|
|
if ($pluginConfig !== null) { |
439
|
|
|
return $pluginConfig; |
440
|
|
|
} |
441
|
|
|
|
442
|
|
|
if ($theme->getParentThemeId() !== null) { |
443
|
|
|
$criteria = new Criteria(); |
444
|
|
|
$criteria->addFilter(new EqualsFilter('id', $theme->getParentThemeId())); |
445
|
|
|
|
446
|
|
|
/** @var ThemeEntity $parentTheme */ |
447
|
|
|
$parentTheme = $this->themeRepository |
448
|
|
|
->search($criteria, $context) |
449
|
|
|
->first(); |
450
|
|
|
|
451
|
|
|
return $this->pluginRegistry |
452
|
|
|
->getConfigurations() |
453
|
|
|
->getByTechnicalName($parentTheme->getTechnicalName()); |
|
|
|
|
454
|
|
|
} |
455
|
|
|
|
456
|
|
|
return $this->pluginRegistry |
457
|
|
|
->getConfigurations() |
458
|
|
|
->getByTechnicalName(StorefrontPluginRegistry::BASE_THEME_NAME); |
459
|
|
|
} |
460
|
|
|
|
461
|
|
|
private function mergeStaticConfig(ThemeEntity $theme): array |
462
|
|
|
{ |
463
|
|
|
$configuredTheme = []; |
464
|
|
|
|
465
|
|
|
$pluginConfig = null; |
466
|
|
|
if ($theme->getTechnicalName()) { |
467
|
|
|
$pluginConfig = $this->pluginRegistry->getConfigurations()->getByTechnicalName($theme->getTechnicalName()); |
468
|
|
|
} |
469
|
|
|
|
470
|
|
|
if ($pluginConfig !== null) { |
471
|
|
|
$configuredTheme = $pluginConfig->getThemeConfig(); |
472
|
|
|
} |
473
|
|
|
|
474
|
|
|
if ($theme !== null && $theme->getBaseConfig() !== null) { |
475
|
|
|
$configuredTheme = array_replace_recursive($configuredTheme, $theme->getBaseConfig()); |
476
|
|
|
} |
477
|
|
|
|
478
|
|
|
if ($theme !== null && $theme->getConfigValues() !== null) { |
479
|
|
|
$configuredThemeFields = []; |
480
|
|
|
if (array_key_exists('fields', $configuredTheme)) { |
481
|
|
|
$configuredThemeFields = $configuredTheme['fields']; |
482
|
|
|
} |
483
|
|
|
$configuredTheme['fields'] = array_replace_recursive($configuredThemeFields, $theme->getConfigValues()); |
484
|
|
|
} |
485
|
|
|
|
486
|
|
|
return $configuredTheme; |
487
|
|
|
} |
488
|
|
|
|
489
|
|
|
private function getTab($fieldConfig): string |
490
|
|
|
{ |
491
|
|
|
$tab = 'default'; |
492
|
|
|
|
493
|
|
|
if (isset($fieldConfig['tab'])) { |
494
|
|
|
$tab = $fieldConfig['tab']; |
495
|
|
|
} |
496
|
|
|
|
497
|
|
|
return $tab; |
498
|
|
|
} |
499
|
|
|
|
500
|
|
|
private function getBlock($fieldConfig): string |
501
|
|
|
{ |
502
|
|
|
$block = 'default'; |
503
|
|
|
|
504
|
|
|
if (isset($fieldConfig['block'])) { |
505
|
|
|
$block = $fieldConfig['block']; |
506
|
|
|
} |
507
|
|
|
|
508
|
|
|
return $block; |
509
|
|
|
} |
510
|
|
|
|
511
|
|
|
private function getSection($fieldConfig): string |
512
|
|
|
{ |
513
|
|
|
$section = 'default'; |
514
|
|
|
|
515
|
|
|
if (isset($fieldConfig['section'])) { |
516
|
|
|
$section = $fieldConfig['section']; |
517
|
|
|
} |
518
|
|
|
|
519
|
|
|
return $section; |
520
|
|
|
} |
521
|
|
|
|
522
|
|
|
private function getTabLabel(string $tabName, array $translations) |
523
|
|
|
{ |
524
|
|
|
if ($tabName === 'default') { |
525
|
|
|
return ''; |
526
|
|
|
} |
527
|
|
|
|
528
|
|
|
return $translations['tabs.' . $tabName] ?? $tabName; |
529
|
|
|
} |
530
|
|
|
|
531
|
|
|
private function getBlockLabel(string $blockName, array $translations) |
532
|
|
|
{ |
533
|
|
|
if ($blockName === 'default') { |
534
|
|
|
return ''; |
535
|
|
|
} |
536
|
|
|
|
537
|
|
|
return $translations['blocks.' . $blockName] ?? $blockName; |
538
|
|
|
} |
539
|
|
|
|
540
|
|
|
private function getSectionLabel(string $sectionName, array $translations) |
541
|
|
|
{ |
542
|
|
|
if ($sectionName === 'default') { |
543
|
|
|
return ''; |
544
|
|
|
} |
545
|
|
|
|
546
|
|
|
return $translations['sections.' . $sectionName] ?? $sectionName; |
547
|
|
|
} |
548
|
|
|
|
549
|
|
|
private function translateLabels(array $themeConfiguration, array $translations): array |
550
|
|
|
{ |
551
|
|
|
foreach ($themeConfiguration as $key => &$value) { |
552
|
|
|
$value['label'] = $translations['fields.' . $key] ?? $key; |
553
|
|
|
} |
554
|
|
|
|
555
|
|
|
return $themeConfiguration; |
556
|
|
|
} |
557
|
|
|
|
558
|
|
|
private function translateHelpTexts(array $themeConfiguration, array $translations): array |
559
|
|
|
{ |
560
|
|
|
foreach ($themeConfiguration as $key => &$value) { |
561
|
|
|
$value['helpText'] = $translations['fields.' . $key] ?? null; |
562
|
|
|
} |
563
|
|
|
|
564
|
|
|
return $themeConfiguration; |
565
|
|
|
} |
566
|
|
|
|
567
|
|
|
/** |
568
|
|
|
* @throws InconsistentCriteriaIdsException |
569
|
|
|
*/ |
570
|
|
|
private function getTranslations(string $themeId, Context $context): array |
571
|
|
|
{ |
572
|
|
|
/** @var ThemeEntity $theme */ |
573
|
|
|
$theme = $this->themeRepository->search(new Criteria([$themeId]), $context)->get($themeId); |
574
|
|
|
$translations = $theme->getLabels() ?: []; |
575
|
|
|
if ($theme->getParentThemeId() !== null) { |
576
|
|
|
$parentTheme = $this->themeRepository->search(new Criteria([$theme->getParentThemeId()]), $context) |
577
|
|
|
->get($theme->getParentThemeId()); |
578
|
|
|
$parentTranslations = $parentTheme->getLabels() ?: []; |
579
|
|
|
$translations = array_replace_recursive($parentTranslations, $translations); |
580
|
|
|
} |
581
|
|
|
$criteria = new Criteria(); |
582
|
|
|
$criteria->addFilter(new EqualsFilter('technicalName', StorefrontPluginRegistry::BASE_THEME_NAME)); |
583
|
|
|
$baseTheme = $this->themeRepository->search($criteria, $context)->first(); |
584
|
|
|
$baseTranslations = $baseTheme->getLabels() ?: []; |
585
|
|
|
$translations = array_replace_recursive($baseTranslations, $translations); |
586
|
|
|
|
587
|
|
|
return $translations; |
588
|
|
|
} |
589
|
|
|
} |
590
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.