Failed Conditions
Pull Request — develop (#6873)
by
unknown
112:44 queued 47:41
created

YamlDriver::loadMetadataForClass()   F

Complexity

Conditions 142
Paths > 20000

Size

Total Lines 613
Code Lines 319

Duplication

Lines 80
Ratio 13.05 %

Importance

Changes 0
Metric Value
cc 142
eloc 319
nc 153354241
nop 2
dl 80
loc 613
rs 2
c 0
b 0
f 0

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
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the MIT license. For more information, see
17
 * <http://www.doctrine-project.org>.
18
 */
19
20
namespace Doctrine\ORM\Mapping\Driver;
21
22
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
23
use Doctrine\ORM\Mapping\Builder\EntityListenerBuilder;
0 ignored issues
show
Bug introduced by
The type Doctrine\ORM\Mapping\Builder\EntityListenerBuilder was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
24
use Doctrine\Common\Persistence\Mapping\Driver\FileDriver;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Doctrine\ORM\Mapping\Driver\FileDriver. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
25
use Doctrine\ORM\Mapping\ClassMetadata as Metadata;
26
use Doctrine\ORM\Mapping\MappingException;
27
use Symfony\Component\Yaml\Yaml;
28
29
/**
30
 * The YamlDriver reads the mapping metadata from yaml schema files.
31
 *
32
 * @since 2.0
33
 * @author Benjamin Eberlei <[email protected]>
34
 * @author Guilherme Blanco <[email protected]>
35
 * @author Jonathan H. Wage <[email protected]>
36
 * @author Roman Borschel <[email protected]>
37
 */
38
class YamlDriver extends FileDriver
39
{
40
    const DEFAULT_FILE_EXTENSION = '.dcm.yml';
41
42
    /**
43
     * {@inheritDoc}
44
     */
45
    public function __construct($locator, $fileExtension = self::DEFAULT_FILE_EXTENSION)
46
    {
47
        parent::__construct($locator, $fileExtension);
48
    }
49
50
    /**
51
     * {@inheritDoc}
52
     */
53
    public function loadMetadataForClass($className, ClassMetadata $metadata)
54
    {
55
        /* @var $metadata \Doctrine\ORM\Mapping\ClassMetadataInfo */
56
        $element = $this->getElement($className);
57
58
        if ($element['type'] == 'entity') {
59
            if (isset($element['repositoryClass'])) {
60
                $metadata->setCustomRepositoryClass($element['repositoryClass']);
61
            }
62
            if (isset($element['readOnly']) && $element['readOnly'] == true) {
63
                $metadata->markReadOnly();
64
            }
65
        } else if ($element['type'] == 'mappedSuperclass') {
66
            $metadata->setCustomRepositoryClass(
67
                $element['repositoryClass'] ?? null
68
            );
69
            $metadata->isMappedSuperclass = true;
70
        } else if ($element['type'] == 'embeddable') {
71
            $metadata->isEmbeddedClass = true;
72
        } else {
73
            throw MappingException::classIsNotAValidEntityOrMappedSuperClass($className);
74
        }
75
76
        // Evaluate root level properties
77
        $primaryTable = [];
78
79
        if (isset($element['table'])) {
80
            $primaryTable['name'] = $element['table'];
81
        }
82
83
        if (isset($element['schema'])) {
84
            $primaryTable['schema'] = $element['schema'];
85
        }
86
87
        // Evaluate second level cache
88
        if (isset($element['cache'])) {
89
            $metadata->enableCache($this->cacheToArray($element['cache']));
90
        }
91
92
        $metadata->setPrimaryTable($primaryTable);
93
94
        // Evaluate named queries
95
        if (isset($element['namedQueries'])) {
96
            foreach ($element['namedQueries'] as $name => $queryMapping) {
97
                if (is_string($queryMapping)) {
98
                    $queryMapping = ['query' => $queryMapping];
99
                }
100
101
                if ( ! isset($queryMapping['name'])) {
102
                    $queryMapping['name'] = $name;
103
                }
104
105
                $metadata->addNamedQuery($queryMapping);
106
            }
107
        }
108
109
        // Evaluate named native queries
110
        if (isset($element['namedNativeQueries'])) {
111
            foreach ($element['namedNativeQueries'] as $name => $mappingElement) {
112
                if (!isset($mappingElement['name'])) {
113
                    $mappingElement['name'] = $name;
114
                }
115
                $metadata->addNamedNativeQuery(
116
                    [
117
                        'name'              => $mappingElement['name'],
118
                        'query'             => $mappingElement['query'] ?? null,
119
                        'resultClass'       => $mappingElement['resultClass'] ?? null,
120
                        'resultSetMapping'  => $mappingElement['resultSetMapping'] ?? null,
121
                    ]
122
                );
123
            }
124
        }
125
126
        // Evaluate sql result set mappings
127
        if (isset($element['sqlResultSetMappings'])) {
128
            foreach ($element['sqlResultSetMappings'] as $name => $resultSetMapping) {
129
                if (!isset($resultSetMapping['name'])) {
130
                    $resultSetMapping['name'] = $name;
131
                }
132
133
                $entities = [];
134
                $columns  = [];
135
                if (isset($resultSetMapping['entityResult'])) {
136
                    foreach ($resultSetMapping['entityResult'] as $entityResultElement) {
137
                        $entityResult = [
138
                            'fields'                => [],
139
                            'entityClass'           => $entityResultElement['entityClass'] ?? null,
140
                            'discriminatorColumn'   => $entityResultElement['discriminatorColumn'] ?? null,
141
                        ];
142
143
                        if (isset($entityResultElement['fieldResult'])) {
144
                            foreach ($entityResultElement['fieldResult'] as $fieldResultElement) {
145
                                $entityResult['fields'][] = [
146
                                    'name'      => $fieldResultElement['name'] ?? null,
147
                                    'column'    => $fieldResultElement['column'] ?? null,
148
                                ];
149
                            }
150
                        }
151
152
                        $entities[] = $entityResult;
153
                    }
154
                }
155
156
157
                if (isset($resultSetMapping['columnResult'])) {
158
                    foreach ($resultSetMapping['columnResult'] as $columnResultAnnot) {
159
                        $columns[] = [
160
                            'name' => $columnResultAnnot['name'] ?? null,
161
                        ];
162
                    }
163
                }
164
165
                $metadata->addSqlResultSetMapping(
166
                    [
167
                        'name'          => $resultSetMapping['name'],
168
                        'entities'      => $entities,
169
                        'columns'       => $columns
170
                    ]
171
                );
172
            }
173
        }
174
175
        if (isset($element['inheritanceType'])) {
176
            $metadata->setInheritanceType(constant('Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_' . strtoupper($element['inheritanceType'])));
177
178
            if ($metadata->inheritanceType != Metadata::INHERITANCE_TYPE_NONE) {
0 ignored issues
show
Bug introduced by
The constant Doctrine\ORM\Mapping\Cla...::INHERITANCE_TYPE_NONE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
179
                // Evaluate discriminatorColumn
180
                if (isset($element['discriminatorColumn'])) {
181
                    $discrColumn = $element['discriminatorColumn'];
182
                    $metadata->setDiscriminatorColumn(
183
                        [
184
                            'name' => isset($discrColumn['name']) ? (string) $discrColumn['name'] : null,
185
                            'type' => (string) ($discrColumn['type'] ?? 'string'),
186
                            'length' => isset($discrColumn['length']) ? (string) $discrColumn['length'] : 255,
187
                            'columnDefinition' => isset($discrColumn['columnDefinition']) ? (string) $discrColumn['columnDefinition'] : null
188
                        ]
189
                    );
190
                } else {
191
                    $metadata->setDiscriminatorColumn(['name' => 'dtype', 'type' => 'string', 'length' => 255]);
192
                }
193
194
                // Evaluate discriminatorMap
195
                if (isset($element['discriminatorMap'])) {
196
                    $metadata->setDiscriminatorMap($element['discriminatorMap']);
197
                }
198
            }
199
        }
200
201
202
        // Evaluate changeTrackingPolicy
203
        if (isset($element['changeTrackingPolicy'])) {
204
            $metadata->setChangeTrackingPolicy(constant('Doctrine\ORM\Mapping\ClassMetadata::CHANGETRACKING_'
205
                . strtoupper($element['changeTrackingPolicy'])));
206
        }
207
208
        // Evaluate indexes
209
        if (isset($element['indexes'])) {
210
            foreach ($element['indexes'] as $name => $indexYml) {
211
                if ( ! isset($indexYml['name'])) {
212
                    $indexYml['name'] = $name;
213
                }
214
215 View Code Duplication
                if (is_string($indexYml['columns'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
216
                    $index = ['columns' => array_map('trim', explode(',', $indexYml['columns']))];
217
                } else {
218
                    $index = ['columns' => $indexYml['columns']];
219
                }
220
221
                if (isset($indexYml['flags'])) {
222
                    if (is_string($indexYml['flags'])) {
223
                        $index['flags'] = array_map('trim', explode(',', $indexYml['flags']));
224
                    } else {
225
                        $index['flags'] = $indexYml['flags'];
226
                    }
227
                }
228
229
                if (isset($indexYml['options'])) {
230
                    $index['options'] = $indexYml['options'];
231
                }
232
233
                $metadata->table['indexes'][$indexYml['name']] = $index;
234
            }
235
        }
236
237
        // Evaluate uniqueConstraints
238
        if (isset($element['uniqueConstraints'])) {
239
            foreach ($element['uniqueConstraints'] as $name => $uniqueYml) {
240
                if ( ! isset($uniqueYml['name'])) {
241
                    $uniqueYml['name'] = $name;
242
                }
243
244 View Code Duplication
                if (is_string($uniqueYml['columns'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
245
                    $unique = ['columns' => array_map('trim', explode(',', $uniqueYml['columns']))];
246
                } else {
247
                    $unique = ['columns' => $uniqueYml['columns']];
248
                }
249
250
                if (isset($uniqueYml['options'])) {
251
                    $unique['options'] = $uniqueYml['options'];
252
                }
253
254
                $metadata->table['uniqueConstraints'][$uniqueYml['name']] = $unique;
255
            }
256
        }
257
258
        if (isset($element['options'])) {
259
            $metadata->table['options'] = $element['options'];
260
        }
261
262
        $associationIds = [];
263
        if (isset($element['id'])) {
264
            // Evaluate identifier settings
265
            foreach ($element['id'] as $name => $idElement) {
266
                if (isset($idElement['associationKey']) && $idElement['associationKey'] == true) {
267
                    $associationIds[$name] = true;
268
                    continue;
269
                }
270
271
                $mapping = [
272
                    'id' => true,
273
                    'fieldName' => $name
274
                ];
275
276
                if (isset($idElement['type'])) {
277
                    $mapping['type'] = $idElement['type'];
278
                }
279
280
                if (isset($idElement['column'])) {
281
                    $mapping['columnName'] = $idElement['column'];
282
                }
283
284
                if (isset($idElement['length'])) {
285
                    $mapping['length'] = $idElement['length'];
286
                }
287
288
                if (isset($idElement['columnDefinition'])) {
289
                    $mapping['columnDefinition'] = $idElement['columnDefinition'];
290
                }
291
292
                if (isset($idElement['options'])) {
293
                    $mapping['options'] = $idElement['options'];
294
                }
295
296
                $metadata->mapField($mapping);
297
298 View Code Duplication
                if (isset($idElement['generator'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
299
                    $metadata->setIdGeneratorType(constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_'
300
                        . strtoupper($idElement['generator']['strategy'])));
301
                }
302
                // Check for SequenceGenerator/TableGenerator definition
303
                if (isset($idElement['sequenceGenerator'])) {
304
                    $metadata->setSequenceGeneratorDefinition($idElement['sequenceGenerator']);
305
                } else if (isset($idElement['customIdGenerator'])) {
306
                    $customGenerator = $idElement['customIdGenerator'];
307
                    $metadata->setCustomGeneratorDefinition(
308
                        [
309
                            'class' => (string) $customGenerator['class']
310
                        ]
311
                    );
312
                } else if (isset($idElement['tableGenerator'])) {
313
                    throw MappingException::tableIdGeneratorNotImplemented($className);
314
                }
315
            }
316
        }
317
318
        // Evaluate fields
319
        if (isset($element['fields'])) {
320
            foreach ($element['fields'] as $name => $fieldMapping) {
321
322
                $mapping = $this->columnToArray($name, $fieldMapping);
323
324
                if (isset($fieldMapping['id'])) {
325
                    $mapping['id'] = true;
326 View Code Duplication
                    if (isset($fieldMapping['generator']['strategy'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
327
                        $metadata->setIdGeneratorType(constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_'
328
                            . strtoupper($fieldMapping['generator']['strategy'])));
329
                    }
330
                }
331
332
                if (isset($mapping['version'])) {
333
                    $metadata->setVersionMapping($mapping);
334
                    unset($mapping['version']);
335
                }
336
337
                $metadata->mapField($mapping);
338
            }
339
        }
340
341
        if (isset($element['embedded'])) {
342
            foreach ($element['embedded'] as $name => $embeddedMapping) {
343
                $mapping = [
344
                    'fieldName' => $name,
345
                    'class' => $embeddedMapping['class'],
346
                    'columnPrefix' => $embeddedMapping['columnPrefix'] ?? null,
347
                ];
348
                $metadata->mapEmbedded($mapping);
349
            }
350
        }
351
352
        // Evaluate oneToOne relationships
353
        if (isset($element['oneToOne'])) {
354
            foreach ($element['oneToOne'] as $name => $oneToOneElement) {
355
                $mapping = [
356
                    'fieldName' => $name,
357
                    'targetEntity' => $oneToOneElement['targetEntity']
358
                ];
359
360
                if (isset($associationIds[$mapping['fieldName']])) {
361
                    $mapping['id'] = true;
362
                }
363
364 View Code Duplication
                if (isset($oneToOneElement['fetch'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
365
                    $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $oneToOneElement['fetch']);
366
                }
367
368
                if (isset($oneToOneElement['mappedBy'])) {
369
                    $mapping['mappedBy'] = $oneToOneElement['mappedBy'];
370
                } else {
371
                    if (isset($oneToOneElement['inversedBy'])) {
372
                        $mapping['inversedBy'] = $oneToOneElement['inversedBy'];
373
                    }
374
375
                    $joinColumns = [];
376
377 View Code Duplication
                    if (isset($oneToOneElement['joinColumn'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
378
                        $joinColumns[] = $this->joinColumnToArray($oneToOneElement['joinColumn']);
379
                    } else if (isset($oneToOneElement['joinColumns'])) {
380
                        foreach ($oneToOneElement['joinColumns'] as $joinColumnName => $joinColumnElement) {
381
                            if ( ! isset($joinColumnElement['name'])) {
382
                                $joinColumnElement['name'] = $joinColumnName;
383
                            }
384
385
                            $joinColumns[] = $this->joinColumnToArray($joinColumnElement);
386
                        }
387
                    }
388
389
                    $mapping['joinColumns'] = $joinColumns;
390
                }
391
392
                if (isset($oneToOneElement['cascade'])) {
393
                    $mapping['cascade'] = $oneToOneElement['cascade'];
394
                }
395
396
                if (isset($oneToOneElement['orphanRemoval'])) {
397
                    $mapping['orphanRemoval'] = (bool) $oneToOneElement['orphanRemoval'];
398
                }
399
400
                // Evaluate second level cache
401 View Code Duplication
                if (isset($oneToOneElement['cache'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
402
                    $mapping['cache'] = $metadata->getAssociationCacheDefaults($mapping['fieldName'], $this->cacheToArray($oneToOneElement['cache']));
403
                }
404
405
                $metadata->mapOneToOne($mapping);
406
            }
407
        }
408
409
        // Evaluate oneToMany relationships
410
        if (isset($element['oneToMany'])) {
411
            foreach ($element['oneToMany'] as $name => $oneToManyElement) {
412
                $mapping = [
413
                    'fieldName' => $name,
414
                    'targetEntity' => $oneToManyElement['targetEntity'],
415
                    'mappedBy' => $oneToManyElement['mappedBy']
416
                ];
417
418 View Code Duplication
                if (isset($oneToManyElement['fetch'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
419
                    $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $oneToManyElement['fetch']);
420
                }
421
422
                if (isset($oneToManyElement['cascade'])) {
423
                    $mapping['cascade'] = $oneToManyElement['cascade'];
424
                }
425
426
                if (isset($oneToManyElement['orphanRemoval'])) {
427
                    $mapping['orphanRemoval'] = (bool) $oneToManyElement['orphanRemoval'];
428
                }
429
430
                if (isset($oneToManyElement['orderBy'])) {
431
                    $mapping['orderBy'] = $oneToManyElement['orderBy'];
432
                }
433
434
                if (isset($oneToManyElement['indexBy'])) {
435
                    $mapping['indexBy'] = $oneToManyElement['indexBy'];
436
                }
437
438
439
                // Evaluate second level cache
440 View Code Duplication
                if (isset($oneToManyElement['cache'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
441
                    $mapping['cache'] = $metadata->getAssociationCacheDefaults($mapping['fieldName'], $this->cacheToArray($oneToManyElement['cache']));
442
                }
443
444
                $metadata->mapOneToMany($mapping);
445
            }
446
        }
447
448
        // Evaluate manyToOne relationships
449
        if (isset($element['manyToOne'])) {
450
            foreach ($element['manyToOne'] as $name => $manyToOneElement) {
451
                $mapping = [
452
                    'fieldName' => $name,
453
                    'targetEntity' => $manyToOneElement['targetEntity']
454
                ];
455
456
                if (isset($associationIds[$mapping['fieldName']])) {
457
                    $mapping['id'] = true;
458
                }
459
460 View Code Duplication
                if (isset($manyToOneElement['fetch'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
461
                    $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $manyToOneElement['fetch']);
462
                }
463
464
                if (isset($manyToOneElement['inversedBy'])) {
465
                    $mapping['inversedBy'] = $manyToOneElement['inversedBy'];
466
                }
467
468
                $joinColumns = [];
469
470 View Code Duplication
                if (isset($manyToOneElement['joinColumn'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
471
                    $joinColumns[] = $this->joinColumnToArray($manyToOneElement['joinColumn']);
472
                } else if (isset($manyToOneElement['joinColumns'])) {
473
                    foreach ($manyToOneElement['joinColumns'] as $joinColumnName => $joinColumnElement) {
474
                        if ( ! isset($joinColumnElement['name'])) {
475
                            $joinColumnElement['name'] = $joinColumnName;
476
                        }
477
478
                        $joinColumns[] = $this->joinColumnToArray($joinColumnElement);
479
                    }
480
                }
481
482
                $mapping['joinColumns'] = $joinColumns;
483
484
                if (isset($manyToOneElement['cascade'])) {
485
                    $mapping['cascade'] = $manyToOneElement['cascade'];
486
                }
487
488
                // Evaluate second level cache
489 View Code Duplication
                if (isset($manyToOneElement['cache'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
490
                    $mapping['cache'] = $metadata->getAssociationCacheDefaults($mapping['fieldName'], $this->cacheToArray($manyToOneElement['cache']));
491
                }
492
493
                $metadata->mapManyToOne($mapping);
494
            }
495
        }
496
497
        // Evaluate manyToMany relationships
498
        if (isset($element['manyToMany'])) {
499
            foreach ($element['manyToMany'] as $name => $manyToManyElement) {
500
                $mapping = [
501
                    'fieldName' => $name,
502
                    'targetEntity' => $manyToManyElement['targetEntity']
503
                ];
504
505 View Code Duplication
                if (isset($manyToManyElement['fetch'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
506
                    $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $manyToManyElement['fetch']);
507
                }
508
509
                if (isset($manyToManyElement['mappedBy'])) {
510
                    $mapping['mappedBy'] = $manyToManyElement['mappedBy'];
511
                } else if (isset($manyToManyElement['joinTable'])) {
512
513
                    $joinTableElement = $manyToManyElement['joinTable'];
514
                    $joinTable = [
515
                        'name' => $joinTableElement['name']
516
                    ];
517
518
                    if (isset($joinTableElement['schema'])) {
519
                        $joinTable['schema'] = $joinTableElement['schema'];
520
                    }
521
522 View Code Duplication
                    if (isset($joinTableElement['joinColumns'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
523
                        foreach ($joinTableElement['joinColumns'] as $joinColumnName => $joinColumnElement) {
524
                            if ( ! isset($joinColumnElement['name'])) {
525
                                $joinColumnElement['name'] = $joinColumnName;
526
                            }
527
                            $joinTable['joinColumns'][] = $this->joinColumnToArray($joinColumnElement);
528
                        }
529
                    }
530
531 View Code Duplication
                    if (isset($joinTableElement['inverseJoinColumns'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
532
                        foreach ($joinTableElement['inverseJoinColumns'] as $joinColumnName => $joinColumnElement) {
533
                            if ( ! isset($joinColumnElement['name'])) {
534
                                $joinColumnElement['name'] = $joinColumnName;
535
                            }
536
                            $joinTable['inverseJoinColumns'][] = $this->joinColumnToArray($joinColumnElement);
537
                        }
538
                    }
539
540
                    $mapping['joinTable'] = $joinTable;
541
                }
542
543
                if (isset($manyToManyElement['inversedBy'])) {
544
                    $mapping['inversedBy'] = $manyToManyElement['inversedBy'];
545
                }
546
547
                if (isset($manyToManyElement['cascade'])) {
548
                    $mapping['cascade'] = $manyToManyElement['cascade'];
549
                }
550
551
                if (isset($manyToManyElement['orderBy'])) {
552
                    $mapping['orderBy'] = $manyToManyElement['orderBy'];
553
                }
554
555
                if (isset($manyToManyElement['indexBy'])) {
556
                    $mapping['indexBy'] = $manyToManyElement['indexBy'];
557
                }
558
559
                if (isset($manyToManyElement['orphanRemoval'])) {
560
                    $mapping['orphanRemoval'] = (bool) $manyToManyElement['orphanRemoval'];
561
                }
562
563
                // Evaluate second level cache
564 View Code Duplication
                if (isset($manyToManyElement['cache'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
565
                    $mapping['cache'] = $metadata->getAssociationCacheDefaults($mapping['fieldName'], $this->cacheToArray($manyToManyElement['cache']));
566
                }
567
568
                $metadata->mapManyToMany($mapping);
569
            }
570
        }
571
572
        // Evaluate associationOverride
573
        if (isset($element['associationOverride']) && is_array($element['associationOverride'])) {
574
575
            foreach ($element['associationOverride'] as $fieldName => $associationOverrideElement) {
576
                $override   = [];
577
578
                // Check for joinColumn
579
                if (isset($associationOverrideElement['joinColumn'])) {
580
                    $joinColumns = [];
581
                    foreach ($associationOverrideElement['joinColumn'] as $name => $joinColumnElement) {
582
                        if ( ! isset($joinColumnElement['name'])) {
583
                            $joinColumnElement['name'] = $name;
584
                        }
585
                        $joinColumns[] = $this->joinColumnToArray($joinColumnElement);
586
                    }
587
                    $override['joinColumns'] = $joinColumns;
588
                }
589
590
                // Check for joinTable
591
                if (isset($associationOverrideElement['joinTable'])) {
592
593
                    $joinTableElement   = $associationOverrideElement['joinTable'];
594
                    $joinTable          =  [
595
                        'name' => $joinTableElement['name']
596
                    ];
597
598
                    if (isset($joinTableElement['schema'])) {
599
                        $joinTable['schema'] = $joinTableElement['schema'];
600
                    }
601
602
                    foreach ($joinTableElement['joinColumns'] as $name => $joinColumnElement) {
603
                        if ( ! isset($joinColumnElement['name'])) {
604
                            $joinColumnElement['name'] = $name;
605
                        }
606
607
                        $joinTable['joinColumns'][] = $this->joinColumnToArray($joinColumnElement);
608
                    }
609
610
                    foreach ($joinTableElement['inverseJoinColumns'] as $name => $joinColumnElement) {
611
                        if ( ! isset($joinColumnElement['name'])) {
612
                            $joinColumnElement['name'] = $name;
613
                        }
614
615
                        $joinTable['inverseJoinColumns'][] = $this->joinColumnToArray($joinColumnElement);
616
                    }
617
618
                    $override['joinTable'] = $joinTable;
619
                }
620
621
                // Check for inversedBy
622
                if (isset($associationOverrideElement['inversedBy'])) {
623
                    $override['inversedBy'] = (string) $associationOverrideElement['inversedBy'];
624
                }
625
626
                // Check for `fetch`
0 ignored issues
show
Unused Code Comprehensibility introduced by
38% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
627
                if (isset($associationOverrideElement['fetch'])) {
628
                    $override['fetch'] = constant(Metadata::class . '::FETCH_' . $associationOverrideElement['fetch']);
629
                }
630
631
                $metadata->setAssociationOverride($fieldName, $override);
632
            }
633
        }
634
635
        // Evaluate associationOverride
636
        if (isset($element['attributeOverride']) && is_array($element['attributeOverride'])) {
637
638
            foreach ($element['attributeOverride'] as $fieldName => $attributeOverrideElement) {
639
                $mapping = $this->columnToArray($fieldName, $attributeOverrideElement);
640
                $metadata->setAttributeOverride($fieldName, $mapping);
641
            }
642
        }
643
644
        // Evaluate lifeCycleCallbacks
645
        if (isset($element['lifecycleCallbacks'])) {
646
            foreach ($element['lifecycleCallbacks'] as $type => $methods) {
647
                foreach ($methods as $method) {
648
                    $metadata->addLifecycleCallback($method, constant('Doctrine\ORM\Events::' . $type));
649
                }
650
            }
651
        }
652
653
        // Evaluate entityListeners
654
        if (isset($element['entityListeners'])) {
655
            foreach ($element['entityListeners'] as $className => $entityListener) {
656
                // Evaluate the listener using naming convention.
657
                if (empty($entityListener)) {
658
                    EntityListenerBuilder::bindEntityListener($metadata, $className);
659
660
                    continue;
661
                }
662
663
                foreach ($entityListener as $eventName => $callbackElement) {
664
                    foreach ($callbackElement as $methodName) {
665
                        $metadata->addEntityListener($eventName, $className, $methodName);
666
                    }
667
                }
668
            }
669
        }
670
    }
671
672
    /**
673
     * Constructs a joinColumn mapping array based on the information
674
     * found in the given join column element.
675
     *
676
     * @param array $joinColumnElement The array join column element.
677
     *
678
     * @return array The mapping array.
679
     */
680
    private function joinColumnToArray($joinColumnElement)
681
    {
682
        $joinColumn = [];
683
        if (isset($joinColumnElement['referencedColumnName'])) {
684
            $joinColumn['referencedColumnName'] = (string) $joinColumnElement['referencedColumnName'];
685
        }
686
687
        if (isset($joinColumnElement['name'])) {
688
            $joinColumn['name'] = (string) $joinColumnElement['name'];
689
        }
690
691
        if (isset($joinColumnElement['fieldName'])) {
692
            $joinColumn['fieldName'] = (string) $joinColumnElement['fieldName'];
693
        }
694
695
        if (isset($joinColumnElement['unique'])) {
696
            $joinColumn['unique'] = (bool) $joinColumnElement['unique'];
697
        }
698
699
        if (isset($joinColumnElement['nullable'])) {
700
            $joinColumn['nullable'] = (bool) $joinColumnElement['nullable'];
701
        }
702
703
        if (isset($joinColumnElement['onDelete'])) {
704
            $joinColumn['onDelete'] = $joinColumnElement['onDelete'];
705
        }
706
707
        if (isset($joinColumnElement['columnDefinition'])) {
708
            $joinColumn['columnDefinition'] = $joinColumnElement['columnDefinition'];
709
        }
710
711
        return $joinColumn;
712
    }
713
714
    /**
715
     * Parses the given column as array.
716
     *
717
     * @param string $fieldName
718
     * @param array  $column
719
     *
720
     * @return  array
721
     */
722
    private function columnToArray($fieldName, $column)
723
    {
724
        $mapping = [
725
            'fieldName' => $fieldName
726
        ];
727
728
        if (isset($column['type'])) {
729
            $params = explode('(', $column['type']);
730
731
            $column['type']  = $params[0];
732
            $mapping['type'] = $column['type'];
733
734
            if (isset($params[1])) {
735
                $column['length'] = (integer) substr($params[1], 0, strlen($params[1]) - 1);
736
            }
737
        }
738
739
        if (isset($column['column'])) {
740
            $mapping['columnName'] = $column['column'];
741
        }
742
743
        if (isset($column['length'])) {
744
            $mapping['length'] = $column['length'];
745
        }
746
747
        if (isset($column['precision'])) {
748
            $mapping['precision'] = $column['precision'];
749
        }
750
751
        if (isset($column['scale'])) {
752
            $mapping['scale'] = $column['scale'];
753
        }
754
755
        if (isset($column['unique'])) {
756
            $mapping['unique'] = (bool) $column['unique'];
757
        }
758
759
        if (isset($column['options'])) {
760
            $mapping['options'] = $column['options'];
761
        }
762
763
        if (isset($column['nullable'])) {
764
            $mapping['nullable'] = $column['nullable'];
765
        }
766
767
        if (isset($column['version']) && $column['version']) {
768
            $mapping['version'] = $column['version'];
769
        }
770
771
        if (isset($column['columnDefinition'])) {
772
            $mapping['columnDefinition'] = $column['columnDefinition'];
773
        }
774
775
        return $mapping;
776
    }
777
778
    /**
779
     * Parse / Normalize the cache configuration
780
     *
781
     * @param array $cacheMapping
782
     *
783
     * @return array
784
     */
785
    private function cacheToArray($cacheMapping)
786
    {
787
        $region = isset($cacheMapping['region']) ? (string) $cacheMapping['region'] : null;
788
        $usage  = isset($cacheMapping['usage']) ? strtoupper($cacheMapping['usage']) : null;
789
790
        if ($usage && ! defined('Doctrine\ORM\Mapping\ClassMetadata::CACHE_USAGE_' . $usage)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $usage of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
791
            throw new \InvalidArgumentException(sprintf('Invalid cache usage "%s"', $usage));
792
        }
793
794
        if ($usage) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $usage of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
795
            $usage = constant('Doctrine\ORM\Mapping\ClassMetadata::CACHE_USAGE_' . $usage);
796
        }
797
798
        return [
799
            'usage'  => $usage,
800
            'region' => $region,
801
        ];
802
    }
803
804
    /**
805
     * {@inheritDoc}
806
     */
807
    protected function loadMappingFile($file)
808
    {
809
        return Yaml::parse(file_get_contents($file));
0 ignored issues
show
Bug introduced by
It seems like file_get_contents($file) can also be of type false; however, parameter $input of Symfony\Component\Yaml\Yaml::parse() 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

809
        return Yaml::parse(/** @scrutinizer ignore-type */ file_get_contents($file));
Loading history...
810
    }
811
}
812