Failed Conditions
Push — master ( 4bfa22...148895 )
by Guilherme
17:21 queued 09:56
created

convertManyToManyElementToManyToManyAnnotation()   B

Complexity

Conditions 8
Paths 96

Size

Total Lines 34
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 8.2964

Importance

Changes 0
Metric Value
cc 8
eloc 17
nc 96
nop 1
dl 0
loc 34
ccs 15
cts 18
cp 0.8333
crap 8.2964
rs 8.4444
c 0
b 0
f 0
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\DBAL\DBALException;
9
use Doctrine\ORM\Annotation;
10
use Doctrine\ORM\Events;
11
use Doctrine\ORM\Mapping;
12
use Doctrine\ORM\Mapping\Builder;
13
use InvalidArgumentException;
14
use SimpleXMLElement;
15
use function class_exists;
16
use function constant;
17
use function explode;
18
use function file_get_contents;
19
use function in_array;
20
use function simplexml_load_string;
21
use function sprintf;
22
use function str_replace;
23
use function strtoupper;
24
25
/**
26
 * XmlDriver is a metadata driver that enables mapping through XML files.
27
 */
28
class XmlDriver extends FileDriver
29
{
30
    public const DEFAULT_FILE_EXTENSION = '.dcm.xml';
31
32
    /**
33
     * {@inheritDoc}
34
     */
35 41
    public function __construct($locator, $fileExtension = self::DEFAULT_FILE_EXTENSION)
36
    {
37 41
        parent::__construct($locator, $fileExtension);
38 41
    }
39
40
    /**
41
     * {@inheritDoc}
42
     *
43
     * @throws DBALException
44
     */
45 36
    public function loadMetadataForClass(
46
        string $className,
47
        ?Mapping\ComponentMetadata $parent,
48
        Mapping\ClassMetadataBuildingContext $metadataBuildingContext
49
    ) : Mapping\ComponentMetadata {
50 36
        $metadata = new Mapping\ClassMetadata($className, $parent, $metadataBuildingContext);
51
52
        /** @var SimpleXMLElement $xmlRoot */
53 36
        $xmlRoot = $this->getElement($className);
54
55 34
        if ($xmlRoot->getName() === 'entity') {
56 34
            if (isset($xmlRoot['repository-class'])) {
57
                $metadata->setCustomRepositoryClassName((string) $xmlRoot['repository-class']);
58
            }
59
60 34
            if (isset($xmlRoot['read-only']) && $this->evaluateBoolean($xmlRoot['read-only'])) {
61 34
                $metadata->asReadOnly();
62
            }
63 5
        } elseif ($xmlRoot->getName() === 'mapped-superclass') {
64 5
            if (isset($xmlRoot['repository-class'])) {
65 1
                $metadata->setCustomRepositoryClassName((string) $xmlRoot['repository-class']);
66
            }
67
68 5
            $metadata->isMappedSuperclass = true;
69
        } elseif ($xmlRoot->getName() === 'embeddable') {
70
            $metadata->isEmbeddedClass = true;
71
        } else {
72
            throw Mapping\MappingException::classIsNotAValidEntityOrMappedSuperClass($className);
73
        }
74
75
        // Process table information
76 34
        $parent = $metadata->getParent();
77
78 34
        if ($parent && $parent->inheritanceType === Mapping\InheritanceType::SINGLE_TABLE) {
79
            // Handle the case where a middle mapped super class inherits from a single table inheritance tree.
80
            do {
81 2
                if (! $parent->isMappedSuperclass) {
82 2
                    $metadata->setTable($parent->table);
83
84 2
                    break;
85
                }
86
87
                $parent = $parent->getParent();
88 2
            } while ($parent !== null);
89
        } else {
90 34
            $tableAnnotation = new Annotation\Table();
91
92
            // Evaluate <entity...> attributes
93 34
            if (isset($xmlRoot['table'])) {
94 12
                $tableAnnotation->name = (string) $xmlRoot['table'];
95
            }
96
97 34
            if (isset($xmlRoot['schema'])) {
98 2
                $tableAnnotation->schema = (string) $xmlRoot['schema'];
99
            }
100
101
            // Evaluate <indexes...>
102 34
            if (isset($xmlRoot->indexes)) {
103 4
                $tableAnnotation->indexes = $this->parseIndexes($xmlRoot->indexes->children());
104
            }
105
106
            // Evaluate <unique-constraints..>
107 34
            if (isset($xmlRoot->{'unique-constraints'})) {
108 3
                $tableAnnotation->uniqueConstraints = $this->parseUniqueConstraints($xmlRoot->{'unique-constraints'}->children());
109
            }
110
111 34
            if (isset($xmlRoot->options)) {
112 3
                $tableAnnotation->options = $this->parseOptions($xmlRoot->options->children());
113
            }
114
115 34
            $tableBuilder = new Builder\TableMetadataBuilder($metadataBuildingContext);
116
117
            $tableBuilder
118 34
                ->withEntityClassMetadata($metadata)
119 34
                ->withTableAnnotation($tableAnnotation);
120
121 34
            $metadata->setTable($tableBuilder->build());
122
        }
123
124
        // Evaluate second level cache
125 34
        if (isset($xmlRoot->cache)) {
126 2
            $cacheBuilder = new Builder\CacheMetadataBuilder($metadataBuildingContext);
127
128
            $cacheBuilder
129 2
                ->withComponentMetadata($metadata)
130 2
                ->withCacheAnnotation($this->convertCacheElementToCacheAnnotation($xmlRoot->cache));
131
132 2
            $metadata->setCache($cacheBuilder->build());
133
        }
134
135 34
        if (isset($xmlRoot['inheritance-type'])) {
136 10
            $inheritanceType = strtoupper((string) $xmlRoot['inheritance-type']);
137
138 10
            $metadata->setInheritanceType(
139 10
                constant(sprintf('%s::%s', Mapping\InheritanceType::class, $inheritanceType))
140
            );
141
142 10
            if ($metadata->inheritanceType !== Mapping\InheritanceType::NONE) {
143 10
                $discriminatorColumnBuilder = new Builder\DiscriminatorColumnMetadataBuilder($metadataBuildingContext);
144
145
                $discriminatorColumnBuilder
146 10
                    ->withComponentMetadata($metadata)
147 10
                    ->withDiscriminatorColumnAnnotation(
148 10
                        isset($xmlRoot->{'discriminator-column'})
149 8
                            ? $this->convertDiscrimininatorColumnElementToDiscriminatorColumnAnnotation($xmlRoot->{'discriminator-column'})
150 10
                            : null
151
                    );
152
153 10
                $metadata->setDiscriminatorColumn($discriminatorColumnBuilder->build());
154
155
                // Evaluate <discriminator-map...>
156 10
                if (isset($xmlRoot->{'discriminator-map'})) {
157 10
                    $map = [];
158
159 10
                    foreach ($xmlRoot->{'discriminator-map'}->{'discriminator-mapping'} as $discrMapElement) {
160 10
                        $map[(string) $discrMapElement['value']] = (string) $discrMapElement['class'];
161
                    }
162
163 10
                    $metadata->setDiscriminatorMap($map);
164
                }
165
            }
166
        }
167
168
        // Evaluate <change-tracking-policy...>
169 34
        if (isset($xmlRoot['change-tracking-policy'])) {
170
            $changeTrackingPolicy = strtoupper((string) $xmlRoot['change-tracking-policy']);
171
172
            $metadata->setChangeTrackingPolicy(
173
                constant(sprintf('%s::%s', Mapping\ChangeTrackingPolicy::class, $changeTrackingPolicy))
174
            );
175
        }
176
177
        // Evaluate <field ...> mappings
178 34
        if (isset($xmlRoot->field)) {
179 20
            $fieldBuilder = new Builder\FieldMetadataBuilder($metadataBuildingContext);
180
181
            $fieldBuilder
182 20
                ->withComponentMetadata($metadata);
183
184 20
            foreach ($xmlRoot->field as $fieldElement) {
185 20
                $versionAnnotation = isset($fieldElement['version']) && $this->evaluateBoolean($fieldElement['version'])
186 3
                    ? new Annotation\Version()
187 20
                    : null;
188
189
                $fieldBuilder
190 20
                    ->withFieldName((string) $fieldElement['name'])
191 20
                    ->withColumnAnnotation($this->convertFieldElementToColumnAnnotation($fieldElement))
192 20
                    ->withIdAnnotation(null)
193 20
                    ->withVersionAnnotation($versionAnnotation);
194
195 20
                $fieldMetadata = $fieldBuilder->build();
196
197
                // Prevent column duplication
198 20
                if ($metadata->checkPropertyDuplication($fieldMetadata->getColumnName())) {
0 ignored issues
show
Bug introduced by
It seems like $fieldMetadata->getColumnName() can also be of type null; however, parameter $columnName of Doctrine\ORM\Mapping\Cla...ckPropertyDuplication() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

198
                if ($metadata->checkPropertyDuplication(/** @scrutinizer ignore-type */ $fieldMetadata->getColumnName())) {
Loading history...
199
                    throw Mapping\MappingException::duplicateColumnName(
200
                        $metadata->getClassName(),
201
                        $fieldMetadata->getColumnName()
202
                    );
203
                }
204
205 20
                $metadata->addProperty($fieldMetadata);
206
            }
207
        }
208
209 34
        if (isset($xmlRoot->embedded)) {
210
            foreach ($xmlRoot->embedded as $embeddedMapping) {
211
                $columnPrefix = isset($embeddedMapping['column-prefix'])
212
                    ? (string) $embeddedMapping['column-prefix']
213
                    : null;
214
215
                $useColumnPrefix = isset($embeddedMapping['use-column-prefix'])
216
                    ? $this->evaluateBoolean($embeddedMapping['use-column-prefix'])
217
                    : true;
218
219
                $mapping = [
220
                    'fieldName'    => (string) $embeddedMapping['name'],
221
                    'class'        => (string) $embeddedMapping['class'],
222
                    'columnPrefix' => $useColumnPrefix ? $columnPrefix : false,
223
                ];
224
225
                $metadata->mapEmbedded($mapping);
226
            }
227
        }
228
229
        // Evaluate <id ...> mappings
230 34
        $associationIds = [];
231
232 34
        $fieldBuilder = new Builder\FieldMetadataBuilder($metadataBuildingContext);
233
234
        $fieldBuilder
235 34
            ->withComponentMetadata($metadata);
236
237 34
        foreach ($xmlRoot->id as $idElement) {
238 29
            $fieldName = (string) $idElement['name'];
239
240 29
            if (isset($idElement['association-key']) && $this->evaluateBoolean($idElement['association-key'])) {
241 2
                $associationIds[$fieldName] = true;
242
243 2
                continue;
244
            }
245
246 28
            $versionAnnotation = isset($idElement['version']) && $this->evaluateBoolean($idElement['version'])
247
                ? new Annotation\Version()
248 28
                : null;
249
250
            $fieldMetadata = $fieldBuilder
251 28
                ->withFieldName($fieldName)
252 28
                ->withColumnAnnotation($this->convertFieldElementToColumnAnnotation($idElement))
253 28
                ->withIdAnnotation(new Annotation\Id())
254 28
                ->withVersionAnnotation($versionAnnotation)
255 28
                ->withGeneratedValueAnnotation(
256 28
                    isset($idElement->generator)
257 27
                        ? $this->convertGeneratorElementToGeneratedValueAnnotation($idElement->generator)
258 28
                        : null
259
                )
260 28
                ->withSequenceGeneratorAnnotation(
261 28
                    isset($idElement->{'sequence-generator'})
262 3
                        ? $this->convertSequenceGeneratorElementToSequenceGeneratorAnnotation($idElement->{'sequence-generator'})
263 28
                        : null
264
                )
265 28
                ->withCustomIdGeneratorAnnotation(
266 28
                    isset($idElement->{'custom-id-generator'})
267 2
                        ? $this->convertCustomIdGeneratorElementToCustomIdGeneratorAnnotation($idElement->{'custom-id-generator'})
268 28
                        : null
269
                )
270 28
                ->build();
271
272
            // Prevent column duplication
273 28
            if ($metadata->checkPropertyDuplication($fieldMetadata->getColumnName())) {
274
                throw Mapping\MappingException::duplicateColumnName(
275
                    $metadata->getClassName(),
276
                    $fieldMetadata->getColumnName()
277
                );
278
            }
279
280 28
            $metadata->fieldNames[$fieldMetadata->getColumnName()] = $fieldMetadata->getName();
281
282 28
            $metadata->addProperty($fieldMetadata);
283
        }
284
285
        // Evaluate <one-to-one ...> mappings
286 34
        if (isset($xmlRoot->{'one-to-one'})) {
287 7
            $oneToOneAssociationBuilder = new Builder\OneToOneAssociationMetadataBuilder($metadataBuildingContext);
288
289
            $oneToOneAssociationBuilder
290 7
                ->withComponentMetadata($metadata);
291
292 7
            foreach ($xmlRoot->{'one-to-one'} as $oneToOneElement) {
293 7
                $fieldName           = (string) $oneToOneElement['field'];
294
                $associationMetadata = $oneToOneAssociationBuilder
295 7
                    ->withFieldName($fieldName)
296 7
                    ->withCacheAnnotation(
297 7
                        isset($oneToOneElement->cache)
298
                            ? $this->convertCacheElementToCacheAnnotation($oneToOneElement->cache)
299 7
                            : null
300
                    )
301 7
                    ->withOneToOneAnnotation($this->convertOneToOneElementToOneToOneAnnotation($oneToOneElement))
302 7
                    ->withIdAnnotation(isset($associationIds[$fieldName]) ? new Annotation\Id() : null)
303 7
                    ->withJoinColumnAnnotation(
304 7
                        isset($oneToOneElement->{'join-column'})
305 5
                            ? $this->convertJoinColumnElementToJoinColumnAnnotation($oneToOneElement->{'join-column'})
306 7
                            : null
307
                    )
308 7
                    ->withJoinColumnsAnnotation(
309 7
                        isset($oneToOneElement->{'join-columns'})
310
                            ? $this->convertJoinColumnsElementToJoinColumnsAnnotation($oneToOneElement->{'join-columns'})
311 7
                            : null
312
                    )
313 7
                    ->build();
314
315
                // Prevent column duplication
316 7
                foreach ($associationMetadata->getJoinColumns() as $joinColumnMetadata) {
317 5
                    $columnName = $joinColumnMetadata->getColumnName();
318
319
                    // @todo guilhermeblanco Open an issue to discuss making this scenario impossible.
320
                    //if ($metadata->checkPropertyDuplication($columnName)) {
321
                    //    throw Mapping\MappingException::duplicateColumnName($metadata->getClassName(), $columnName);
322
                    //}
323
324 5
                    if ($associationMetadata->isOwningSide()) {
325 5
                        $metadata->fieldNames[$columnName] = $associationMetadata->getName();
326
                    }
327
                }
328
329 7
                $metadata->addProperty($associationMetadata);
330
            }
331
        }
332
333
        // Evaluate <many-to-one ...> mappings
334 34
        if (isset($xmlRoot->{'many-to-one'})) {
335 8
            $manyToOneAssociationBuilder = new Builder\ManyToOneAssociationMetadataBuilder($metadataBuildingContext);
336
337
            $manyToOneAssociationBuilder
338 8
                ->withComponentMetadata($metadata);
339
340 8
            foreach ($xmlRoot->{'many-to-one'} as $manyToOneElement) {
341 8
                $fieldName           = (string) $manyToOneElement['field'];
342
                $associationMetadata = $manyToOneAssociationBuilder
343 8
                    ->withFieldName($fieldName)
344 8
                    ->withCacheAnnotation(
345 8
                        isset($manyToOneElement->cache)
346 1
                            ? $this->convertCacheElementToCacheAnnotation($manyToOneElement->cache)
347 8
                            : null
348
                    )
349 8
                    ->withManyToOneAnnotation($this->convertManyToOneElementToManyToOneAnnotation($manyToOneElement))
350 8
                    ->withIdAnnotation(isset($associationIds[$fieldName]) ? new Annotation\Id() : null)
351 8
                    ->withJoinColumnAnnotation(
352 8
                        isset($manyToOneElement->{'join-column'})
353 7
                            ? $this->convertJoinColumnElementToJoinColumnAnnotation($manyToOneElement->{'join-column'})
354 8
                            : null
355
                    )
356 8
                    ->withJoinColumnsAnnotation(
357 8
                        isset($manyToOneElement->{'join-columns'})
358 1
                            ? $this->convertJoinColumnsElementToJoinColumnsAnnotation($manyToOneElement->{'join-columns'})
359 8
                            : null
360
                    )
361 8
                    ->build();
362
363
                // Prevent column duplication
364 7
                foreach ($associationMetadata->getJoinColumns() as $joinColumnMetadata) {
365 7
                    $columnName = $joinColumnMetadata->getColumnName();
366
367
                    // @todo guilhermeblanco Open an issue to discuss making this scenario impossible.
368
                    //if ($metadata->checkPropertyDuplication($columnName)) {
369
                    //    throw Mapping\MappingException::duplicateColumnName($metadata->getClassName(), $columnName);
370
                    //}
371
372 7
                    if ($associationMetadata->isOwningSide()) {
373 7
                        $metadata->fieldNames[$columnName] = $associationMetadata->getName();
374
                    }
375
                }
376
377 7
                $metadata->addProperty($associationMetadata);
378
            }
379
        }
380
381
        // Evaluate <one-to-many ...> mappings
382 33
        if (isset($xmlRoot->{'one-to-many'})) {
383 9
            $oneToManyAssociationBuilder = new Builder\OneToManyAssociationMetadataBuilder($metadataBuildingContext);
384
385
            $oneToManyAssociationBuilder
386 9
                ->withComponentMetadata($metadata);
387
388 9
            foreach ($xmlRoot->{'one-to-many'} as $oneToManyElement) {
389 9
                $fieldName           = (string) $oneToManyElement['field'];
390
                $associationMetadata = $oneToManyAssociationBuilder
391 9
                    ->withFieldName($fieldName)
392 9
                    ->withCacheAnnotation(
393 9
                        isset($oneToManyElement->cache)
394 1
                            ? $this->convertCacheElementToCacheAnnotation($oneToManyElement->cache)
395 9
                            : null
396
                    )
397 9
                    ->withOneToManyAnnotation($this->convertOneToManyElementToOneToManyAnnotation($oneToManyElement))
398 9
                    ->withOrderByAnnotation(
399 9
                        isset($oneToManyElement->{'order-by'})
400 5
                            ? $this->convertOrderByElementToOrderByAnnotation($oneToManyElement->{'order-by'})
401 9
                            : null
402
                    )
403 9
                    ->withIdAnnotation(isset($associationIds[$fieldName]) ? new Annotation\Id() : null)
404 9
                    ->build();
405
406 9
                $metadata->addProperty($associationMetadata);
407
            }
408
        }
409
410
        // Evaluate <many-to-many ...> mappings
411 33
        if (isset($xmlRoot->{'many-to-many'})) {
412 14
            $manyToManyAssociationBuilder = new Builder\ManyToManyAssociationMetadataBuilder($metadataBuildingContext);
413
414
            $manyToManyAssociationBuilder
415 14
                ->withComponentMetadata($metadata);
416
417 14
            foreach ($xmlRoot->{'many-to-many'} as $manyToManyElement) {
418 14
                $fieldName           = (string) $manyToManyElement['field'];
419
                $associationMetadata = $manyToManyAssociationBuilder
420 14
                    ->withFieldName($fieldName)
421 14
                    ->withCacheAnnotation(
422 14
                        isset($manyToManyElement->cache)
423
                            ? $this->convertCacheElementToCacheAnnotation($manyToManyElement->cache)
424 14
                            : null
425
                    )
426 14
                    ->withManyToManyAnnotation($this->convertManyToManyElementToManyToManyAnnotation($manyToManyElement))
427 14
                    ->withJoinTableAnnotation(
428 14
                        isset($manyToManyElement->{'join-table'})
429 8
                            ? $this->convertJoinTableElementToJoinTableAnnotation($manyToManyElement->{'join-table'})
430 14
                            : null
431
                    )
432 14
                    ->withOrderByAnnotation(
433 14
                        isset($manyToManyElement->{'order-by'})
434 1
                            ? $this->convertOrderByElementToOrderByAnnotation($manyToManyElement->{'order-by'})
435 14
                            : null
436
                    )
437 14
                    ->withIdAnnotation(isset($associationIds[$fieldName]) ? new Annotation\Id() : null)
438 14
                    ->build();
439
440 14
                $metadata->addProperty($associationMetadata);
441
            }
442
        }
443
444
        // Evaluate association-overrides
445 33
        if (isset($xmlRoot->{'attribute-overrides'})) {
446 2
            $fieldBuilder = new Builder\FieldMetadataBuilder($metadataBuildingContext);
447
448
            $fieldBuilder
449 2
                ->withComponentMetadata($metadata);
450
451 2
            foreach ($xmlRoot->{'attribute-overrides'}->{'attribute-override'} as $overrideElement) {
452 2
                $fieldName = (string) $overrideElement['name'];
453 2
                $property  = $metadata->getProperty($fieldName);
454
455 2
                if (! $property) {
456
                    throw Mapping\MappingException::invalidOverrideFieldName($metadata->getClassName(), $fieldName);
457
                }
458
459 2
                foreach ($overrideElement->field as $fieldElement) {
460 2
                    $versionAnnotation = isset($fieldElement['version']) && $this->evaluateBoolean($fieldElement['version'])
461
                        ? new Annotation\Version()
462 2
                        : null;
463
464
                    $fieldBuilder
465 2
                        ->withFieldName($fieldName)
466 2
                        ->withColumnAnnotation($this->convertFieldElementToColumnAnnotation($fieldElement))
467 2
                        ->withIdAnnotation(null)
468 2
                        ->withVersionAnnotation($versionAnnotation);
469
470 2
                    $fieldMetadata = $fieldBuilder->build();
471 2
                    $columnName    = $fieldMetadata->getColumnName();
472
473
                    // Prevent column duplication
474 2
                    if ($metadata->checkPropertyDuplication($columnName)) {
475
                        throw Mapping\MappingException::duplicateColumnName($metadata->getClassName(), $columnName);
476
                    }
477
478 2
                    $metadata->fieldNames[$fieldMetadata->getColumnName()] = $fieldName;
479
480 2
                    $metadata->setPropertyOverride($fieldMetadata);
481
                }
482
            }
483
        }
484
485
        // Evaluate association-overrides
486 33
        if (isset($xmlRoot->{'association-overrides'})) {
487 4
            foreach ($xmlRoot->{'association-overrides'}->{'association-override'} as $overrideElement) {
488 4
                $fieldName = (string) $overrideElement['name'];
489 4
                $property  = $metadata->getProperty($fieldName);
490
491 4
                if (! $property) {
492
                    throw Mapping\MappingException::invalidOverrideFieldName($metadata->getClassName(), $fieldName);
493
                }
494
495 4
                $override = clone $property;
496
497
                // Check for join-columns
498 4
                if (isset($overrideElement->{'join-columns'})) {
499 2
                    $joinColumnBuilder = new Builder\JoinColumnMetadataBuilder($metadataBuildingContext);
500
501
                    $joinColumnBuilder
502 2
                        ->withComponentMetadata($metadata)
503 2
                        ->withFieldName($override->getName());
504
505 2
                    $joinColumns = [];
506
507 2
                    foreach ($overrideElement->{'join-columns'}->{'join-column'} as $joinColumnElement) {
508 2
                        $joinColumnBuilder->withJoinColumnAnnotation(
509 2
                            $this->convertJoinColumnElementToJoinColumnAnnotation($joinColumnElement)
510
                        );
511
512 2
                        $joinColumnMetadata = $joinColumnBuilder->build();
513 2
                        $columnName         = $joinColumnMetadata->getColumnName();
514
515
                        // @todo guilhermeblanco Open an issue to discuss making this scenario impossible.
516
                        //if ($metadata->checkPropertyDuplication($columnName)) {
517
                        //    throw Mapping\MappingException::duplicateColumnName($metadata->getClassName(), $columnName);
518
                        //}
519
520 2
                        if ($override->isOwningSide()) {
0 ignored issues
show
Bug introduced by
The method isOwningSide() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\AssociationMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

520
                        if ($override->/** @scrutinizer ignore-call */ isOwningSide()) {
Loading history...
521 2
                            $metadata->fieldNames[$columnName] = $fieldName;
522
                        }
523
524 2
                        $joinColumns[] = $joinColumnMetadata;
525
                    }
526
527 2
                    $override->setJoinColumns($joinColumns);
0 ignored issues
show
Bug introduced by
The method setJoinColumns() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\ToOneAssociationMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

527
                    $override->/** @scrutinizer ignore-call */ 
528
                               setJoinColumns($joinColumns);
Loading history...
528
                }
529
530
                // Check for join-table
531 4
                if ($overrideElement->{'join-table'}) {
532 2
                    $joinTableElement    = $overrideElement->{'join-table'};
533 2
                    $joinTableAnnotation = $this->convertJoinTableElementToJoinTableAnnotation($joinTableElement);
534 2
                    $joinTableBuilder    = new Builder\JoinTableMetadataBuilder($metadataBuildingContext);
535
536
                    $joinTableBuilder
537 2
                        ->withComponentMetadata($metadata)
538 2
                        ->withFieldName($property->getName())
539 2
                        ->withTargetEntity($property->getTargetEntity())
0 ignored issues
show
Bug introduced by
The method getTargetEntity() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\AssociationMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

539
                        ->withTargetEntity($property->/** @scrutinizer ignore-call */ getTargetEntity())
Loading history...
540 2
                        ->withJoinTableAnnotation($joinTableAnnotation);
541
542 2
                    $override->setJoinTable($joinTableBuilder->build());
0 ignored issues
show
Bug introduced by
The method setJoinTable() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\ManyToManyAssociationMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

542
                    $override->/** @scrutinizer ignore-call */ 
543
                               setJoinTable($joinTableBuilder->build());
Loading history...
543
                }
544
545
                // Check for inversed-by
546 4
                if (isset($overrideElement->{'inversed-by'})) {
547 1
                    $override->setInversedBy((string) $overrideElement->{'inversed-by'}['name']);
0 ignored issues
show
Bug introduced by
The method setInversedBy() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\AssociationMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

547
                    $override->/** @scrutinizer ignore-call */ 
548
                               setInversedBy((string) $overrideElement->{'inversed-by'}['name']);
Loading history...
548
                }
549
550
                // Check for fetch
551 4
                if (isset($overrideElement['fetch'])) {
552 1
                    $override->setFetchMode(
0 ignored issues
show
Bug introduced by
The method setFetchMode() does not exist on Doctrine\ORM\Mapping\Property. It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\AssociationMetadata. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

552
                    $override->/** @scrutinizer ignore-call */ 
553
                               setFetchMode(
Loading history...
553 1
                        constant('Doctrine\ORM\Mapping\FetchMode::' . (string) $overrideElement['fetch'])
554
                    );
555
                }
556
557 4
                $metadata->setPropertyOverride($override);
558
            }
559
        }
560
561
        // Evaluate <lifecycle-callbacks...>
562 33
        if (isset($xmlRoot->{'lifecycle-callbacks'})) {
563 3
            foreach ($xmlRoot->{'lifecycle-callbacks'}->{'lifecycle-callback'} as $lifecycleCallback) {
564 3
                $eventName  = constant(Events::class . '::' . (string) $lifecycleCallback['type']);
565 3
                $methodName = (string) $lifecycleCallback['method'];
566
567 3
                $metadata->addLifecycleCallback($eventName, $methodName);
568
            }
569
        }
570
571
        // Evaluate entity listener
572 33
        if (isset($xmlRoot->{'entity-listeners'})) {
573 2
            foreach ($xmlRoot->{'entity-listeners'}->{'entity-listener'} as $listenerElement) {
574 2
                $listenerClassName = (string) $listenerElement['class'];
575
576 2
                if (! class_exists($listenerClassName)) {
577
                    throw Mapping\MappingException::entityListenerClassNotFound(
578
                        $listenerClassName,
579
                        $metadata->getClassName()
580
                    );
581
                }
582
583 2
                foreach ($listenerElement as $callbackElement) {
584 2
                    $eventName  = (string) $callbackElement['type'];
585 2
                    $methodName = (string) $callbackElement['method'];
586
587 2
                    $metadata->addEntityListener($eventName, $listenerClassName, $methodName);
588
                }
589
            }
590
        }
591
592 33
        return $metadata;
593
    }
594
595
    /**
596
     * Parses (nested) index elements.
597
     *
598
     * @param SimpleXMLElement $indexes The XML element.
599
     *
600
     * @return Annotation\Index[] The indexes array.
601
     */
602 4
    private function parseIndexes(SimpleXMLElement $indexes) : array
603
    {
604 4
        $array = [];
605
606
        /** @var SimpleXMLElement $index */
607 4
        foreach ($indexes as $index) {
608 4
            $indexAnnotation = new Annotation\Index();
609
610 4
            $indexAnnotation->columns = explode(',', (string) $index['columns']);
611 4
            $indexAnnotation->options = isset($index->options) ? $this->parseOptions($index->options->children()) : [];
612 4
            $indexAnnotation->flags   = isset($index['flags']) ? explode(',', (string) $index['flags']) : [];
613
614 4
            if (isset($index['name'])) {
615 3
                $indexAnnotation->name = (string) $index['name'];
616
            }
617
618 4
            if (isset($index['unique'])) {
619
                $indexAnnotation->unique = $this->evaluateBoolean($index['unique']);
620
            }
621
622 4
            $array[] = $indexAnnotation;
623
        }
624
625 4
        return $array;
626
    }
627
628
    /**
629
     * Parses (nested) unique constraint elements.
630
     *
631
     * @param SimpleXMLElement $uniqueConstraints The XML element.
632
     *
633
     * @return Annotation\UniqueConstraint[] The unique constraints array.
634
     */
635 3
    private function parseUniqueConstraints(SimpleXMLElement $uniqueConstraints) : array
636
    {
637 3
        $array = [];
638
639
        /** @var SimpleXMLElement $uniqueConstraint */
640 3
        foreach ($uniqueConstraints as $uniqueConstraint) {
641 3
            $uniqueConstraintAnnotation = new Annotation\UniqueConstraint();
642
643 3
            $uniqueConstraintAnnotation->columns = explode(',', (string) $uniqueConstraint['columns']);
644 3
            $uniqueConstraintAnnotation->options = isset($uniqueConstraint->options) ? $this->parseOptions($uniqueConstraint->options->children()) : [];
645 3
            $uniqueConstraintAnnotation->flags   = isset($uniqueConstraint['flags']) ? explode(',', (string) $uniqueConstraint['flags']) : [];
646
647 3
            if (isset($uniqueConstraint['name'])) {
648 3
                $uniqueConstraintAnnotation->name = (string) $uniqueConstraint['name'];
649
            }
650
651 3
            $array[] = $uniqueConstraintAnnotation;
652
        }
653
654 3
        return $array;
655
    }
656
657
    /**
658
     * Parses (nested) option elements.
659
     *
660
     * @param SimpleXMLElement $options The XML element.
661
     *
662
     * @return mixed[] The options array.
663
     */
664 4
    private function parseOptions(SimpleXMLElement $options) : array
665
    {
666 4
        $array = [];
667
668
        /** @var SimpleXMLElement $option */
669 4
        foreach ($options as $option) {
670 4
            if ($option->count()) {
671 3
                $value = $this->parseOptions($option->children());
672
            } else {
673 4
                $value = (string) $option;
674
            }
675
676 4
            $attributes = $option->attributes();
677
678 4
            if (isset($attributes->name)) {
679 4
                $nameAttribute = (string) $attributes->name;
680
681 4
                $array[$nameAttribute] = in_array($nameAttribute, ['unsigned', 'fixed'], true)
682 3
                    ? $this->evaluateBoolean($value)
683 4
                    : $value;
684
            } else {
685
                $array[] = $value;
686
            }
687
        }
688
689 4
        return $array;
690
    }
691
692 7
    private function convertOneToOneElementToOneToOneAnnotation(
693
        SimpleXMLElement $oneToOneElement
694
    ) : Annotation\OneToOne {
695 7
        $oneToOneAnnotation = new Annotation\OneToOne();
696
697 7
        $oneToOneAnnotation->targetEntity = (string) $oneToOneElement['target-entity'];
698
699 7
        if (isset($oneToOneElement['mapped-by'])) {
700 3
            $oneToOneAnnotation->mappedBy = (string) $oneToOneElement['mapped-by'];
701
        }
702
703 7
        if (isset($oneToOneElement['inversed-by'])) {
704 4
            $oneToOneAnnotation->inversedBy = (string) $oneToOneElement['inversed-by'];
705
        }
706
707 7
        if (isset($oneToOneElement['orphan-removal'])) {
708
            $oneToOneAnnotation->orphanRemoval = $this->evaluateBoolean($oneToOneElement['orphan-removal']);
709
        }
710
711 7
        if (isset($oneToOneElement['fetch'])) {
712 3
            $oneToOneAnnotation->fetch = (string) $oneToOneElement['fetch'];
713
        }
714
715 7
        if (isset($oneToOneElement->cascade)) {
716 7
            $oneToOneAnnotation->cascade = $this->getCascadeMappings($oneToOneElement->cascade);
717
        }
718
719 7
        return $oneToOneAnnotation;
720
    }
721
722 8
    private function convertManyToOneElementToManyToOneAnnotation(
723
        SimpleXMLElement $manyToOneElement
724
    ) : Annotation\ManyToOne {
725 8
        $manyToOneAnnotation = new Annotation\ManyToOne();
726
727 8
        $manyToOneAnnotation->targetEntity = (string) $manyToOneElement['target-entity'];
728
729 8
        if (isset($manyToOneElement['inversed-by'])) {
730 2
            $manyToOneAnnotation->inversedBy = (string) $manyToOneElement['inversed-by'];
731
        }
732
733 8
        if (isset($manyToOneElement['fetch'])) {
734
            $manyToOneAnnotation->fetch = (string) $manyToOneElement['fetch'];
735
        }
736
737 8
        if (isset($manyToOneElement->cascade)) {
738 4
            $manyToOneAnnotation->cascade = $this->getCascadeMappings($manyToOneElement->cascade);
739
        }
740
741 8
        return $manyToOneAnnotation;
742
    }
743
744 9
    private function convertOneToManyElementToOneToManyAnnotation(
745
        SimpleXMLElement $oneToManyElement
746
    ) : Annotation\OneToMany {
747 9
        $oneToManyAnnotation = new Annotation\OneToMany();
748
749 9
        $oneToManyAnnotation->targetEntity = (string) $oneToManyElement['target-entity'];
750
751 9
        if (isset($oneToManyElement['mapped-by'])) {
752 9
            $oneToManyAnnotation->mappedBy = (string) $oneToManyElement['mapped-by'];
753
        }
754
755 9
        if (isset($oneToManyElement['fetch'])) {
756
            $oneToManyAnnotation->fetch = (string) $oneToManyElement['fetch'];
757
        }
758
759 9
        if (isset($oneToManyElement->cascade)) {
760 6
            $oneToManyAnnotation->cascade = $this->getCascadeMappings($oneToManyElement->cascade);
761
        }
762
763 9
        if (isset($oneToManyElement['orphan-removal'])) {
764 3
            $oneToManyAnnotation->orphanRemoval = $this->evaluateBoolean($oneToManyElement['orphan-removal']);
765
        }
766
767 9
        if (isset($oneToManyElement['index-by'])) {
768 3
            $oneToManyAnnotation->indexBy = (string) $oneToManyElement['index-by'];
769 6
        } elseif (isset($oneToManyElement->{'index-by'})) {
770
            throw new InvalidArgumentException('<index-by /> is not a valid tag');
771
        }
772
773 9
        return $oneToManyAnnotation;
774
    }
775
776 14
    private function convertManyToManyElementToManyToManyAnnotation(
777
        SimpleXMLElement $manyToManyElement
778
    ) : Annotation\ManyToMany {
779 14
        $manyToManyAnnotation = new Annotation\ManyToMany();
780
781 14
        $manyToManyAnnotation->targetEntity = (string) $manyToManyElement['target-entity'];
782
783 14
        if (isset($manyToManyElement['mapped-by'])) {
784 5
            $manyToManyAnnotation->mappedBy = (string) $manyToManyElement['mapped-by'];
785
        }
786
787 14
        if (isset($manyToManyElement['inversed-by'])) {
788 6
            $manyToManyAnnotation->inversedBy = (string) $manyToManyElement['inversed-by'];
789
        }
790
791 14
        if (isset($manyToManyElement['fetch'])) {
792 4
            $manyToManyAnnotation->fetch = (string) $manyToManyElement['fetch'];
793
        }
794
795 14
        if (isset($manyToManyElement->cascade)) {
796 8
            $manyToManyAnnotation->cascade = $this->getCascadeMappings($manyToManyElement->cascade);
797
        }
798
799 14
        if (isset($manyToManyElement['orphan-removal'])) {
800
            $manyToManyAnnotation->orphanRemoval = $this->evaluateBoolean($manyToManyElement['orphan-removal']);
801
        }
802
803 14
        if (isset($manyToManyElement['index-by'])) {
804
            $manyToManyAnnotation->indexBy = (string) $manyToManyElement['index-by'];
805 14
        } elseif (isset($manyToManyElement->{'index-by'})) {
806
            throw new InvalidArgumentException('<index-by /> is not a valid tag');
807
        }
808
809 14
        return $manyToManyAnnotation;
810
    }
811
812 30
    private function convertFieldElementToColumnAnnotation(
813
        SimpleXMLElement $fieldElement
814
    ) : Annotation\Column {
815 30
        $columnAnnotation = new Annotation\Column();
816
817 30
        $columnAnnotation->type = isset($fieldElement['type']) ? (string) $fieldElement['type'] : 'string';
818
819 30
        if (isset($fieldElement['column'])) {
820 20
            $columnAnnotation->name = (string) $fieldElement['column'];
821
        }
822
823 30
        if (isset($fieldElement['length'])) {
824 6
            $columnAnnotation->length = (int) $fieldElement['length'];
825
        }
826
827 30
        if (isset($fieldElement['precision'])) {
828 1
            $columnAnnotation->precision = (int) $fieldElement['precision'];
829
        }
830
831 30
        if (isset($fieldElement['scale'])) {
832 1
            $columnAnnotation->scale = (int) $fieldElement['scale'];
833
        }
834
835 30
        if (isset($fieldElement['unique'])) {
836 7
            $columnAnnotation->unique = $this->evaluateBoolean($fieldElement['unique']);
837
        }
838
839 30
        if (isset($fieldElement['nullable'])) {
840 7
            $columnAnnotation->nullable = $this->evaluateBoolean($fieldElement['nullable']);
841
        }
842
843 30
        if (isset($fieldElement['column-definition'])) {
844 4
            $columnAnnotation->columnDefinition = (string) $fieldElement['column-definition'];
845
        }
846
847 30
        if (isset($fieldElement->options)) {
848 3
            $columnAnnotation->options = $this->parseOptions($fieldElement->options->children());
849
        }
850
851 30
        return $columnAnnotation;
852
    }
853
854 27
    private function convertGeneratorElementToGeneratedValueAnnotation(
855
        SimpleXMLElement $generatorElement
856
    ) : Annotation\GeneratedValue {
857 27
        $generatedValueAnnotation = new Annotation\GeneratedValue();
858
859 27
        $generatedValueAnnotation->strategy = (string) ($generatorElement['strategy'] ?? 'AUTO');
860
861 27
        return $generatedValueAnnotation;
862
    }
863
864 3
    private function convertSequenceGeneratorElementToSequenceGeneratorAnnotation(
865
        SimpleXMLElement $sequenceGeneratorElement
866
    ) : Annotation\SequenceGenerator {
867 3
        $sequenceGeneratorAnnotation = new Annotation\SequenceGenerator();
868
869 3
        $sequenceGeneratorAnnotation->sequenceName   = (string) ($sequenceGeneratorElement['sequence-name'] ?? null);
870 3
        $sequenceGeneratorAnnotation->allocationSize = (int) ($sequenceGeneratorElement['allocation-size'] ?? 1);
871
872 3
        return $sequenceGeneratorAnnotation;
873
    }
874
875 2
    private function convertCustomIdGeneratorElementToCustomIdGeneratorAnnotation(
876
        SimpleXMLElement $customIdGeneratorElement
877
    ) : Annotation\CustomIdGenerator {
878 2
        $customIdGeneratorAnnotation = new Annotation\CustomIdGenerator();
879
880 2
        $customIdGeneratorAnnotation->class     = (string) $customIdGeneratorElement['class'];
881 2
        $customIdGeneratorAnnotation->arguments = [];
882
883 2
        return $customIdGeneratorAnnotation;
884
    }
885
886
    /**
887
     * Constructs a JoinTable annotation based on the information
888
     * found in the given SimpleXMLElement.
889
     *
890
     * @param SimpleXMLElement $joinTableElement The XML element.
891
     */
892 8
    private function convertJoinTableElementToJoinTableAnnotation(
893
        SimpleXMLElement $joinTableElement
894
    ) : Annotation\JoinTable {
895 8
        $joinTableAnnotation = new Annotation\JoinTable();
896
897 8
        if (isset($joinTableElement['name'])) {
898 8
            $joinTableAnnotation->name = (string) $joinTableElement['name'];
899
        }
900
901 8
        if (isset($joinTableElement['schema'])) {
902
            $joinTableAnnotation->schema = (string) $joinTableElement['schema'];
903
        }
904
905 8
        if (isset($joinTableElement->{'join-columns'})) {
906 8
            $joinColumns = [];
907
908 8
            foreach ($joinTableElement->{'join-columns'}->{'join-column'} as $joinColumnElement) {
909 8
                $joinColumns[] = $this->convertJoinColumnElementToJoinColumnAnnotation($joinColumnElement);
910
            }
911
912 8
            $joinTableAnnotation->joinColumns = $joinColumns;
913
        }
914
915 8
        if (isset($joinTableElement->{'inverse-join-columns'})) {
916 8
            $joinColumns = [];
917
918 8
            foreach ($joinTableElement->{'inverse-join-columns'}->{'join-column'} as $joinColumnElement) {
919 8
                $joinColumns[] = $this->convertJoinColumnElementToJoinColumnAnnotation($joinColumnElement);
920
            }
921
922 8
            $joinTableAnnotation->inverseJoinColumns = $joinColumns;
923
        }
924
925 8
        return $joinTableAnnotation;
926
    }
927
928 1
    private function convertJoinColumnsElementToJoinColumnsAnnotation(
929
        SimpleXMLElement $joinColumnsElement
930
    ) : Annotation\JoinColumns {
931 1
        $joinColumnsAnnotation = new Annotation\JoinColumns();
932 1
        $joinColumns           = [];
933
934 1
        foreach ($joinColumnsElement->{'join-column'} as $joinColumnElement) {
935 1
            $joinColumns[] = $this->convertJoinColumnElementToJoinColumnAnnotation($joinColumnElement);
936
        }
937
938 1
        $joinColumnsAnnotation->value = $joinColumns;
939
940 1
        return $joinColumnsAnnotation;
941
    }
942
943
    /**
944
     * Constructs a JoinColumn annotation based on the information
945
     * found in the given SimpleXMLElement.
946
     *
947
     * @param SimpleXMLElement $joinColumnElement The XML element.
948
     */
949 13
    private function convertJoinColumnElementToJoinColumnAnnotation(
950
        SimpleXMLElement $joinColumnElement
951
    ) : Annotation\JoinColumn {
952 13
        $joinColumnAnnotation = new Annotation\JoinColumn();
953
954 13
        $joinColumnAnnotation->name                 = (string) $joinColumnElement['name'];
955 13
        $joinColumnAnnotation->referencedColumnName = (string) $joinColumnElement['referenced-column-name'];
956
957 13
        if (isset($joinColumnElement['column-definition'])) {
958 3
            $joinColumnAnnotation->columnDefinition = (string) $joinColumnElement['column-definition'];
959
        }
960
961 13
        if (isset($joinColumnElement['field-name'])) {
962
            $joinColumnAnnotation->fieldName = (string) $joinColumnElement['field-name'];
963
        }
964
965 13
        if (isset($joinColumnElement['nullable'])) {
966 4
            $joinColumnAnnotation->nullable = $this->evaluateBoolean($joinColumnElement['nullable']);
967
        }
968
969 13
        if (isset($joinColumnElement['unique'])) {
970 3
            $joinColumnAnnotation->unique = $this->evaluateBoolean($joinColumnElement['unique']);
971
        }
972
973 13
        if (isset($joinColumnElement['on-delete'])) {
974 3
            $joinColumnAnnotation->onDelete = strtoupper((string) $joinColumnElement['on-delete']);
975
        }
976
977 13
        return $joinColumnAnnotation;
978
    }
979
980
    /**
981
     * Parse the given Cache as CacheMetadata
982
     */
983 2
    private function convertCacheElementToCacheAnnotation(SimpleXMLElement $cacheMapping) : Annotation\Cache
984
    {
985 2
        $cacheAnnotation = new Annotation\Cache();
986
987 2
        if (isset($cacheMapping['region'])) {
988
            $cacheAnnotation->region = (string) $cacheMapping['region'];
989
        }
990
991 2
        if (isset($cacheMapping['usage'])) {
992 2
            $cacheAnnotation->usage = strtoupper((string) $cacheMapping['usage']);
993
        }
994
995 2
        return $cacheAnnotation;
996
    }
997
998 8
    private function convertDiscrimininatorColumnElementToDiscriminatorColumnAnnotation(
999
        SimpleXMLElement $discriminatorColumnElement
1000
    ) : Annotation\DiscriminatorColumn {
1001 8
        $discriminatorColumnAnnotation = new Annotation\DiscriminatorColumn();
1002
1003 8
        $discriminatorColumnAnnotation->type = (string) ($discriminatorColumnElement['type'] ?? 'string');
1004 8
        $discriminatorColumnAnnotation->name = (string) $discriminatorColumnElement['name'];
1005
1006 8
        if (isset($discriminatorColumnElement['column-definition'])) {
1007 1
            $discriminatorColumnAnnotation->columnDefinition = (string) $discriminatorColumnElement['column-definition'];
1008
        }
1009
1010 8
        if (isset($discriminatorColumnElement['length'])) {
1011 3
            $discriminatorColumnAnnotation->length = (int) $discriminatorColumnElement['length'];
1012
        }
1013
1014 8
        return $discriminatorColumnAnnotation;
1015
    }
1016
1017 6
    private function convertOrderByElementToOrderByAnnotation(
1018
        SimpleXMLElement $orderByElement
1019
    ) : Annotation\OrderBy {
1020 6
        $orderByAnnotation = new Annotation\OrderBy();
1021 6
        $orderBy           = [];
1022
1023 6
        foreach ($orderByElement->{'order-by-field'} as $orderByField) {
1024 6
            $orderBy[(string) $orderByField['name']] = isset($orderByField['direction'])
1025 4
                ? (string) $orderByField['direction']
1026 2
                : Criteria::ASC;
1027
        }
1028
1029 6
        $orderByAnnotation->value = $orderBy;
1030
1031 6
        return $orderByAnnotation;
1032
    }
1033
1034
    /**
1035
     * Gathers a list of cascade options found in the given cascade element.
1036
     *
1037
     * @param SimpleXMLElement $cascadeElement The cascade element.
1038
     *
1039
     * @return string[] The list of cascade options.
1040
     */
1041 10
    private function getCascadeMappings(SimpleXMLElement $cascadeElement) : array
1042
    {
1043 10
        $cascades = [];
1044
1045
        /** @var SimpleXMLElement $action */
1046 10
        foreach ($cascadeElement->children() as $action) {
1047
            // According to the JPA specifications, XML uses "cascade-persist"
1048
            // instead of "persist". Here, both variations are supported
1049
            // because Annotation use "persist" and we want to make sure that
1050
            // this driver doesn't need to know anything about the supported
1051
            // cascading actions
1052 10
            $cascades[] = str_replace('cascade-', '', $action->getName());
1053
        }
1054
1055 10
        return $cascades;
1056
    }
1057
1058
    /**
1059
     * {@inheritDoc}
1060
     */
1061 36
    protected function loadMappingFile($file)
1062
    {
1063 36
        $result = [];
1064
        // Note: we do not use `simplexml_load_file()` because of https://bugs.php.net/bug.php?id=62577
1065 36
        $xmlElement = simplexml_load_string(file_get_contents($file));
1066
1067 36
        if (isset($xmlElement->entity)) {
1068 35
            foreach ($xmlElement->entity as $entityElement) {
1069 35
                $entityName          = (string) $entityElement['name'];
1070 35
                $result[$entityName] = $entityElement;
1071
            }
1072 6
        } elseif (isset($xmlElement->{'mapped-superclass'})) {
1073 5
            foreach ($xmlElement->{'mapped-superclass'} as $mappedSuperClass) {
1074 5
                $className          = (string) $mappedSuperClass['name'];
1075 5
                $result[$className] = $mappedSuperClass;
1076
            }
1077 1
        } elseif (isset($xmlElement->embeddable)) {
1078
            foreach ($xmlElement->embeddable as $embeddableElement) {
1079
                $embeddableName          = (string) $embeddableElement['name'];
1080
                $result[$embeddableName] = $embeddableElement;
1081
            }
1082
        }
1083
1084 36
        return $result;
1085
    }
1086
1087
    /**
1088
     * @param mixed $element
1089
     *
1090
     * @return bool
1091
     */
1092 9
    protected function evaluateBoolean($element)
1093
    {
1094 9
        $flag = (string) $element;
1095
1096 9
        return $flag === 'true' || $flag === '1';
1097
    }
1098
}
1099