-
Notifications
You must be signed in to change notification settings - Fork 19
/
TemplateDataMapper.php
135 lines (111 loc) · 4.1 KB
/
TemplateDataMapper.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
<?php
declare(strict_types=1);
/*
* This file is part of Sulu.
*
* (c) Sulu GmbH
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Sulu\Bundle\ContentBundle\Content\Application\ContentDataMapper\DataMapper;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\TemplateInterface;
use Sulu\Component\Content\Metadata\Factory\StructureMetadataFactoryInterface;
class TemplateDataMapper implements DataMapperInterface
{
/**
* @var StructureMetadataFactoryInterface
*/
private $factory;
/**
* @var array<string, string>
*/
private $structureDefaultTypes;
/**
* @param array<string, string> $structureDefaultTypes
*/
public function __construct(StructureMetadataFactoryInterface $factory, array $structureDefaultTypes)
{
$this->factory = $factory;
$this->structureDefaultTypes = $structureDefaultTypes;
}
public function map(
DimensionContentInterface $unlocalizedDimensionContent,
DimensionContentInterface $localizedDimensionContent,
array $data
): void {
if (!$localizedDimensionContent instanceof TemplateInterface
|| !$unlocalizedDimensionContent instanceof TemplateInterface
) {
return;
}
$type = $localizedDimensionContent::getTemplateType();
/** @var string|null $template */
$template = $data['template'] ?? null;
if (null === $template) {
$template = $this->structureDefaultTypes[$type] ?? null;
}
if (null === $template) {
throw new \RuntimeException('Expected "template" to be set in the data array.');
}
[$unlocalizedData, $localizedData, $hasAnyValue] = $this->getTemplateData(
$data,
$type,
$template,
$unlocalizedDimensionContent->getTemplateData(),
$localizedDimensionContent->getTemplateData()
);
if (!isset($data['template']) && !$hasAnyValue) {
// do nothing when no data was given
return;
}
$localizedDimensionContent->setTemplateKey($template);
$localizedDimensionContent->setTemplateData($localizedData);
$unlocalizedDimensionContent->setTemplateData($unlocalizedData);
}
/**
* @param mixed[] $data
* @param mixed[] $unlocalizedData
* @param mixed[] $localizedData
*
* @return array{
* 0: mixed[],
* 1: mixed[],
* 2: bool,
* }
*/
private function getTemplateData(
array $data,
string $type,
string $template,
array $unlocalizedData,
array $localizedData
): array {
$metadata = $this->factory->getStructureMetadata($type, $template);
if (!$metadata) {
throw new \RuntimeException(\sprintf('Could not find structure "%s" of type "%s".', $template, $type));
}
$hasAnyValue = false;
$defaultLocalizedData = $localizedData; // use existing localizedData only as default to remove not longer existing properties of the template
$localizedData = [];
foreach ($metadata->getProperties() as $property) {
$name = $property->getName();
// Float are converted to ints in php array as key so we need convert it to string
if (\is_float($name)) {
$name = (string) $name;
}
$value = $property->isLocalized() ? $defaultLocalizedData[$name] ?? null : $defaultLocalizedData[$name] ?? null;
if (\array_key_exists($name, $data)) { // values not explicitly given need to stay untouched for e.g. for shadow pages urls
$hasAnyValue = true;
$value = $data[$name];
}
if ($property->isLocalized()) {
$localizedData[$name] = $value;
continue;
}
$unlocalizedData[$name] = $value;
}
return [$unlocalizedData, $localizedData, $hasAnyValue];
}
}