Completed
Pull Request — master (#1803)
by Maciej
15:26 queued 06:04
created

XmlDriver::loadMetadataForClass()   F

Complexity

Conditions 53
Paths > 20000

Size

Total Lines 159
Code Lines 102

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 75
CRAP Score 105.0971

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 159
ccs 75
cts 102
cp 0.7352
rs 2
c 1
b 0
f 0
cc 53
eloc 102
nc 14155777
nop 2
crap 105.0971

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\ODM\MongoDB\Mapping\Driver;
6
7
use Doctrine\Common\Persistence\Mapping\Driver\FileDriver;
8
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;
9
use Doctrine\ODM\MongoDB\Utility\CollectionHelper;
10
use function array_keys;
11
use function assert;
12
use function constant;
13
use function count;
14
use function current;
15
use function explode;
16
use function in_array;
17
use function is_numeric;
18
use function iterator_to_array;
19
use function next;
20
use function preg_match;
21
use function simplexml_load_file;
22
use function strtoupper;
23
use function trim;
24
25
/**
26
 * XmlDriver is a metadata driver that enables mapping through XML files.
27
 *
28
 */
29
class XmlDriver extends FileDriver
30
{
31
    public const DEFAULT_FILE_EXTENSION = '.dcm.xml';
32
33
    /**
34
     * {@inheritDoc}
35
     */
36 13
    public function __construct($locator, $fileExtension = self::DEFAULT_FILE_EXTENSION)
37
    {
38 13
        parent::__construct($locator, $fileExtension);
39 13
    }
40
41
    /**
42
     * {@inheritDoc}
43
     */
44 7
    public function loadMetadataForClass($className, \Doctrine\Common\Persistence\Mapping\ClassMetadata $class)
45
    {
46 7
        assert($class instanceof ClassMetadata);
47
        /** @var \SimpleXMLElement $xmlRoot */
48 7
        $xmlRoot = $this->getElement($className);
49 7
        if (! $xmlRoot) {
50
            return;
51
        }
52
53 7
        if ($xmlRoot->getName() === 'document') {
54 7
            if (isset($xmlRoot['repository-class'])) {
55 7
                $class->setCustomRepositoryClass((string) $xmlRoot['repository-class']);
56
            }
57 2
        } elseif ($xmlRoot->getName() === 'mapped-superclass') {
58 1
            $class->setCustomRepositoryClass(
59 1
                isset($xmlRoot['repository-class']) ? (string) $xmlRoot['repository-class'] : null
60
            );
61 1
            $class->isMappedSuperclass = true;
62 1
        } elseif ($xmlRoot->getName() === 'embedded-document') {
63 1
            $class->isEmbeddedDocument = true;
64 1
        } elseif ($xmlRoot->getName() === 'query-result-document') {
65 1
            $class->isQueryResultDocument = true;
66
        }
67 7
        if (isset($xmlRoot['db'])) {
68 4
            $class->setDatabase((string) $xmlRoot['db']);
69
        }
70 7
        if (isset($xmlRoot['collection'])) {
71 6
            if (isset($xmlRoot['capped-collection'])) {
72
                $config = ['name' => (string) $xmlRoot['collection']];
73
                $config['capped'] = (bool) $xmlRoot['capped-collection'];
74
                if (isset($xmlRoot['capped-collection-max'])) {
75
                    $config['max'] = (int) $xmlRoot['capped-collection-max'];
76
                }
77
                if (isset($xmlRoot['capped-collection-size'])) {
78
                    $config['size'] = (int) $xmlRoot['capped-collection-size'];
79
                }
80
                $class->setCollection($config);
81
            } else {
82 6
                $class->setCollection((string) $xmlRoot['collection']);
83
            }
84
        }
85 7
        if (isset($xmlRoot['writeConcern'])) {
86
            $class->setWriteConcern((string) $xmlRoot['writeConcern']);
87
        }
88 7
        if (isset($xmlRoot['inheritance-type'])) {
89
            $inheritanceType = (string) $xmlRoot['inheritance-type'];
90
            $class->setInheritanceType(constant(ClassMetadata::class . '::INHERITANCE_TYPE_' . $inheritanceType));
91
        }
92 7
        if (isset($xmlRoot['change-tracking-policy'])) {
93 1
            $class->setChangeTrackingPolicy(constant(ClassMetadata::class . '::CHANGETRACKING_' . strtoupper((string) $xmlRoot['change-tracking-policy'])));
94
        }
95 7
        if (isset($xmlRoot->{'discriminator-field'})) {
96
            $discrField = $xmlRoot->{'discriminator-field'};
97
            /* XSD only allows for "name", which is consistent with association
98
             * configurations, but fall back to "fieldName" for BC.
99
             */
100
            $class->setDiscriminatorField(
101
                (string) ($discrField['name'] ?? $discrField['fieldName'])
102
            );
103
        }
104 7
        if (isset($xmlRoot->{'discriminator-map'})) {
105
            $map = [];
106
            foreach ($xmlRoot->{'discriminator-map'}->{'discriminator-mapping'} as $discrMapElement) {
107
                $map[(string) $discrMapElement['value']] = (string) $discrMapElement['class'];
108
            }
109
            $class->setDiscriminatorMap($map);
110
        }
111 7
        if (isset($xmlRoot->{'default-discriminator-value'})) {
112
            $class->setDefaultDiscriminatorValue((string) $xmlRoot->{'default-discriminator-value'}['value']);
113
        }
114 7
        if (isset($xmlRoot->{'indexes'})) {
115 2
            foreach ($xmlRoot->{'indexes'}->{'index'} as $index) {
116 2
                $this->addIndex($class, $index);
117
            }
118
        }
119 7
        if (isset($xmlRoot->{'shard-key'})) {
120
            $this->setShardKey($class, $xmlRoot->{'shard-key'}[0]);
121
        }
122 7
        if (isset($xmlRoot['read-only']) && (string) $xmlRoot['read-only'] === 'true') {
123
            $class->markReadOnly();
124
        }
125 7
        if (isset($xmlRoot->{'read-preference'})) {
126
            $class->setReadPreference(...$this->transformReadPreference($xmlRoot->{'read-preference'}));
127
        }
128 7
        if (isset($xmlRoot->field)) {
129 7
            foreach ($xmlRoot->field as $field) {
130 7
                $mapping = [];
131 7
                $attributes = $field->attributes();
132 7
                foreach ($attributes as $key => $value) {
133 7
                    $mapping[$key] = (string) $value;
134 7
                    $booleanAttributes = ['id', 'reference', 'embed', 'unique', 'sparse'];
135 7
                    if (! in_array($key, $booleanAttributes)) {
136 7
                        continue;
137
                    }
138
139 7
                    $mapping[$key] = ($mapping[$key] === 'true');
140
                }
141 7
                if (isset($mapping['id']) && $mapping['id'] === true && isset($mapping['strategy'])) {
142 2
                    $mapping['options'] = [];
143 2
                    if (isset($field->{'id-generator-option'})) {
144 1
                        foreach ($field->{'id-generator-option'} as $generatorOptions) {
145 1
                            $attributesGenerator = iterator_to_array($generatorOptions->attributes());
146 1
                            if (! isset($attributesGenerator['name']) || ! isset($attributesGenerator['value'])) {
147
                                continue;
148
                            }
149
150 1
                            $mapping['options'][(string) $attributesGenerator['name']] = (string) $attributesGenerator['value'];
151
                        }
152
                    }
153
                }
154
155 7
                if (isset($attributes['not-saved'])) {
156
                    $mapping['notSaved'] = ((string) $attributes['not-saved'] === 'true');
157
                }
158
159 7
                if (isset($attributes['also-load'])) {
160
                    $mapping['alsoLoadFields'] = explode(',', $attributes['also-load']);
161 7
                } elseif (isset($attributes['version'])) {
162
                    $mapping['version'] = ((string) $attributes['version'] === 'true');
163 7
                } elseif (isset($attributes['lock'])) {
164
                    $mapping['lock'] = ((string) $attributes['lock'] === 'true');
165
                }
166
167 7
                $this->addFieldMapping($class, $mapping);
168
            }
169
        }
170 7
        if (isset($xmlRoot->{'embed-one'})) {
171 1
            foreach ($xmlRoot->{'embed-one'} as $embed) {
172 1
                $this->addEmbedMapping($class, $embed, 'one');
173
            }
174
        }
175 7
        if (isset($xmlRoot->{'embed-many'})) {
176 1
            foreach ($xmlRoot->{'embed-many'} as $embed) {
177 1
                $this->addEmbedMapping($class, $embed, 'many');
178
            }
179
        }
180 7
        if (isset($xmlRoot->{'reference-many'})) {
181 3
            foreach ($xmlRoot->{'reference-many'} as $reference) {
182 3
                $this->addReferenceMapping($class, $reference, 'many');
183
            }
184
        }
185 7
        if (isset($xmlRoot->{'reference-one'})) {
186 2
            foreach ($xmlRoot->{'reference-one'} as $reference) {
187 2
                $this->addReferenceMapping($class, $reference, 'one');
188
            }
189
        }
190 7
        if (isset($xmlRoot->{'lifecycle-callbacks'})) {
191 1
            foreach ($xmlRoot->{'lifecycle-callbacks'}->{'lifecycle-callback'} as $lifecycleCallback) {
192 1
                $class->addLifecycleCallback((string) $lifecycleCallback['method'], constant('Doctrine\ODM\MongoDB\Events::' . (string) $lifecycleCallback['type']));
193
            }
194
        }
195 7
        if (! isset($xmlRoot->{'also-load-methods'})) {
196 7
            return;
197
        }
198
199 1
        foreach ($xmlRoot->{'also-load-methods'}->{'also-load-method'} as $alsoLoadMethod) {
200 1
            $class->registerAlsoLoadMethod((string) $alsoLoadMethod['method'], (string) $alsoLoadMethod['field']);
201
        }
202 1
    }
203
204 8
    private function addFieldMapping(ClassMetadata $class, $mapping)
205
    {
206 8
        if (isset($mapping['name'])) {
207 8
            $name = $mapping['name'];
208
        } elseif (isset($mapping['fieldName'])) {
209
            $name = $mapping['fieldName'];
210
        } else {
211
            throw new \InvalidArgumentException('Cannot infer a MongoDB name from the mapping');
212
        }
213
214 8
        $class->mapField($mapping);
215
216
        // Index this field if either "index", "unique", or "sparse" are set
217 8
        if (! (isset($mapping['index']) || isset($mapping['unique']) || isset($mapping['sparse']))) {
218 8
            return;
219
        }
220
221 1
        $keys = [$name => $mapping['order'] ?? 'asc'];
222 1
        $options = [];
223
224 1
        if (isset($mapping['background'])) {
225
            $options['background'] = (bool) $mapping['background'];
226
        }
227 1
        if (isset($mapping['drop-dups'])) {
228
            $options['dropDups'] = (bool) $mapping['drop-dups'];
229
        }
230 1
        if (isset($mapping['index-name'])) {
231
            $options['name'] = (string) $mapping['index-name'];
232
        }
233 1
        if (isset($mapping['sparse'])) {
234 1
            $options['sparse'] = (bool) $mapping['sparse'];
235
        }
236 1
        if (isset($mapping['unique'])) {
237 1
            $options['unique'] = (bool) $mapping['unique'];
238
        }
239
240 1
        $class->addIndex($keys, $options);
241 1
    }
242
243 1
    private function addEmbedMapping(ClassMetadata $class, $embed, $type)
244
    {
245 1
        $attributes = $embed->attributes();
246 1
        $defaultStrategy = $type === 'one' ? ClassMetadata::STORAGE_STRATEGY_SET : CollectionHelper::DEFAULT_STRATEGY;
247
        $mapping = [
248 1
            'type'            => $type,
249
            'embedded'        => true,
250 1
            'targetDocument'  => isset($attributes['target-document']) ? (string) $attributes['target-document'] : null,
251 1
            'collectionClass' => isset($attributes['collection-class']) ? (string) $attributes['collection-class'] : null,
252 1
            'name'            => (string) $attributes['field'],
253 1
            'strategy'        => (string) ($attributes['strategy'] ?? $defaultStrategy),
254
        ];
255 1
        if (isset($attributes['fieldName'])) {
256
            $mapping['fieldName'] = (string) $attributes['fieldName'];
257
        }
258 1
        if (isset($embed->{'discriminator-field'})) {
259
            $attr = $embed->{'discriminator-field'};
260
            $mapping['discriminatorField'] = (string) $attr['name'];
261
        }
262 1
        if (isset($embed->{'discriminator-map'})) {
263
            foreach ($embed->{'discriminator-map'}->{'discriminator-mapping'} as $discriminatorMapping) {
264
                $attr = $discriminatorMapping->attributes();
265
                $mapping['discriminatorMap'][(string) $attr['value']] = (string) $attr['class'];
266
            }
267
        }
268 1
        if (isset($embed->{'default-discriminator-value'})) {
269
            $mapping['defaultDiscriminatorValue'] = (string) $embed->{'default-discriminator-value'}['value'];
270
        }
271 1
        if (isset($attributes['not-saved'])) {
272
            $mapping['notSaved'] = ((string) $attributes['not-saved'] === 'true');
273
        }
274 1
        if (isset($attributes['also-load'])) {
275
            $mapping['alsoLoadFields'] = explode(',', $attributes['also-load']);
276
        }
277 1
        $this->addFieldMapping($class, $mapping);
278 1
    }
279
280 4
    private function addReferenceMapping(ClassMetadata $class, $reference, $type)
281
    {
282 4
        $cascade = array_keys((array) $reference->cascade);
283 4
        if (count($cascade) === 1) {
284 1
            $cascade = current($cascade) ?: next($cascade);
285
        }
286 4
        $attributes = $reference->attributes();
287 4
        $defaultStrategy = $type === 'one' ? ClassMetadata::STORAGE_STRATEGY_SET : CollectionHelper::DEFAULT_STRATEGY;
288
        $mapping = [
289 4
            'cascade'          => $cascade,
290 4
            'orphanRemoval'    => isset($attributes['orphan-removal']) ? ((string) $attributes['orphan-removal'] === 'true') : false,
291 4
            'type'             => $type,
292
            'reference'        => true,
293 4
            'storeAs'          => (string) ($attributes['store-as'] ?? ClassMetadata::REFERENCE_STORE_AS_DB_REF),
294 4
            'targetDocument'   => isset($attributes['target-document']) ? (string) $attributes['target-document'] : null,
295 4
            'collectionClass'  => isset($attributes['collection-class']) ? (string) $attributes['collection-class'] : null,
296 4
            'name'             => (string) $attributes['field'],
297 4
            'strategy'         => (string) ($attributes['strategy'] ?? $defaultStrategy),
298 4
            'inversedBy'       => isset($attributes['inversed-by']) ? (string) $attributes['inversed-by'] : null,
299 4
            'mappedBy'         => isset($attributes['mapped-by']) ? (string) $attributes['mapped-by'] : null,
300 4
            'repositoryMethod' => isset($attributes['repository-method']) ? (string) $attributes['repository-method'] : null,
301 4
            'limit'            => isset($attributes['limit']) ? (int) $attributes['limit'] : null,
302 4
            'skip'             => isset($attributes['skip']) ? (int) $attributes['skip'] : null,
303
            'prime'            => [],
304
        ];
305
306 4
        if (isset($attributes['fieldName'])) {
307
            $mapping['fieldName'] = (string) $attributes['fieldName'];
308
        }
309 4
        if (isset($reference->{'discriminator-field'})) {
310
            $attr = $reference->{'discriminator-field'};
311
            $mapping['discriminatorField'] = (string) $attr['name'];
312
        }
313 4
        if (isset($reference->{'discriminator-map'})) {
314
            foreach ($reference->{'discriminator-map'}->{'discriminator-mapping'} as $discriminatorMapping) {
315
                $attr = $discriminatorMapping->attributes();
316
                $mapping['discriminatorMap'][(string) $attr['value']] = (string) $attr['class'];
317
            }
318
        }
319 4
        if (isset($reference->{'default-discriminator-value'})) {
320
            $mapping['defaultDiscriminatorValue'] = (string) $reference->{'default-discriminator-value'}['value'];
321
        }
322 4
        if (isset($reference->{'sort'})) {
323
            foreach ($reference->{'sort'}->{'sort'} as $sort) {
324
                $attr = $sort->attributes();
325
                $mapping['sort'][(string) $attr['field']] = (string) ($attr['order'] ?? 'asc');
326
            }
327
        }
328 4
        if (isset($reference->{'criteria'})) {
329
            foreach ($reference->{'criteria'}->{'criteria'} as $criteria) {
330
                $attr = $criteria->attributes();
331
                $mapping['criteria'][(string) $attr['field']] = (string) $attr['value'];
332
            }
333
        }
334 4
        if (isset($attributes['not-saved'])) {
335
            $mapping['notSaved'] = ((string) $attributes['not-saved'] === 'true');
336
        }
337 4
        if (isset($attributes['also-load'])) {
338
            $mapping['alsoLoadFields'] = explode(',', $attributes['also-load']);
339
        }
340 4
        if (isset($reference->{'prime'})) {
341 1
            foreach ($reference->{'prime'}->{'field'} as $field) {
342 1
                $attr = $field->attributes();
343 1
                $mapping['prime'][] = (string) $attr['name'];
344
            }
345
        }
346
347 4
        $this->addFieldMapping($class, $mapping);
348 4
    }
349
350 2
    private function addIndex(ClassMetadata $class, \SimpleXMLElement $xmlIndex)
351
    {
352 2
        $attributes = $xmlIndex->attributes();
353
354 2
        $keys = [];
355
356 2
        foreach ($xmlIndex->{'key'} as $key) {
357 2
            $keys[(string) $key['name']] = (string) ($key['order'] ?? 'asc');
358
        }
359
360 2
        $options = [];
361
362 2
        if (isset($attributes['background'])) {
363
            $options['background'] = ((string) $attributes['background'] === 'true');
364
        }
365 2
        if (isset($attributes['drop-dups'])) {
366
            $options['dropDups'] = ((string) $attributes['drop-dups'] === 'true');
367
        }
368 2
        if (isset($attributes['name'])) {
369
            $options['name'] = (string) $attributes['name'];
370
        }
371 2
        if (isset($attributes['sparse'])) {
372
            $options['sparse'] = ((string) $attributes['sparse'] === 'true');
373
        }
374 2
        if (isset($attributes['unique'])) {
375
            $options['unique'] = ((string) $attributes['unique'] === 'true');
376
        }
377
378 2
        if (isset($xmlIndex->{'option'})) {
379
            foreach ($xmlIndex->{'option'} as $option) {
380
                $value = (string) $option['value'];
381
                if ($value === 'true') {
382
                    $value = true;
383
                } elseif ($value === 'false') {
384
                    $value = false;
385
                } elseif (is_numeric($value)) {
386
                    $value = preg_match('/^[-]?\d+$/', $value) ? (int) $value : (float) $value;
387
                }
388
                $options[(string) $option['name']] = $value;
389
            }
390
        }
391
392 2
        if (isset($xmlIndex->{'partial-filter-expression'})) {
393 2
            $partialFilterExpressionMapping = $xmlIndex->{'partial-filter-expression'};
394
395 2
            if (isset($partialFilterExpressionMapping->and)) {
396 2
                foreach ($partialFilterExpressionMapping->and as $and) {
397 2
                    if (! isset($and->field)) {
398 1
                        continue;
399
                    }
400
401 2
                    $partialFilterExpression = $this->getPartialFilterExpression($and->field);
402 2
                    if (! $partialFilterExpression) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $partialFilterExpression of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
403
                        continue;
404
                    }
405
406 2
                    $options['partialFilterExpression']['$and'][] = $partialFilterExpression;
407
                }
408 1
            } elseif (isset($partialFilterExpressionMapping->field)) {
409 1
                $partialFilterExpression = $this->getPartialFilterExpression($partialFilterExpressionMapping->field);
410
411 1
                if ($partialFilterExpression) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $partialFilterExpression of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
412 1
                    $options['partialFilterExpression'] = $partialFilterExpression;
413
                }
414
            }
415
        }
416
417 2
        $class->addIndex($keys, $options);
418 2
    }
419
420 2
    private function getPartialFilterExpression(\SimpleXMLElement $fields)
421
    {
422 2
        $partialFilterExpression = [];
423 2
        foreach ($fields as $field) {
424 2
            $operator = (string) $field['operator'] ?: null;
425
426 2
            if (! isset($field['value'])) {
427 1
                if (! isset($field->field)) {
428
                    continue;
429
                }
430
431 1
                $nestedExpression = $this->getPartialFilterExpression($field->field);
432 1
                if (! $nestedExpression) {
433
                    continue;
434
                }
435
436 1
                $value = $nestedExpression;
437
            } else {
438 2
                $value = trim((string) $field['value']);
439
            }
440
441 2
            if ($value === 'true') {
442
                $value = true;
443 2
            } elseif ($value === 'false') {
444
                $value = false;
445 2
            } elseif (is_numeric($value)) {
446 1
                $value = preg_match('/^[-]?\d+$/', $value) ? (int) $value : (float) $value;
447
            }
448
449 2
            $partialFilterExpression[(string) $field['name']] = $operator ? ['$' . $operator => $value] : $value;
450
        }
451
452 2
        return $partialFilterExpression;
453
    }
454
455 1
    private function setShardKey(ClassMetadata $class, \SimpleXMLElement $xmlShardkey)
456
    {
457 1
        $attributes = $xmlShardkey->attributes();
458
459 1
        $keys = [];
460 1
        $options = [];
461 1
        foreach ($xmlShardkey->{'key'} as $key) {
462 1
            $keys[(string) $key['name']] = (string) ($key['order'] ?? 'asc');
463
        }
464
465 1
        if (isset($attributes['unique'])) {
466 1
            $options['unique'] = ((string) $attributes['unique'] === 'true');
467
        }
468
469 1
        if (isset($attributes['numInitialChunks'])) {
470 1
            $options['numInitialChunks'] = (int) $attributes['numInitialChunks'];
471
        }
472
473 1
        if (isset($xmlShardkey->{'option'})) {
474
            foreach ($xmlShardkey->{'option'} as $option) {
475
                $value = (string) $option['value'];
476
                if ($value === 'true') {
477
                    $value = true;
478
                } elseif ($value === 'false') {
479
                    $value = false;
480
                } elseif (is_numeric($value)) {
481
                    $value = preg_match('/^[-]?\d+$/', $value) ? (int) $value : (float) $value;
482
                }
483
                $options[(string) $option['name']] = $value;
484
            }
485
        }
486
487 1
        $class->setShardKey($keys, $options);
488 1
    }
489
490
    /**
491
     * Parses <read-preference> to a format suitable for the underlying driver.
492
     *
493
     * list($readPreference, $tags) = $this->transformReadPreference($xml->{read-preference});
494
     *
495
     * @param \SimpleXMLElement $xmlReadPreference
496
     * @return array
497
     */
498
    private function transformReadPreference($xmlReadPreference)
499
    {
500
        $tags = null;
501
        if (isset($xmlReadPreference->{'tag-set'})) {
502
            $tags = [];
503
            foreach ($xmlReadPreference->{'tag-set'} as $tagSet) {
504
                $set = [];
505
                foreach ($tagSet->tag as $tag) {
506
                    $set[(string) $tag['name']] = (string) $tag['value'];
507
                }
508
                $tags[] = $set;
509
            }
510
        }
511
        return [(string) $xmlReadPreference['mode'], $tags];
512
    }
513
514
    /**
515
     * {@inheritDoc}
516
     */
517 7
    protected function loadMappingFile($file)
518
    {
519 7
        $result = [];
520 7
        $xmlElement = simplexml_load_file($file);
521
522 7
        foreach (['document', 'embedded-document', 'mapped-superclass', 'query-result-document'] as $type) {
523 7
            if (! isset($xmlElement->$type)) {
524 7
                continue;
525
            }
526
527 7
            foreach ($xmlElement->$type as $documentElement) {
528 7
                $documentName = (string) $documentElement['name'];
529 7
                $result[$documentName] = $documentElement;
530
            }
531
        }
532
533 7
        return $result;
534
    }
535
}
536