1 | <?php |
||
2 | |||
3 | declare(strict_types=1); |
||
4 | |||
5 | namespace Doctrine\ORM\Mapping\Driver; |
||
6 | |||
7 | use Doctrine\Common\Collections\Criteria; |
||
8 | use Doctrine\ORM\Annotation; |
||
9 | use Doctrine\ORM\Events; |
||
10 | use Doctrine\ORM\Mapping; |
||
11 | use Doctrine\ORM\Mapping\Builder; |
||
12 | use InvalidArgumentException; |
||
13 | use SimpleXMLElement; |
||
14 | use function class_exists; |
||
15 | use function constant; |
||
16 | use function explode; |
||
17 | use function file_get_contents; |
||
18 | use function in_array; |
||
19 | use function simplexml_load_string; |
||
20 | use function str_replace; |
||
21 | use function strtoupper; |
||
22 | |||
23 | /** |
||
24 | * XmlDriver is a metadata driver that enables mapping through XML files. |
||
25 | */ |
||
26 | class XmlDriver extends FileDriver |
||
27 | { |
||
28 | public const DEFAULT_FILE_EXTENSION = '.dcm.xml'; |
||
29 | |||
30 | /** |
||
31 | * {@inheritDoc} |
||
32 | */ |
||
33 | 41 | public function __construct($locator, $fileExtension = self::DEFAULT_FILE_EXTENSION) |
|
34 | { |
||
35 | 41 | parent::__construct($locator, $fileExtension); |
|
36 | 41 | } |
|
37 | |||
38 | 36 | public function loadMetadataForClass( |
|
39 | string $className, |
||
40 | ?Mapping\ComponentMetadata $parent, |
||
41 | Mapping\ClassMetadataBuildingContext $metadataBuildingContext |
||
42 | ) : Mapping\ComponentMetadata { |
||
43 | /** @var SimpleXMLElement $xmlRoot */ |
||
44 | 36 | $xmlRoot = $this->getElement($className); |
|
45 | 34 | $classBuilder = new Builder\ClassMetadataBuilder($metadataBuildingContext); |
|
46 | $classMetadata = $classBuilder |
||
47 | 34 | ->withClassName($className) |
|
48 | 34 | ->withParentMetadata($parent) |
|
49 | 34 | ->withEntityAnnotation( |
|
50 | 34 | $xmlRoot->getName() === 'entity' |
|
51 | 34 | ? $this->convertEntityElementToEntityAnnotation($xmlRoot) |
|
52 | 34 | : null |
|
53 | ) |
||
54 | 34 | ->withMappedSuperclassAnnotation( |
|
55 | 34 | $xmlRoot->getName() === 'mapped-superclass' |
|
56 | 5 | ? $this->convertMappedSuperclassElementToMappedSuperclassAnnotation($xmlRoot) |
|
57 | 34 | : null |
|
58 | ) |
||
59 | 34 | ->withEmbeddableAnnotation( |
|
60 | 34 | $xmlRoot->getName() === 'embeddable' |
|
61 | ? null |
||
62 | 34 | : null |
|
63 | ) |
||
64 | 34 | ->withTableAnnotation( |
|
65 | // @todo guilhermeblanco Is this the proper check to build Table annotation? |
||
66 | 34 | $xmlRoot->getName() === 'entity' |
|
67 | 34 | ? $this->convertTableElementToTableAnnotation($xmlRoot) |
|
68 | 34 | : null |
|
69 | ) |
||
70 | 34 | ->withInheritanceTypeAnnotation( |
|
71 | 34 | isset($xmlRoot['inheritance-type']) |
|
72 | 10 | ? $this->convertInheritanceTypeElementToInheritanceTypeAnnotation($xmlRoot) |
|
73 | 34 | : null |
|
74 | ) |
||
75 | 34 | ->withDiscriminatorColumnAnnotation( |
|
76 | 34 | isset($xmlRoot->{'discriminator-column'}) |
|
77 | 8 | ? $this->convertDiscrimininatorColumnElementToDiscriminatorColumnAnnotation($xmlRoot->{'discriminator-column'}) |
|
78 | 34 | : null |
|
79 | ) |
||
80 | 34 | ->withDiscriminatorMapAnnotation( |
|
81 | 34 | isset($xmlRoot->{'discriminator-map'}) |
|
82 | 10 | ? $this->convertDiscriminatorMapElementToDiscriminatorMapAnnotation($xmlRoot->{'discriminator-map'}) |
|
83 | 34 | : null |
|
84 | ) |
||
85 | 34 | ->withChangeTrackingPolicyAnnotation( |
|
86 | 34 | isset($xmlRoot['change-tracking-policy']) |
|
87 | ? $this->convertChangeTrackingPolicyElementToChangeTrackingPolicyAnnotation($xmlRoot) |
||
88 | 34 | : null |
|
89 | ) |
||
90 | 34 | ->withCacheAnnotation( |
|
91 | 34 | isset($xmlRoot->cache) |
|
92 | 2 | ? $this->convertCacheElementToCacheAnnotation($xmlRoot->cache) |
|
93 | 34 | : null |
|
94 | ) |
||
95 | 34 | ->build(); |
|
96 | |||
97 | 34 | $propertyBuilder = new Builder\PropertyMetadataBuilder($metadataBuildingContext); |
|
98 | |||
99 | 34 | $propertyBuilder->withComponentMetadata($classMetadata); |
|
100 | |||
101 | // Evaluate <field ...> mappings |
||
102 | 34 | if (isset($xmlRoot->field)) { |
|
103 | 20 | foreach ($xmlRoot->field as $fieldElement) { |
|
104 | $propertyBuilder |
||
105 | 20 | ->withFieldName((string) $fieldElement['name']) |
|
106 | 20 | ->withColumnAnnotation($this->convertFieldElementToColumnAnnotation($fieldElement)) |
|
107 | 20 | ->withIdAnnotation(null) |
|
108 | 20 | ->withVersionAnnotation( |
|
109 | 20 | isset($fieldElement['version']) && $this->evaluateBoolean($fieldElement['version']) |
|
110 | 3 | ? new Annotation\Version() |
|
111 | 20 | : null |
|
112 | ); |
||
113 | |||
114 | 20 | $classMetadata->addProperty($propertyBuilder->build()); |
|
115 | } |
||
116 | } |
||
117 | |||
118 | 34 | if (isset($xmlRoot->embedded)) { |
|
119 | foreach ($xmlRoot->embedded as $embeddedElement) { |
||
120 | $propertyBuilder |
||
121 | ->withFieldName((string) $embeddedElement['name']) |
||
122 | ->withEmbeddedAnnotation($this->convertEmbeddedElementToEmbeddedAnnotation($embeddedElement)) |
||
123 | ->withIdAnnotation(null) |
||
124 | ->withVersionAnnotation( |
||
125 | isset($embeddedElement['version']) && $this->evaluateBoolean($embeddedElement['version']) |
||
126 | ? new Annotation\Version() |
||
127 | : null |
||
128 | ); |
||
129 | |||
130 | $classMetadata->addProperty($propertyBuilder->build()); |
||
131 | } |
||
132 | } |
||
133 | |||
134 | // Evaluate <id ...> mappings |
||
135 | 34 | $associationIds = []; |
|
136 | |||
137 | 34 | foreach ($xmlRoot->id as $idElement) { |
|
138 | 29 | $fieldName = (string) $idElement['name']; |
|
139 | |||
140 | 29 | if (isset($idElement['association-key']) && $this->evaluateBoolean($idElement['association-key'])) { |
|
141 | 2 | $associationIds[$fieldName] = true; |
|
142 | |||
143 | 2 | continue; |
|
144 | } |
||
145 | |||
146 | $propertyBuilder |
||
147 | 28 | ->withFieldName($fieldName) |
|
148 | 28 | ->withColumnAnnotation($this->convertFieldElementToColumnAnnotation($idElement)) |
|
149 | 28 | ->withIdAnnotation(new Annotation\Id()) |
|
150 | 28 | ->withVersionAnnotation( |
|
151 | 28 | isset($idElement['version']) && $this->evaluateBoolean($idElement['version']) |
|
152 | ? new Annotation\Version() |
||
153 | 28 | : null |
|
154 | ) |
||
155 | 28 | ->withGeneratedValueAnnotation( |
|
156 | 28 | isset($idElement->generator) |
|
157 | 27 | ? $this->convertGeneratorElementToGeneratedValueAnnotation($idElement->generator) |
|
158 | 28 | : null |
|
159 | ) |
||
160 | 28 | ->withSequenceGeneratorAnnotation( |
|
161 | 28 | isset($idElement->{'sequence-generator'}) |
|
162 | 3 | ? $this->convertSequenceGeneratorElementToSequenceGeneratorAnnotation($idElement->{'sequence-generator'}) |
|
163 | 28 | : null |
|
164 | ) |
||
165 | 28 | ->withCustomIdGeneratorAnnotation( |
|
166 | 28 | isset($idElement->{'custom-id-generator'}) |
|
167 | 2 | ? $this->convertCustomIdGeneratorElementToCustomIdGeneratorAnnotation($idElement->{'custom-id-generator'}) |
|
168 | 28 | : null |
|
169 | ); |
||
170 | |||
171 | 28 | $classMetadata->addProperty($propertyBuilder->build()); |
|
172 | } |
||
173 | |||
174 | // Evaluate <one-to-one ...> mappings |
||
175 | 34 | if (isset($xmlRoot->{'one-to-one'})) { |
|
176 | 7 | foreach ($xmlRoot->{'one-to-one'} as $oneToOneElement) { |
|
177 | 7 | $fieldName = (string) $oneToOneElement['field']; |
|
178 | |||
179 | $propertyBuilder |
||
180 | 7 | ->withFieldName($fieldName) |
|
181 | 7 | ->withOneToOneAnnotation($this->convertOneToOneElementToOneToOneAnnotation($oneToOneElement)) |
|
182 | 7 | ->withIdAnnotation(isset($associationIds[$fieldName]) ? new Annotation\Id() : null) |
|
183 | 7 | ->withVersionAnnotation(null) |
|
184 | 7 | ->withCacheAnnotation( |
|
185 | 7 | isset($oneToOneElement->cache) |
|
186 | ? $this->convertCacheElementToCacheAnnotation($oneToOneElement->cache) |
||
187 | 7 | : null |
|
188 | ) |
||
189 | 7 | ->withJoinColumnAnnotation( |
|
190 | 7 | isset($oneToOneElement->{'join-column'}) |
|
191 | 5 | ? $this->convertJoinColumnElementToJoinColumnAnnotation($oneToOneElement->{'join-column'}) |
|
192 | 7 | : null |
|
193 | ) |
||
194 | 7 | ->withJoinColumnsAnnotation( |
|
195 | 7 | isset($oneToOneElement->{'join-columns'}) |
|
196 | ? $this->convertJoinColumnsElementToJoinColumnsAnnotation($oneToOneElement->{'join-columns'}) |
||
197 | 7 | : null |
|
198 | ); |
||
199 | |||
200 | 7 | $classMetadata->addProperty($propertyBuilder->build()); |
|
201 | } |
||
202 | } |
||
203 | |||
204 | // Evaluate <many-to-one ...> mappings |
||
205 | 34 | if (isset($xmlRoot->{'many-to-one'})) { |
|
206 | 8 | foreach ($xmlRoot->{'many-to-one'} as $manyToOneElement) { |
|
207 | 8 | $fieldName = (string) $manyToOneElement['field']; |
|
208 | |||
209 | $propertyBuilder |
||
210 | 8 | ->withFieldName($fieldName) |
|
211 | 8 | ->withManyToOneAnnotation($this->convertManyToOneElementToManyToOneAnnotation($manyToOneElement)) |
|
212 | 8 | ->withIdAnnotation(isset($associationIds[$fieldName]) ? new Annotation\Id() : null) |
|
213 | 8 | ->withVersionAnnotation(null) |
|
214 | 8 | ->withCacheAnnotation( |
|
215 | 8 | isset($manyToOneElement->cache) |
|
216 | 1 | ? $this->convertCacheElementToCacheAnnotation($manyToOneElement->cache) |
|
217 | 8 | : null |
|
218 | ) |
||
219 | 8 | ->withJoinColumnAnnotation( |
|
220 | 8 | isset($manyToOneElement->{'join-column'}) |
|
221 | 7 | ? $this->convertJoinColumnElementToJoinColumnAnnotation($manyToOneElement->{'join-column'}) |
|
222 | 8 | : null |
|
223 | ) |
||
224 | 8 | ->withJoinColumnsAnnotation( |
|
225 | 8 | isset($manyToOneElement->{'join-columns'}) |
|
226 | 1 | ? $this->convertJoinColumnsElementToJoinColumnsAnnotation($manyToOneElement->{'join-columns'}) |
|
227 | 8 | : null |
|
228 | ); |
||
229 | |||
230 | 8 | $classMetadata->addProperty($propertyBuilder->build()); |
|
231 | } |
||
232 | } |
||
233 | |||
234 | // Evaluate <one-to-many ...> mappings |
||
235 | 33 | if (isset($xmlRoot->{'one-to-many'})) { |
|
236 | 9 | foreach ($xmlRoot->{'one-to-many'} as $oneToManyElement) { |
|
237 | 9 | $fieldName = (string) $oneToManyElement['field']; |
|
238 | |||
239 | $propertyBuilder |
||
240 | 9 | ->withFieldName($fieldName) |
|
241 | 9 | ->withOneToManyAnnotation($this->convertOneToManyElementToOneToManyAnnotation($oneToManyElement)) |
|
242 | 9 | ->withIdAnnotation(isset($associationIds[$fieldName]) ? new Annotation\Id() : null) |
|
243 | 9 | ->withVersionAnnotation(null) |
|
244 | 9 | ->withCacheAnnotation( |
|
245 | 9 | isset($oneToManyElement->cache) |
|
246 | 1 | ? $this->convertCacheElementToCacheAnnotation($oneToManyElement->cache) |
|
247 | 9 | : null |
|
248 | ) |
||
249 | 9 | ->withOrderByAnnotation( |
|
250 | 9 | isset($oneToManyElement->{'order-by'}) |
|
251 | 5 | ? $this->convertOrderByElementToOrderByAnnotation($oneToManyElement->{'order-by'}) |
|
252 | 9 | : null |
|
253 | ); |
||
254 | |||
255 | 9 | $classMetadata->addProperty($propertyBuilder->build()); |
|
256 | } |
||
257 | } |
||
258 | |||
259 | // Evaluate <many-to-many ...> mappings |
||
260 | 33 | if (isset($xmlRoot->{'many-to-many'})) { |
|
261 | 14 | foreach ($xmlRoot->{'many-to-many'} as $manyToManyElement) { |
|
262 | 14 | $fieldName = (string) $manyToManyElement['field']; |
|
263 | |||
264 | $propertyBuilder |
||
265 | 14 | ->withFieldName($fieldName) |
|
266 | 14 | ->withManyToManyAnnotation($this->convertManyToManyElementToManyToManyAnnotation($manyToManyElement)) |
|
267 | 14 | ->withIdAnnotation(isset($associationIds[$fieldName]) ? new Annotation\Id() : null) |
|
268 | 14 | ->withVersionAnnotation(null) |
|
269 | 14 | ->withCacheAnnotation( |
|
270 | 14 | isset($manyToManyElement->cache) |
|
271 | ? $this->convertCacheElementToCacheAnnotation($manyToManyElement->cache) |
||
272 | 14 | : null |
|
273 | ) |
||
274 | 14 | ->withJoinTableAnnotation( |
|
275 | 14 | isset($manyToManyElement->{'join-table'}) |
|
276 | 8 | ? $this->convertJoinTableElementToJoinTableAnnotation($manyToManyElement->{'join-table'}) |
|
277 | 14 | : null |
|
278 | ) |
||
279 | 14 | ->withOrderByAnnotation( |
|
280 | 14 | isset($manyToManyElement->{'order-by'}) |
|
281 | 1 | ? $this->convertOrderByElementToOrderByAnnotation($manyToManyElement->{'order-by'}) |
|
282 | 14 | : null |
|
283 | ); |
||
284 | |||
285 | 14 | $classMetadata->addProperty($propertyBuilder->build()); |
|
286 | } |
||
287 | } |
||
288 | |||
289 | // Evaluate association-overrides |
||
290 | 33 | if (isset($xmlRoot->{'attribute-overrides'})) { |
|
291 | 2 | $fieldBuilder = new Builder\FieldMetadataBuilder($metadataBuildingContext); |
|
292 | |||
293 | $fieldBuilder |
||
294 | 2 | ->withComponentMetadata($classMetadata); |
|
295 | |||
296 | 2 | foreach ($xmlRoot->{'attribute-overrides'}->{'attribute-override'} as $overrideElement) { |
|
297 | 2 | $fieldName = (string) $overrideElement['name']; |
|
298 | 2 | $property = $classMetadata->getProperty($fieldName); |
|
299 | |||
300 | 2 | if (! $property) { |
|
301 | throw Mapping\MappingException::invalidOverrideFieldName($classMetadata->getClassName(), $fieldName); |
||
302 | } |
||
303 | |||
304 | 2 | foreach ($overrideElement->field as $fieldElement) { |
|
305 | 2 | $versionAnnotation = isset($fieldElement['version']) && $this->evaluateBoolean($fieldElement['version']) |
|
306 | ? new Annotation\Version() |
||
307 | 2 | : null; |
|
308 | |||
309 | $fieldBuilder |
||
310 | 2 | ->withFieldName($fieldName) |
|
311 | 2 | ->withColumnAnnotation($this->convertFieldElementToColumnAnnotation($fieldElement)) |
|
312 | 2 | ->withIdAnnotation(null) |
|
313 | 2 | ->withVersionAnnotation($versionAnnotation); |
|
314 | |||
315 | 2 | $fieldMetadata = $fieldBuilder->build(); |
|
316 | 2 | $columnName = $fieldMetadata->getColumnName(); |
|
317 | |||
318 | // Prevent column duplication |
||
319 | 2 | if ($classMetadata->checkPropertyDuplication($columnName)) { |
|
320 | throw Mapping\MappingException::duplicateColumnName($classMetadata->getClassName(), $columnName); |
||
321 | } |
||
322 | |||
323 | 2 | $classMetadata->setPropertyOverride($fieldMetadata); |
|
324 | } |
||
325 | } |
||
326 | } |
||
327 | |||
328 | // Evaluate association-overrides |
||
329 | 33 | if (isset($xmlRoot->{'association-overrides'})) { |
|
330 | 4 | foreach ($xmlRoot->{'association-overrides'}->{'association-override'} as $overrideElement) { |
|
331 | 4 | $fieldName = (string) $overrideElement['name']; |
|
332 | 4 | $property = $classMetadata->getProperty($fieldName); |
|
333 | |||
334 | 4 | if (! $property) { |
|
335 | throw Mapping\MappingException::invalidOverrideFieldName($classMetadata->getClassName(), $fieldName); |
||
336 | } |
||
337 | |||
338 | 4 | $override = clone $property; |
|
339 | |||
340 | // Check for join-columns |
||
341 | 4 | if (isset($overrideElement->{'join-columns'})) { |
|
342 | 2 | $joinColumnBuilder = new Builder\JoinColumnMetadataBuilder($metadataBuildingContext); |
|
343 | |||
344 | $joinColumnBuilder |
||
345 | 2 | ->withComponentMetadata($classMetadata) |
|
346 | 2 | ->withFieldName($override->getName()); |
|
347 | |||
348 | 2 | $joinColumns = []; |
|
349 | |||
350 | 2 | foreach ($overrideElement->{'join-columns'}->{'join-column'} as $joinColumnElement) { |
|
351 | 2 | $joinColumnBuilder->withJoinColumnAnnotation( |
|
352 | 2 | $this->convertJoinColumnElementToJoinColumnAnnotation($joinColumnElement) |
|
353 | ); |
||
354 | |||
355 | 2 | $joinColumnMetadata = $joinColumnBuilder->build(); |
|
356 | 2 | $columnName = $joinColumnMetadata->getColumnName(); |
|
357 | |||
358 | // @todo guilhermeblanco Open an issue to discuss making this scenario impossible. |
||
359 | //if ($metadata->checkPropertyDuplication($columnName)) { |
||
360 | // throw Mapping\MappingException::duplicateColumnName($metadata->getClassName(), $columnName); |
||
361 | //} |
||
362 | |||
363 | 2 | $joinColumns[] = $joinColumnMetadata; |
|
364 | } |
||
365 | |||
366 | 2 | $override->setJoinColumns($joinColumns); |
|
367 | } |
||
368 | |||
369 | // Check for join-table |
||
370 | 4 | if ($overrideElement->{'join-table'}) { |
|
371 | 2 | $joinTableElement = $overrideElement->{'join-table'}; |
|
372 | 2 | $joinTableAnnotation = $this->convertJoinTableElementToJoinTableAnnotation($joinTableElement); |
|
373 | 2 | $joinTableBuilder = new Builder\JoinTableMetadataBuilder($metadataBuildingContext); |
|
374 | |||
375 | $joinTableBuilder |
||
376 | 2 | ->withComponentMetadata($classMetadata) |
|
377 | 2 | ->withFieldName($property->getName()) |
|
378 | 2 | ->withTargetEntity($property->getTargetEntity()) |
|
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||
379 | 2 | ->withJoinTableAnnotation($joinTableAnnotation); |
|
380 | |||
381 | 2 | $override->setJoinTable($joinTableBuilder->build()); |
|
382 | } |
||
383 | |||
384 | // Check for inversed-by |
||
385 | 4 | if (isset($overrideElement->{'inversed-by'})) { |
|
386 | 1 | $override->setInversedBy((string) $overrideElement->{'inversed-by'}['name']); |
|
387 | } |
||
388 | |||
389 | // Check for fetch |
||
390 | 4 | if (isset($overrideElement['fetch'])) { |
|
391 | 1 | $override->setFetchMode( |
|
392 | 1 | constant('Doctrine\ORM\Mapping\FetchMode::' . (string) $overrideElement['fetch']) |
|
393 | ); |
||
394 | } |
||
395 | |||
396 | 4 | $classMetadata->setPropertyOverride($override); |
|
397 | } |
||
398 | } |
||
399 | |||
400 | // Evaluate <lifecycle-callbacks...> |
||
401 | 33 | if (isset($xmlRoot->{'lifecycle-callbacks'})) { |
|
402 | 3 | foreach ($xmlRoot->{'lifecycle-callbacks'}->{'lifecycle-callback'} as $lifecycleCallback) { |
|
403 | 3 | $eventName = constant(Events::class . '::' . (string) $lifecycleCallback['type']); |
|
404 | 3 | $methodName = (string) $lifecycleCallback['method']; |
|
405 | |||
406 | 3 | $classMetadata->addLifecycleCallback($eventName, $methodName); |
|
407 | } |
||
408 | } |
||
409 | |||
410 | // Evaluate entity listener |
||
411 | 33 | if (isset($xmlRoot->{'entity-listeners'})) { |
|
412 | 2 | foreach ($xmlRoot->{'entity-listeners'}->{'entity-listener'} as $listenerElement) { |
|
413 | 2 | $listenerClassName = (string) $listenerElement['class']; |
|
414 | |||
415 | 2 | if (! class_exists($listenerClassName)) { |
|
416 | throw Mapping\MappingException::entityListenerClassNotFound( |
||
417 | $listenerClassName, |
||
418 | $classMetadata->getClassName() |
||
419 | ); |
||
420 | } |
||
421 | |||
422 | 2 | foreach ($listenerElement as $callbackElement) { |
|
423 | 2 | $eventName = (string) $callbackElement['type']; |
|
424 | 2 | $methodName = (string) $callbackElement['method']; |
|
425 | |||
426 | 2 | $classMetadata->addEntityListener($eventName, $listenerClassName, $methodName); |
|
427 | } |
||
428 | } |
||
429 | } |
||
430 | |||
431 | 33 | return $classMetadata; |
|
432 | } |
||
433 | |||
434 | /** |
||
435 | * {@inheritDoc} |
||
436 | */ |
||
437 | 36 | protected function loadMappingFile($file) |
|
438 | { |
||
439 | 36 | $result = []; |
|
440 | // Note: we do not use `simplexml_load_file()` because of https://bugs.php.net/bug.php?id=62577 |
||
441 | 36 | $xmlElement = simplexml_load_string(file_get_contents($file)); |
|
442 | |||
443 | 36 | if (isset($xmlElement->entity)) { |
|
444 | 35 | foreach ($xmlElement->entity as $entityElement) { |
|
445 | 35 | $entityName = (string) $entityElement['name']; |
|
446 | 35 | $result[$entityName] = $entityElement; |
|
447 | } |
||
448 | 6 | } elseif (isset($xmlElement->{'mapped-superclass'})) { |
|
449 | 5 | foreach ($xmlElement->{'mapped-superclass'} as $mappedSuperClass) { |
|
450 | 5 | $className = (string) $mappedSuperClass['name']; |
|
451 | 5 | $result[$className] = $mappedSuperClass; |
|
452 | } |
||
453 | 1 | } elseif (isset($xmlElement->embeddable)) { |
|
454 | foreach ($xmlElement->embeddable as $embeddableElement) { |
||
455 | $embeddableName = (string) $embeddableElement['name']; |
||
456 | $result[$embeddableName] = $embeddableElement; |
||
457 | } |
||
458 | } |
||
459 | |||
460 | 36 | return $result; |
|
461 | } |
||
462 | |||
463 | 34 | private function convertEntityElementToEntityAnnotation( |
|
464 | SimpleXMLElement $entityElement |
||
465 | ) : Annotation\Entity { |
||
466 | 34 | $entityAnnotation = new Annotation\Entity(); |
|
467 | |||
468 | 34 | if (isset($entityElement['repository-class'])) { |
|
469 | $entityAnnotation->repositoryClass = (string) $entityElement['repository-class']; |
||
470 | } |
||
471 | |||
472 | 34 | if (isset($entityElement['read-only'])) { |
|
473 | $entityAnnotation->readOnly = $this->evaluateBoolean($entityElement['read-only']); |
||
474 | } |
||
475 | |||
476 | 34 | return $entityAnnotation; |
|
477 | } |
||
478 | |||
479 | 5 | private function convertMappedSuperclassElementToMappedSuperclassAnnotation( |
|
480 | SimpleXMLElement $mappedSuperclassElement |
||
481 | ) : Annotation\MappedSuperclass { |
||
482 | 5 | $mappedSuperclassAnnotation = new Annotation\MappedSuperclass(); |
|
483 | |||
484 | 5 | if (isset($mappedSuperclassElement['repository-class'])) { |
|
485 | 1 | $mappedSuperclassAnnotation->repositoryClass = (string) $mappedSuperclassElement['repository-class']; |
|
486 | } |
||
487 | |||
488 | 5 | return $mappedSuperclassAnnotation; |
|
489 | } |
||
490 | |||
491 | 34 | private function convertTableElementToTableAnnotation( |
|
492 | SimpleXMLElement $tableElement |
||
493 | ) : Annotation\Table { |
||
494 | 34 | $tableAnnotation = new Annotation\Table(); |
|
495 | |||
496 | // Evaluate <entity...> attributes |
||
497 | 34 | if (isset($tableElement['table'])) { |
|
498 | 12 | $tableAnnotation->name = (string) $tableElement['table']; |
|
499 | } |
||
500 | |||
501 | 34 | if (isset($tableElement['schema'])) { |
|
502 | 2 | $tableAnnotation->schema = (string) $tableElement['schema']; |
|
503 | } |
||
504 | |||
505 | // Evaluate <indexes...> |
||
506 | 34 | if (isset($tableElement->indexes)) { |
|
507 | 4 | $indexes = []; |
|
508 | |||
509 | /** @var SimpleXMLElement $indexElement */ |
||
510 | 4 | foreach ($tableElement->indexes->children() as $indexElement) { |
|
511 | 4 | $indexes[] = $this->convertIndexElementToIndexAnnotation($indexElement); |
|
512 | } |
||
513 | |||
514 | 4 | $tableAnnotation->indexes = $indexes; |
|
515 | } |
||
516 | |||
517 | // Evaluate <unique-constraints..> |
||
518 | 34 | if (isset($tableElement->{'unique-constraints'})) { |
|
519 | 3 | $uniqueConstraints = []; |
|
520 | |||
521 | 3 | foreach ($tableElement->{'unique-constraints'}->children() as $uniqueConstraintElement) { |
|
522 | 3 | $uniqueConstraints[] = $this->convertUniqueConstraintElementToUniqueConstraintAnnotation($uniqueConstraintElement); |
|
523 | } |
||
524 | |||
525 | 3 | $tableAnnotation->uniqueConstraints = $uniqueConstraints; |
|
526 | } |
||
527 | |||
528 | 34 | if (isset($tableElement->options)) { |
|
529 | 3 | $tableAnnotation->options = $this->parseOptions($tableElement->options->children()); |
|
530 | } |
||
531 | |||
532 | 34 | return $tableAnnotation; |
|
533 | } |
||
534 | |||
535 | 4 | private function convertIndexElementToIndexAnnotation( |
|
536 | SimpleXMLElement $indexElement |
||
537 | ) : Annotation\Index { |
||
538 | 4 | $indexAnnotation = new Annotation\Index(); |
|
539 | |||
540 | 4 | $indexAnnotation->columns = explode(',', (string) $indexElement['columns']); |
|
541 | 4 | $indexAnnotation->options = isset($indexElement->options) ? $this->parseOptions($indexElement->options->children()) : []; |
|
542 | 4 | $indexAnnotation->flags = isset($indexElement['flags']) ? explode(',', (string) $indexElement['flags']) : []; |
|
543 | |||
544 | 4 | if (isset($indexElement['name'])) { |
|
545 | 3 | $indexAnnotation->name = (string) $indexElement['name']; |
|
546 | } |
||
547 | |||
548 | 4 | if (isset($indexElement['unique'])) { |
|
549 | $indexAnnotation->unique = $this->evaluateBoolean($indexElement['unique']); |
||
550 | } |
||
551 | |||
552 | 4 | return $indexAnnotation; |
|
553 | } |
||
554 | |||
555 | 3 | private function convertUniqueConstraintElementToUniqueConstraintAnnotation( |
|
556 | SimpleXMLElement $uniqueConstraintElement |
||
557 | ) : Annotation\UniqueConstraint { |
||
558 | 3 | $uniqueConstraintAnnotation = new Annotation\UniqueConstraint(); |
|
559 | |||
560 | 3 | $uniqueConstraintAnnotation->columns = explode(',', (string) $uniqueConstraintElement['columns']); |
|
561 | 3 | $uniqueConstraintAnnotation->options = isset($uniqueConstraintElement->options) ? $this->parseOptions($uniqueConstraintElement->options->children()) : []; |
|
562 | 3 | $uniqueConstraintAnnotation->flags = isset($uniqueConstraintElement['flags']) ? explode(',', (string) $uniqueConstraintElement['flags']) : []; |
|
563 | |||
564 | 3 | if (isset($uniqueConstraintElement['name'])) { |
|
565 | 3 | $uniqueConstraintAnnotation->name = (string) $uniqueConstraintElement['name']; |
|
566 | } |
||
567 | |||
568 | 3 | return $uniqueConstraintAnnotation; |
|
569 | } |
||
570 | |||
571 | 10 | private function convertInheritanceTypeElementToInheritanceTypeAnnotation( |
|
572 | SimpleXMLElement $inheritanceTypeElement |
||
573 | ) : Annotation\InheritanceType { |
||
574 | 10 | $inheritanceTypeAnnotation = new Annotation\InheritanceType(); |
|
575 | |||
576 | 10 | $inheritanceTypeAnnotation->value = strtoupper((string) $inheritanceTypeElement['inheritance-type']); |
|
577 | |||
578 | 10 | return $inheritanceTypeAnnotation; |
|
579 | } |
||
580 | |||
581 | private function convertChangeTrackingPolicyElementToChangeTrackingPolicyAnnotation( |
||
582 | SimpleXMLElement $changeTrackingPolicyElement |
||
583 | ) : Annotation\ChangeTrackingPolicy { |
||
584 | $changeTrackingPolicyAnnotation = new Annotation\ChangeTrackingPolicy(); |
||
585 | |||
586 | $changeTrackingPolicyAnnotation->value = strtoupper((string) $changeTrackingPolicyElement['change-tracking-policy']); |
||
587 | |||
588 | return $changeTrackingPolicyAnnotation; |
||
589 | } |
||
590 | |||
591 | 8 | private function convertDiscrimininatorColumnElementToDiscriminatorColumnAnnotation( |
|
592 | SimpleXMLElement $discriminatorColumnElement |
||
593 | ) : Annotation\DiscriminatorColumn { |
||
594 | 8 | $discriminatorColumnAnnotation = new Annotation\DiscriminatorColumn(); |
|
595 | |||
596 | 8 | $discriminatorColumnAnnotation->type = (string) ($discriminatorColumnElement['type'] ?? 'string'); |
|
597 | 8 | $discriminatorColumnAnnotation->name = (string) $discriminatorColumnElement['name']; |
|
598 | |||
599 | 8 | if (isset($discriminatorColumnElement['column-definition'])) { |
|
600 | 1 | $discriminatorColumnAnnotation->columnDefinition = (string) $discriminatorColumnElement['column-definition']; |
|
601 | } |
||
602 | |||
603 | 8 | if (isset($discriminatorColumnElement['length'])) { |
|
604 | 3 | $discriminatorColumnAnnotation->length = (int) $discriminatorColumnElement['length']; |
|
605 | } |
||
606 | |||
607 | 8 | return $discriminatorColumnAnnotation; |
|
608 | } |
||
609 | |||
610 | 10 | private function convertDiscriminatorMapElementToDiscriminatorMapAnnotation( |
|
611 | SimpleXMLElement $discriminatorMapElement |
||
612 | ) : Annotation\DiscriminatorMap { |
||
613 | 10 | $discriminatorMapAnnotation = new Annotation\DiscriminatorMap(); |
|
614 | 10 | $discriminatorMap = []; |
|
615 | |||
616 | 10 | foreach ($discriminatorMapElement->{'discriminator-mapping'} as $discriminatorMapElement) { |
|
617 | 10 | $discriminatorMap[(string) $discriminatorMapElement['value']] = (string) $discriminatorMapElement['class']; |
|
618 | } |
||
619 | |||
620 | 10 | $discriminatorMapAnnotation->value = $discriminatorMap; |
|
621 | |||
622 | 10 | return $discriminatorMapAnnotation; |
|
623 | } |
||
624 | |||
625 | 2 | private function convertCacheElementToCacheAnnotation( |
|
626 | SimpleXMLElement $cacheElement |
||
627 | ) : Annotation\Cache { |
||
628 | 2 | $cacheAnnotation = new Annotation\Cache(); |
|
629 | |||
630 | 2 | if (isset($cacheElement['region'])) { |
|
631 | $cacheAnnotation->region = (string) $cacheElement['region']; |
||
632 | } |
||
633 | |||
634 | 2 | if (isset($cacheElement['usage'])) { |
|
635 | 2 | $cacheAnnotation->usage = strtoupper((string) $cacheElement['usage']); |
|
636 | } |
||
637 | |||
638 | 2 | return $cacheAnnotation; |
|
639 | } |
||
640 | |||
641 | 30 | private function convertFieldElementToColumnAnnotation( |
|
642 | SimpleXMLElement $fieldElement |
||
643 | ) : Annotation\Column { |
||
644 | 30 | $columnAnnotation = new Annotation\Column(); |
|
645 | |||
646 | 30 | $columnAnnotation->type = isset($fieldElement['type']) ? (string) $fieldElement['type'] : 'string'; |
|
647 | |||
648 | 30 | if (isset($fieldElement['column'])) { |
|
649 | 20 | $columnAnnotation->name = (string) $fieldElement['column']; |
|
650 | } |
||
651 | |||
652 | 30 | if (isset($fieldElement['length'])) { |
|
653 | 6 | $columnAnnotation->length = (int) $fieldElement['length']; |
|
654 | } |
||
655 | |||
656 | 30 | if (isset($fieldElement['precision'])) { |
|
657 | 1 | $columnAnnotation->precision = (int) $fieldElement['precision']; |
|
658 | } |
||
659 | |||
660 | 30 | if (isset($fieldElement['scale'])) { |
|
661 | 1 | $columnAnnotation->scale = (int) $fieldElement['scale']; |
|
662 | } |
||
663 | |||
664 | 30 | if (isset($fieldElement['unique'])) { |
|
665 | 7 | $columnAnnotation->unique = $this->evaluateBoolean($fieldElement['unique']); |
|
666 | } |
||
667 | |||
668 | 30 | if (isset($fieldElement['nullable'])) { |
|
669 | 7 | $columnAnnotation->nullable = $this->evaluateBoolean($fieldElement['nullable']); |
|
670 | } |
||
671 | |||
672 | 30 | if (isset($fieldElement['column-definition'])) { |
|
673 | 4 | $columnAnnotation->columnDefinition = (string) $fieldElement['column-definition']; |
|
674 | } |
||
675 | |||
676 | 30 | if (isset($fieldElement->options)) { |
|
677 | 3 | $columnAnnotation->options = $this->parseOptions($fieldElement->options->children()); |
|
678 | } |
||
679 | |||
680 | 30 | return $columnAnnotation; |
|
681 | } |
||
682 | |||
683 | private function convertEmbeddedElementToEmbeddedAnnotation( |
||
684 | SimpleXMLElement $embeddedElement |
||
685 | ) : Annotation\Embedded { |
||
686 | $embeddedAnnotation = new Annotation\Embedded(); |
||
687 | |||
688 | $embeddedAnnotation->class = (string) $embeddedElement['class']; |
||
689 | |||
690 | if (isset($embeddedElement['column-prefix'])) { |
||
691 | $embeddedAnnotation->columnPrefix = (string) $embeddedElement['column-prefix']; |
||
692 | } |
||
693 | |||
694 | return $embeddedAnnotation; |
||
695 | } |
||
696 | |||
697 | 7 | private function convertOneToOneElementToOneToOneAnnotation( |
|
698 | SimpleXMLElement $oneToOneElement |
||
699 | ) : Annotation\OneToOne { |
||
700 | 7 | $oneToOneAnnotation = new Annotation\OneToOne(); |
|
701 | |||
702 | 7 | $oneToOneAnnotation->targetEntity = (string) $oneToOneElement['target-entity']; |
|
703 | |||
704 | 7 | if (isset($oneToOneElement['mapped-by'])) { |
|
705 | 3 | $oneToOneAnnotation->mappedBy = (string) $oneToOneElement['mapped-by']; |
|
706 | } |
||
707 | |||
708 | 7 | if (isset($oneToOneElement['inversed-by'])) { |
|
709 | 4 | $oneToOneAnnotation->inversedBy = (string) $oneToOneElement['inversed-by']; |
|
710 | } |
||
711 | |||
712 | 7 | if (isset($oneToOneElement['orphan-removal'])) { |
|
713 | $oneToOneAnnotation->orphanRemoval = $this->evaluateBoolean($oneToOneElement['orphan-removal']); |
||
714 | } |
||
715 | |||
716 | 7 | if (isset($oneToOneElement['fetch'])) { |
|
717 | 3 | $oneToOneAnnotation->fetch = (string) $oneToOneElement['fetch']; |
|
718 | } |
||
719 | |||
720 | 7 | if (isset($oneToOneElement->cascade)) { |
|
721 | 7 | $oneToOneAnnotation->cascade = $this->getCascadeMappings($oneToOneElement->cascade); |
|
722 | } |
||
723 | |||
724 | 7 | return $oneToOneAnnotation; |
|
725 | } |
||
726 | |||
727 | 8 | private function convertManyToOneElementToManyToOneAnnotation( |
|
728 | SimpleXMLElement $manyToOneElement |
||
729 | ) : Annotation\ManyToOne { |
||
730 | 8 | $manyToOneAnnotation = new Annotation\ManyToOne(); |
|
731 | |||
732 | 8 | $manyToOneAnnotation->targetEntity = (string) $manyToOneElement['target-entity']; |
|
733 | |||
734 | 8 | if (isset($manyToOneElement['inversed-by'])) { |
|
735 | 2 | $manyToOneAnnotation->inversedBy = (string) $manyToOneElement['inversed-by']; |
|
736 | } |
||
737 | |||
738 | 8 | if (isset($manyToOneElement['fetch'])) { |
|
739 | $manyToOneAnnotation->fetch = (string) $manyToOneElement['fetch']; |
||
740 | } |
||
741 | |||
742 | 8 | if (isset($manyToOneElement->cascade)) { |
|
743 | 4 | $manyToOneAnnotation->cascade = $this->getCascadeMappings($manyToOneElement->cascade); |
|
744 | } |
||
745 | |||
746 | 8 | return $manyToOneAnnotation; |
|
747 | } |
||
748 | |||
749 | 9 | private function convertOneToManyElementToOneToManyAnnotation( |
|
750 | SimpleXMLElement $oneToManyElement |
||
751 | ) : Annotation\OneToMany { |
||
752 | 9 | $oneToManyAnnotation = new Annotation\OneToMany(); |
|
753 | |||
754 | 9 | $oneToManyAnnotation->targetEntity = (string) $oneToManyElement['target-entity']; |
|
755 | |||
756 | 9 | if (isset($oneToManyElement['mapped-by'])) { |
|
757 | 9 | $oneToManyAnnotation->mappedBy = (string) $oneToManyElement['mapped-by']; |
|
758 | } |
||
759 | |||
760 | 9 | if (isset($oneToManyElement['fetch'])) { |
|
761 | $oneToManyAnnotation->fetch = (string) $oneToManyElement['fetch']; |
||
762 | } |
||
763 | |||
764 | 9 | if (isset($oneToManyElement->cascade)) { |
|
765 | 6 | $oneToManyAnnotation->cascade = $this->getCascadeMappings($oneToManyElement->cascade); |
|
766 | } |
||
767 | |||
768 | 9 | if (isset($oneToManyElement['orphan-removal'])) { |
|
769 | 3 | $oneToManyAnnotation->orphanRemoval = $this->evaluateBoolean($oneToManyElement['orphan-removal']); |
|
770 | } |
||
771 | |||
772 | 9 | if (isset($oneToManyElement['index-by'])) { |
|
773 | 3 | $oneToManyAnnotation->indexBy = (string) $oneToManyElement['index-by']; |
|
774 | 6 | } elseif (isset($oneToManyElement->{'index-by'})) { |
|
775 | throw new InvalidArgumentException('<index-by /> is not a valid tag'); |
||
776 | } |
||
777 | |||
778 | 9 | return $oneToManyAnnotation; |
|
779 | } |
||
780 | |||
781 | 14 | private function convertManyToManyElementToManyToManyAnnotation( |
|
782 | SimpleXMLElement $manyToManyElement |
||
783 | ) : Annotation\ManyToMany { |
||
784 | 14 | $manyToManyAnnotation = new Annotation\ManyToMany(); |
|
785 | |||
786 | 14 | $manyToManyAnnotation->targetEntity = (string) $manyToManyElement['target-entity']; |
|
787 | |||
788 | 14 | if (isset($manyToManyElement['mapped-by'])) { |
|
789 | 5 | $manyToManyAnnotation->mappedBy = (string) $manyToManyElement['mapped-by']; |
|
790 | } |
||
791 | |||
792 | 14 | if (isset($manyToManyElement['inversed-by'])) { |
|
793 | 6 | $manyToManyAnnotation->inversedBy = (string) $manyToManyElement['inversed-by']; |
|
794 | } |
||
795 | |||
796 | 14 | if (isset($manyToManyElement['fetch'])) { |
|
797 | 4 | $manyToManyAnnotation->fetch = (string) $manyToManyElement['fetch']; |
|
798 | } |
||
799 | |||
800 | 14 | if (isset($manyToManyElement->cascade)) { |
|
801 | 8 | $manyToManyAnnotation->cascade = $this->getCascadeMappings($manyToManyElement->cascade); |
|
802 | } |
||
803 | |||
804 | 14 | if (isset($manyToManyElement['orphan-removal'])) { |
|
805 | $manyToManyAnnotation->orphanRemoval = $this->evaluateBoolean($manyToManyElement['orphan-removal']); |
||
806 | } |
||
807 | |||
808 | 14 | if (isset($manyToManyElement['index-by'])) { |
|
809 | $manyToManyAnnotation->indexBy = (string) $manyToManyElement['index-by']; |
||
810 | 14 | } elseif (isset($manyToManyElement->{'index-by'})) { |
|
811 | throw new InvalidArgumentException('<index-by /> is not a valid tag'); |
||
812 | } |
||
813 | |||
814 | 14 | return $manyToManyAnnotation; |
|
815 | } |
||
816 | |||
817 | /** |
||
818 | * Constructs a JoinTable annotation based on the information |
||
819 | * found in the given SimpleXMLElement. |
||
820 | * |
||
821 | * @param SimpleXMLElement $joinTableElement The XML element. |
||
822 | */ |
||
823 | 8 | private function convertJoinTableElementToJoinTableAnnotation( |
|
824 | SimpleXMLElement $joinTableElement |
||
825 | ) : Annotation\JoinTable { |
||
826 | 8 | $joinTableAnnotation = new Annotation\JoinTable(); |
|
827 | |||
828 | 8 | if (isset($joinTableElement['name'])) { |
|
829 | 8 | $joinTableAnnotation->name = (string) $joinTableElement['name']; |
|
830 | } |
||
831 | |||
832 | 8 | if (isset($joinTableElement['schema'])) { |
|
833 | $joinTableAnnotation->schema = (string) $joinTableElement['schema']; |
||
834 | } |
||
835 | |||
836 | 8 | if (isset($joinTableElement->{'join-columns'})) { |
|
837 | 8 | $joinColumns = []; |
|
838 | |||
839 | 8 | foreach ($joinTableElement->{'join-columns'}->{'join-column'} as $joinColumnElement) { |
|
840 | 8 | $joinColumns[] = $this->convertJoinColumnElementToJoinColumnAnnotation($joinColumnElement); |
|
841 | } |
||
842 | |||
843 | 8 | $joinTableAnnotation->joinColumns = $joinColumns; |
|
844 | } |
||
845 | |||
846 | 8 | if (isset($joinTableElement->{'inverse-join-columns'})) { |
|
847 | 8 | $joinColumns = []; |
|
848 | |||
849 | 8 | foreach ($joinTableElement->{'inverse-join-columns'}->{'join-column'} as $joinColumnElement) { |
|
850 | 8 | $joinColumns[] = $this->convertJoinColumnElementToJoinColumnAnnotation($joinColumnElement); |
|
851 | } |
||
852 | |||
853 | 8 | $joinTableAnnotation->inverseJoinColumns = $joinColumns; |
|
854 | } |
||
855 | |||
856 | 8 | return $joinTableAnnotation; |
|
857 | } |
||
858 | |||
859 | 1 | private function convertJoinColumnsElementToJoinColumnsAnnotation( |
|
860 | SimpleXMLElement $joinColumnsElement |
||
861 | ) : Annotation\JoinColumns { |
||
862 | 1 | $joinColumnsAnnotation = new Annotation\JoinColumns(); |
|
863 | 1 | $joinColumns = []; |
|
864 | |||
865 | 1 | foreach ($joinColumnsElement->{'join-column'} as $joinColumnElement) { |
|
866 | 1 | $joinColumns[] = $this->convertJoinColumnElementToJoinColumnAnnotation($joinColumnElement); |
|
867 | } |
||
868 | |||
869 | 1 | $joinColumnsAnnotation->value = $joinColumns; |
|
870 | |||
871 | 1 | return $joinColumnsAnnotation; |
|
872 | } |
||
873 | |||
874 | /** |
||
875 | * Constructs a JoinColumn annotation based on the information |
||
876 | * found in the given SimpleXMLElement. |
||
877 | * |
||
878 | * @param SimpleXMLElement $joinColumnElement The XML element. |
||
879 | */ |
||
880 | 13 | private function convertJoinColumnElementToJoinColumnAnnotation( |
|
881 | SimpleXMLElement $joinColumnElement |
||
882 | ) : Annotation\JoinColumn { |
||
883 | 13 | $joinColumnAnnotation = new Annotation\JoinColumn(); |
|
884 | |||
885 | 13 | $joinColumnAnnotation->name = (string) $joinColumnElement['name']; |
|
886 | 13 | $joinColumnAnnotation->referencedColumnName = (string) $joinColumnElement['referenced-column-name']; |
|
887 | |||
888 | 13 | if (isset($joinColumnElement['column-definition'])) { |
|
889 | 3 | $joinColumnAnnotation->columnDefinition = (string) $joinColumnElement['column-definition']; |
|
890 | } |
||
891 | |||
892 | 13 | if (isset($joinColumnElement['field-name'])) { |
|
893 | $joinColumnAnnotation->fieldName = (string) $joinColumnElement['field-name']; |
||
894 | } |
||
895 | |||
896 | 13 | if (isset($joinColumnElement['nullable'])) { |
|
897 | 4 | $joinColumnAnnotation->nullable = $this->evaluateBoolean($joinColumnElement['nullable']); |
|
898 | } |
||
899 | |||
900 | 13 | if (isset($joinColumnElement['unique'])) { |
|
901 | 3 | $joinColumnAnnotation->unique = $this->evaluateBoolean($joinColumnElement['unique']); |
|
902 | } |
||
903 | |||
904 | 13 | if (isset($joinColumnElement['on-delete'])) { |
|
905 | 3 | $joinColumnAnnotation->onDelete = strtoupper((string) $joinColumnElement['on-delete']); |
|
906 | } |
||
907 | |||
908 | 13 | return $joinColumnAnnotation; |
|
909 | } |
||
910 | |||
911 | 6 | private function convertOrderByElementToOrderByAnnotation( |
|
912 | SimpleXMLElement $orderByElement |
||
913 | ) : Annotation\OrderBy { |
||
914 | 6 | $orderByAnnotation = new Annotation\OrderBy(); |
|
915 | 6 | $orderBy = []; |
|
916 | |||
917 | 6 | foreach ($orderByElement->{'order-by-field'} as $orderByField) { |
|
918 | 6 | $orderBy[(string) $orderByField['name']] = isset($orderByField['direction']) |
|
919 | 4 | ? (string) $orderByField['direction'] |
|
920 | 2 | : Criteria::ASC; |
|
921 | } |
||
922 | |||
923 | 6 | $orderByAnnotation->value = $orderBy; |
|
924 | |||
925 | 6 | return $orderByAnnotation; |
|
926 | } |
||
927 | |||
928 | 27 | private function convertGeneratorElementToGeneratedValueAnnotation( |
|
929 | SimpleXMLElement $generatorElement |
||
930 | ) : Annotation\GeneratedValue { |
||
931 | 27 | $generatedValueAnnotation = new Annotation\GeneratedValue(); |
|
932 | |||
933 | 27 | $generatedValueAnnotation->strategy = (string) ($generatorElement['strategy'] ?? 'AUTO'); |
|
934 | |||
935 | 27 | return $generatedValueAnnotation; |
|
936 | } |
||
937 | |||
938 | 3 | private function convertSequenceGeneratorElementToSequenceGeneratorAnnotation( |
|
939 | SimpleXMLElement $sequenceGeneratorElement |
||
940 | ) : Annotation\SequenceGenerator { |
||
941 | 3 | $sequenceGeneratorAnnotation = new Annotation\SequenceGenerator(); |
|
942 | |||
943 | 3 | $sequenceGeneratorAnnotation->sequenceName = (string) ($sequenceGeneratorElement['sequence-name'] ?? null); |
|
944 | 3 | $sequenceGeneratorAnnotation->allocationSize = (int) ($sequenceGeneratorElement['allocation-size'] ?? 1); |
|
945 | |||
946 | 3 | return $sequenceGeneratorAnnotation; |
|
947 | } |
||
948 | |||
949 | 2 | private function convertCustomIdGeneratorElementToCustomIdGeneratorAnnotation( |
|
950 | SimpleXMLElement $customIdGeneratorElement |
||
951 | ) : Annotation\CustomIdGenerator { |
||
952 | 2 | $customIdGeneratorAnnotation = new Annotation\CustomIdGenerator(); |
|
953 | |||
954 | 2 | $customIdGeneratorAnnotation->class = (string) $customIdGeneratorElement['class']; |
|
955 | 2 | $customIdGeneratorAnnotation->arguments = []; |
|
956 | |||
957 | 2 | return $customIdGeneratorAnnotation; |
|
958 | } |
||
959 | |||
960 | /** |
||
961 | * Gathers a list of cascade options found in the given cascade element. |
||
962 | * |
||
963 | * @param SimpleXMLElement $cascadeElement The cascade element. |
||
964 | * |
||
965 | * @return string[] The list of cascade options. |
||
966 | */ |
||
967 | 10 | private function getCascadeMappings(SimpleXMLElement $cascadeElement) : array |
|
968 | { |
||
969 | 10 | $cascades = []; |
|
970 | |||
971 | /** @var SimpleXMLElement $action */ |
||
972 | 10 | foreach ($cascadeElement->children() as $action) { |
|
973 | // According to the JPA specifications, XML uses "cascade-persist" |
||
974 | // instead of "persist". Here, both variations are supported |
||
975 | // because Annotation use "persist" and we want to make sure that |
||
976 | // this driver doesn't need to know anything about the supported |
||
977 | // cascading actions |
||
978 | 10 | $cascades[] = str_replace('cascade-', '', $action->getName()); |
|
979 | } |
||
980 | |||
981 | 10 | return $cascades; |
|
982 | } |
||
983 | |||
984 | /** |
||
985 | * @param mixed $element |
||
986 | * |
||
987 | * @return bool |
||
988 | */ |
||
989 | 9 | private function evaluateBoolean($element) |
|
990 | { |
||
991 | 9 | $flag = (string) $element; |
|
992 | |||
993 | 9 | return $flag === 'true' || $flag === '1'; |
|
994 | } |
||
995 | |||
996 | /** |
||
997 | * Parses (nested) option elements. |
||
998 | * |
||
999 | * @param SimpleXMLElement $options The XML element. |
||
1000 | * |
||
1001 | * @return mixed[] The options array. |
||
1002 | */ |
||
1003 | 4 | private function parseOptions(SimpleXMLElement $options) : array |
|
1004 | { |
||
1005 | 4 | $array = []; |
|
1006 | |||
1007 | /** @var SimpleXMLElement $option */ |
||
1008 | 4 | foreach ($options as $option) { |
|
1009 | 4 | if ($option->count()) { |
|
1010 | 3 | $value = $this->parseOptions($option->children()); |
|
1011 | } else { |
||
1012 | 4 | $value = (string) $option; |
|
1013 | } |
||
1014 | |||
1015 | 4 | $attributes = $option->attributes(); |
|
1016 | |||
1017 | 4 | if (isset($attributes->name)) { |
|
1018 | 4 | $nameAttribute = (string) $attributes->name; |
|
1019 | |||
1020 | 4 | $array[$nameAttribute] = in_array($nameAttribute, ['unsigned', 'fixed'], true) |
|
1021 | 3 | ? $this->evaluateBoolean($value) |
|
1022 | 4 | : $value; |
|
1023 | } else { |
||
1024 | $array[] = $value; |
||
1025 | } |
||
1026 | } |
||
1027 | |||
1028 | 4 | return $array; |
|
1029 | } |
||
1030 | } |
||
1031 |