Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
65 / 65 |
|
100.00% |
7 / 7 |
CRAP | |
100.00% |
1 / 1 |
LeagueDefinitionFactory | |
100.00% |
65 / 65 |
|
100.00% |
7 / 7 |
20 | |
100.00% |
1 / 1 |
makeAttributeDefinition | |
100.00% |
13 / 13 |
|
100.00% |
1 / 1 |
3 | |||
isValTester | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
3 | |||
makeAttributeValueTesterDefinition | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
2 | |||
isArrayOfStrings | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
2 | |||
makeElementDefinition | |
100.00% |
16 / 16 |
|
100.00% |
1 / 1 |
5 | |||
makeEventDefinition | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
2 | |||
makeOtherDefinition | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
3 |
1 | <?php |
2 | |
3 | /** |
4 | * @author: Doug Wilbourne (dougwilbourne@gmail.com) |
5 | */ |
6 | |
7 | declare(strict_types=1); |
8 | |
9 | namespace pvc\html\htmlBuilder\definitions\implementations\league; |
10 | |
11 | use League\Container\Argument\LiteralArgument; |
12 | use League\Container\Definition\Definition; |
13 | use League\Container\Definition\DefinitionInterface; |
14 | use pvc\html\err\DTOInvalidPropertyValueException; |
15 | use pvc\html\err\DTOMissingPropertyException; |
16 | use pvc\html\htmlBuilder\definitions\dto\AttributeDTO; |
17 | use pvc\html\htmlBuilder\definitions\dto\AttributeValTesterDTO; |
18 | use pvc\html\htmlBuilder\definitions\dto\ElementDTO; |
19 | use pvc\html\htmlBuilder\definitions\dto\EventDTO; |
20 | use pvc\html\htmlBuilder\definitions\dto\OtherDTO; |
21 | use pvc\html\htmlBuilder\definitions\types\AttributeType; |
22 | use pvc\html\htmlBuilder\definitions\types\ElementType; |
23 | use pvc\html\htmlBuilder\definitions\types\EventType; |
24 | use pvc\html\val_tester\EventScriptTester; |
25 | use pvc\interfaces\html\htmlBuilder\definitions\DefinitionFactoryInterface; |
26 | use pvc\interfaces\validator\ValTesterInterface; |
27 | use Throwable; |
28 | |
29 | /** |
30 | * Class LeagueDefinitionFactory |
31 | * |
32 | * @phpstan-import-type DefArray from DefinitionFactoryInterface |
33 | * @implements DefinitionFactoryInterface<Definition> |
34 | */ |
35 | class LeagueDefinitionFactory implements DefinitionFactoryInterface |
36 | { |
37 | /** |
38 | * makeAttributeDefinition |
39 | * @param DefArray $definitionArray |
40 | * @return DefinitionInterface |
41 | * @throws DTOMissingPropertyException |
42 | */ |
43 | public function makeAttributeDefinition(array $definitionArray): mixed |
44 | { |
45 | $attributeDTO = new AttributeDTO(); |
46 | $attributeDTO->permitExtraProperties(); |
47 | $attributeDTO->hydrateFromArray($definitionArray); |
48 | |
49 | if (!$class = AttributeType::getClass($attributeDTO->concrete)) { |
50 | throw new DTOInvalidPropertyValueException('concrete', $attributeDTO->concrete, 'Attribute'); |
51 | } |
52 | |
53 | $def = (new Definition($attributeDTO->defId, $class)) |
54 | ->addMethodCall('setDefId', [new LiteralArgument($attributeDTO->defId)]) |
55 | ->addMethodCall('setName', [new LiteralArgument($attributeDTO->name)]) |
56 | ->addMethodCall('setGlobal', [$attributeDTO->global]); |
57 | |
58 | if ($attributeDTO->valTester) { |
59 | $def->addMethodCall('setTester', [$attributeDTO->valTester]) |
60 | ->addMethodCall('setCaseSensitive', [$attributeDTO->caseSensitive]); |
61 | } |
62 | return $def; |
63 | } |
64 | |
65 | /** |
66 | * isValTester |
67 | * @param string $valTester |
68 | * @return bool |
69 | */ |
70 | protected function isValTester(string $valTester): bool |
71 | { |
72 | try { |
73 | /** @phpstan-ignore argument.type */ |
74 | $reflection = new \ReflectionClass($valTester); |
75 | if (!$reflection->implementsInterface(ValTesterInterface::class)) { |
76 | return false; |
77 | } |
78 | } catch (Throwable $e) { |
79 | return false; |
80 | } |
81 | return true; |
82 | } |
83 | |
84 | |
85 | /** |
86 | * makeAttributeValueTesterDefinition |
87 | * @param DefArray $definitionArray |
88 | * @return DefinitionInterface |
89 | */ |
90 | public function makeAttributeValueTesterDefinition(array $definitionArray): mixed |
91 | { |
92 | $attributeValTesterDTO = new AttributeValTesterDTO(); |
93 | $attributeValTesterDTO->permitExtraProperties(); |
94 | $attributeValTesterDTO->hydrateFromArray($definitionArray); |
95 | |
96 | if (!$this->isValTester($attributeValTesterDTO->concrete)) { |
97 | throw new DTOInvalidPropertyValueException('valTester', $attributeValTesterDTO->concrete, 'AttributeValtesterDTO'); |
98 | } |
99 | |
100 | return (new Definition($attributeValTesterDTO->defId, $attributeValTesterDTO->concrete)) |
101 | ->addArgument($attributeValTesterDTO->arg) |
102 | ->setShared(true); |
103 | } |
104 | |
105 | |
106 | /** |
107 | * isArrayOfStrings |
108 | * @param array<mixed> $array |
109 | * @return bool |
110 | */ |
111 | protected function isArrayOfStrings(array $array): bool |
112 | { |
113 | $callback = function (bool $carry, mixed $x) { |
114 | return $carry && is_string($x); |
115 | }; |
116 | return array_reduce($array, $callback, true); |
117 | } |
118 | |
119 | |
120 | /** |
121 | * makeElementDefinition |
122 | * @param DefArray $definitionArray |
123 | * @return DefinitionInterface |
124 | */ |
125 | public function makeElementDefinition(array $definitionArray): mixed |
126 | { |
127 | $elementDTO = new ElementDTO(); |
128 | $elementDTO->permitExtraProperties(); |
129 | $elementDTO->hydrateFromArray($definitionArray); |
130 | |
131 | if (!$class = ElementType::getClass($elementDTO->concrete)) { |
132 | throw new DTOInvalidPropertyValueException('concrete', $elementDTO->concrete, 'ElementDTO'); |
133 | } |
134 | |
135 | if (!$this->isArrayOfStrings($elementDTO->allowedAttributeDefIds)) { |
136 | $childDefIds = implode(',', $elementDTO->allowedAttributeDefIds); |
137 | throw new DTOInvalidPropertyValueException('allowedAttributeDefIds', $childDefIds, 'ElementDTO'); |
138 | } |
139 | |
140 | if (!$this->isArrayOfStrings($elementDTO->allowedChildDefIds)) { |
141 | throw new DTOInvalidPropertyValueException('allowedChildDefIds', $elementDTO->allowedChildDefIds, 'ElementDTO'); |
142 | } |
143 | |
144 | $def = (new Definition($elementDTO->defId, $class)) |
145 | ->addMethodCall('setName', [new LiteralArgument($elementDTO->name)]) |
146 | ->addMethodCall('setAllowedAttributeDefIds', [$elementDTO->allowedAttributeDefIds]); |
147 | |
148 | /** |
149 | * child elements are only applicable to the Tag class (not TagVoid) |
150 | */ |
151 | if ($elementDTO->concrete == 'Tag') { |
152 | $def->addMethodCall('setAllowedChildDefIds', [$elementDTO->allowedChildDefIds]); |
153 | } |
154 | return $def; |
155 | } |
156 | |
157 | /** |
158 | * makeEventDefinition |
159 | * @param DefArray $definitionArray |
160 | * @return DefinitionInterface |
161 | */ |
162 | public function makeEventDefinition(array $definitionArray): mixed |
163 | { |
164 | $eventDTO = new EventDTO(); |
165 | $eventDTO->permitExtraProperties(); |
166 | $eventDTO->hydrateFromArray($definitionArray); |
167 | |
168 | if (!$class = EventType::getClass($eventDTO->concrete)) { |
169 | throw new DTOInvalidPropertyValueException('concrete', $eventDTO->concrete, 'EventDTO'); |
170 | } |
171 | |
172 | return (new Definition($eventDTO->defId, $class)) |
173 | ->addArgument(EventScriptTester::class) |
174 | ->addMethodCall('setDefId', [new LiteralArgument($eventDTO->defId)]); |
175 | } |
176 | |
177 | /** |
178 | * makeOtherSharedDefinition |
179 | * @param DefArray $definitionArray |
180 | * @return DefinitionInterface |
181 | */ |
182 | public function makeOtherDefinition(array $definitionArray): mixed |
183 | { |
184 | $otherDTO = new OtherDTO(); |
185 | $otherDTO->permitExtraProperties(); |
186 | $otherDTO->hydrateFromArray($definitionArray); |
187 | |
188 | if (!class_exists($otherDTO->concrete)) { |
189 | throw new DTOInvalidPropertyValueException('concrete', $otherDTO->concrete, 'OtherDTO'); |
190 | } |
191 | |
192 | $def = (new Definition($otherDTO->defId, $otherDTO->concrete)) |
193 | ->setShared($otherDTO->shared); |
194 | /** |
195 | * not all the constructors have arguments.... |
196 | */ |
197 | if ($otherDTO->arg) { |
198 | $def->addArgument($otherDTO->arg); |
199 | } |
200 | return $def; |
201 | } |
202 | } |