Completed
Pull Request — master (#5938)
by Maximilian
18:05 queued 10:56
created

YamlDriver::loadMetadataForClass()   F

Complexity

Conditions 153
Paths > 20000

Size

Total Lines 610
Code Lines 320

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 276
CRAP Score 175.0323

Importance

Changes 3
Bugs 2 Features 1
Metric Value
c 3
b 2
f 1
dl 0
loc 610
ccs 276
cts 306
cp 0.902
rs 2
cc 153
eloc 320
nc 153354241
nop 2
crap 175.0323

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;
24
use Doctrine\Common\Persistence\Mapping\Driver\FileDriver;
25
use Doctrine\ORM\Mapping\MappingException;
26
use Symfony\Component\Yaml\Yaml;
27
28
/**
29
 * The YamlDriver reads the mapping metadata from yaml schema files.
30
 *
31
 * @since 2.0
32
 * @author Benjamin Eberlei <[email protected]>
33
 * @author Guilherme Blanco <[email protected]>
34
 * @author Jonathan H. Wage <[email protected]>
35
 * @author Roman Borschel <[email protected]>
36
 */
37
class YamlDriver extends FileDriver
38
{
39
    const DEFAULT_FILE_EXTENSION = '.dcm.yml';
40
41
    /**
42
     * {@inheritDoc}
43
     */
44 69
    public function __construct($locator, $fileExtension = self::DEFAULT_FILE_EXTENSION)
45
    {
46 69
        parent::__construct($locator, $fileExtension);
47 69
    }
48
49
    /**
50
     * {@inheritDoc}
51
     */
52 64
    public function loadMetadataForClass($className, ClassMetadata $metadata)
53
    {
54
        /* @var $metadata \Doctrine\ORM\Mapping\ClassMetadataInfo */
55 64
        $element = $this->getElement($className);
56
57 62
        if ($element['type'] == 'entity') {
58 58
            if (isset($element['repositoryClass'])) {
59
                $metadata->setCustomRepositoryClass($element['repositoryClass']);
60
            }
61 58
            if (isset($element['readOnly']) && $element['readOnly'] == true) {
62 58
                $metadata->markReadOnly();
63
            }
64 16
        } else if ($element['type'] == 'mappedSuperclass') {
65 14
            $metadata->setCustomRepositoryClass(
66 14
                isset($element['repositoryClass']) ? $element['repositoryClass'] : null
67
            );
68 14
            $metadata->isMappedSuperclass = true;
69 2
        } else if ($element['type'] == 'embeddable') {
70
            $metadata->isEmbeddedClass = true;
71
        } else {
72 2
            throw MappingException::classIsNotAValidEntityOrMappedSuperClass($className);
73
        }
74
75
        // Evaluate root level properties
76 60
        $primaryTable = array();
77
78 60
        if (isset($element['table'])) {
79 24
            $primaryTable['name'] = $element['table'];
80
        }
81
82 60
        if (isset($element['schema'])) {
83 2
            $primaryTable['schema'] = $element['schema'];
84
        }
85
86
        // Evaluate second level cache
87 60
        if (isset($element['cache'])) {
88 2
            $metadata->enableCache($this->cacheToArray($element['cache']));
89
        }
90
91 60
        $metadata->setPrimaryTable($primaryTable);
92
93
        // Evaluate named queries
94 60
        if (isset($element['namedQueries'])) {
95 6
            foreach ($element['namedQueries'] as $name => $queryMapping) {
96 6
                if (is_string($queryMapping)) {
97 6
                    $queryMapping = array('query' => $queryMapping);
98
                }
99
100 6
                if ( ! isset($queryMapping['name'])) {
101 6
                    $queryMapping['name'] = $name;
102
                }
103
104 6
                $metadata->addNamedQuery($queryMapping);
105
            }
106
        }
107
108
        // Evaluate named native queries
109 60
        if (isset($element['namedNativeQueries'])) {
110 6
            foreach ($element['namedNativeQueries'] as $name => $mappingElement) {
111 6
                if (!isset($mappingElement['name'])) {
112 6
                    $mappingElement['name'] = $name;
113
                }
114 6
                $metadata->addNamedNativeQuery(array(
115 6
                    'name'              => $mappingElement['name'],
116 6
                    'query'             => isset($mappingElement['query']) ? $mappingElement['query'] : null,
117 6
                    'resultClass'       => isset($mappingElement['resultClass']) ? $mappingElement['resultClass'] : null,
118 6
                    'resultSetMapping'  => isset($mappingElement['resultSetMapping']) ? $mappingElement['resultSetMapping'] : null,
119
                ));
120
            }
121
        }
122
123
        // Evaluate sql result set mappings
124 60
        if (isset($element['sqlResultSetMappings'])) {
125 6
            foreach ($element['sqlResultSetMappings'] as $name => $resultSetMapping) {
126 6
                if (!isset($resultSetMapping['name'])) {
127 6
                    $resultSetMapping['name'] = $name;
128
                }
129
130 6
                $entities = array();
131 6
                $columns  = array();
132 6
                if (isset($resultSetMapping['entityResult'])) {
133 6
                    foreach ($resultSetMapping['entityResult'] as $entityResultElement) {
134
                        $entityResult = array(
135 6
                            'fields'                => array(),
136 6
                            'entityClass'           => isset($entityResultElement['entityClass']) ? $entityResultElement['entityClass'] : null,
137 6
                            'discriminatorColumn'   => isset($entityResultElement['discriminatorColumn']) ? $entityResultElement['discriminatorColumn'] : null,
138
                        );
139
140 6
                        if (isset($entityResultElement['fieldResult'])) {
141 6
                            foreach ($entityResultElement['fieldResult'] as $fieldResultElement) {
142 6
                                $entityResult['fields'][] = array(
143 6
                                    'name'      => isset($fieldResultElement['name']) ? $fieldResultElement['name'] : null,
144 6
                                    'column'    => isset($fieldResultElement['column']) ? $fieldResultElement['column'] : null,
145
                                );
146
                            }
147
                        }
148
149 6
                        $entities[] = $entityResult;
150
                    }
151
                }
152
153
154 6
                if (isset($resultSetMapping['columnResult'])) {
155 6
                    foreach ($resultSetMapping['columnResult'] as $columnResultAnnot) {
156 6
                        $columns[] = array(
157 6
                            'name' => isset($columnResultAnnot['name']) ? $columnResultAnnot['name'] : null,
158
                        );
159
                    }
160
                }
161
162 6
                $metadata->addSqlResultSetMapping(array(
163 6
                    'name'          => $resultSetMapping['name'],
164 6
                    'entities'      => $entities,
165 6
                    'columns'       => $columns
166
                ));
167
            }
168
        }
169
170 60
        if (isset($element['inheritanceType'])) {
171 18
            $metadata->setInheritanceType(constant('Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_' . strtoupper($element['inheritanceType'])));
172
173 18
            if ($metadata->inheritanceType != \Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_NONE) {
174
                // Evaluate discriminatorColumn
175 18
                if (isset($element['discriminatorColumn'])) {
176 12
                    $discrColumn = $element['discriminatorColumn'];
177 12
                    $metadata->setDiscriminatorColumn(array(
178 12
                        'name' => isset($discrColumn['name']) ? (string) $discrColumn['name'] : null,
179 12
                        'type' => isset($discrColumn['type']) ? (string) $discrColumn['type'] : 'string',
180 12
                        'length' => isset($discrColumn['length']) ? (string) $discrColumn['length'] : 255,
181 12
                        'columnDefinition' => isset($discrColumn['columnDefinition']) ? (string) $discrColumn['columnDefinition'] : null
182
                    ));
183
                } else {
184 12
                    $metadata->setDiscriminatorColumn(array('name' => 'dtype', 'type' => 'string', 'length' => 255));
185
                }
186
187
                // Evaluate discriminatorMap
188 18
                if (isset($element['discriminatorMap'])) {
189 18
                    $metadata->setDiscriminatorMap($element['discriminatorMap']);
190
                }
191
            }
192
        }
193
194
195
        // Evaluate changeTrackingPolicy
196 60
        if (isset($element['changeTrackingPolicy'])) {
197
            $metadata->setChangeTrackingPolicy(constant('Doctrine\ORM\Mapping\ClassMetadata::CHANGETRACKING_'
198
                . strtoupper($element['changeTrackingPolicy'])));
199
        }
200
201
        // Evaluate indexes
202 60
        if (isset($element['indexes'])) {
203 8
            foreach ($element['indexes'] as $name => $indexYml) {
204 8
                if ( ! isset($indexYml['name'])) {
205 8
                    $indexYml['name'] = $name;
206
                }
207
208 8
                if (is_string($indexYml['columns'])) {
209 8
                    $index = array('columns' => array_map('trim', explode(',', $indexYml['columns'])));
210
                } else {
211
                    $index = array('columns' => $indexYml['columns']);
212
                }
213
214 8
                if (isset($indexYml['flags'])) {
215 2
                    if (is_string($indexYml['flags'])) {
216 2
                        $index['flags'] = array_map('trim', explode(',', $indexYml['flags']));
217
                    } else {
218
                        $index['flags'] = $indexYml['flags'];
219
                    }
220
                }
221
222 8
                if (isset($indexYml['options'])) {
223 2
                    $index['options'] = $indexYml['options'];
224
                }
225
226 8
                $metadata->table['indexes'][$indexYml['name']] = $index;
227
            }
228
        }
229
230
        // Evaluate uniqueConstraints
231 60
        if (isset($element['uniqueConstraints'])) {
232 7
            foreach ($element['uniqueConstraints'] as $name => $uniqueYml) {
233 7
                if ( ! isset($uniqueYml['name'])) {
234 7
                    $uniqueYml['name'] = $name;
235
                }
236
237 7
                if (is_string($uniqueYml['columns'])) {
238 6
                    $unique = array('columns' => array_map('trim', explode(',', $uniqueYml['columns'])));
239
                } else {
240 1
                    $unique = array('columns' => $uniqueYml['columns']);
241
                }
242
243 7
                if (isset($uniqueYml['options'])) {
244 4
                    $unique['options'] = $uniqueYml['options'];
245
                }
246
247 7
                $metadata->table['uniqueConstraints'][$uniqueYml['name']] = $unique;
248
            }
249
        }
250
251 60
        if (isset($element['options'])) {
252 6
            $metadata->table['options'] = $element['options'];
253
        }
254
255 60
        $associationIds = array();
256 60
        if (isset($element['id'])) {
257
            // Evaluate identifier settings
258 56
            foreach ($element['id'] as $name => $idElement) {
259 56
                if (isset($idElement['associationKey']) && $idElement['associationKey'] == true) {
260
                    $associationIds[$name] = true;
261
                    continue;
262
                }
263
264
                $mapping = array(
265 56
                    'id' => true,
266 56
                    'fieldName' => $name
267
                );
268
269 56
                if (isset($idElement['type'])) {
270 36
                    $mapping['type'] = $idElement['type'];
271
                }
272
273 56
                if (isset($idElement['column'])) {
274 8
                    $mapping['columnName'] = $idElement['column'];
275
                }
276
277 56
                if (isset($idElement['length'])) {
278 6
                    $mapping['length'] = $idElement['length'];
279
                }
280
281 56
                if (isset($idElement['columnDefinition'])) {
282 2
                    $mapping['columnDefinition'] = $idElement['columnDefinition'];
283
                }
284
285 56
                if (isset($idElement['options'])) {
286 4
                    $mapping['options'] = $idElement['options'];
287
                }
288
289 56
                $metadata->mapField($mapping);
290
291 56
                if (isset($idElement['generator'])) {
292 53
                    $metadata->setIdGeneratorType(constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_'
293 53
                        . strtoupper($idElement['generator']['strategy'])));
294
                }
295
                // Check for SequenceGenerator/TableGenerator definition
296 56
                if (isset($idElement['sequenceGenerator'])) {
297 4
                    $metadata->setSequenceGeneratorDefinition($idElement['sequenceGenerator']);
298 52
                } else if (isset($idElement['customIdGenerator'])) {
299 4
                    $customGenerator = $idElement['customIdGenerator'];
300 4
                    $metadata->setCustomGeneratorDefinition(array(
301 4
                        'class' => (string) $customGenerator['class']
302
                    ));
303 48
                } else if (isset($idElement['tableGenerator'])) {
304 56
                    throw MappingException::tableIdGeneratorNotImplemented($className);
305
                }
306
            }
307
        }
308
309
        // Evaluate fields
310 60
        if (isset($element['fields'])) {
311 41
            foreach ($element['fields'] as $name => $fieldMapping) {
312
313 41
                $mapping = $this->columnToArray($name, $fieldMapping);
314
315 41
                if (isset($fieldMapping['id'])) {
316
                    $mapping['id'] = true;
317
                    if (isset($fieldMapping['generator']['strategy'])) {
318
                        $metadata->setIdGeneratorType(constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_'
319
                            . strtoupper($fieldMapping['generator']['strategy'])));
320
                    }
321
                }
322
323 41
                if (isset($mapping['version'])) {
324 4
                    $metadata->setVersionMapping($mapping);
325 4
                    unset($mapping['version']);
326
                }
327
328 41
                $metadata->mapField($mapping);
329
            }
330
        }
331
332 60
        if (isset($element['embedded'])) {
333
            foreach ($element['embedded'] as $name => $embeddedMapping) {
334
                $mapping = array(
335
                    'fieldName' => $name,
336
                    'class' => $embeddedMapping['class'],
337
                    'columnPrefix' => isset($embeddedMapping['columnPrefix']) ? $embeddedMapping['columnPrefix'] : null,
338
                );
339
                $metadata->mapEmbedded($mapping);
340
            }
341
        }
342
343
        // Evaluate oneToOne relationships
344 60
        if (isset($element['oneToOne'])) {
345 13
            foreach ($element['oneToOne'] as $name => $oneToOneElement) {
346
                $mapping = array(
347 13
                    'fieldName' => $name,
348 13
                    'targetEntity' => $oneToOneElement['targetEntity']
349
                );
350
351 13
                if (isset($associationIds[$mapping['fieldName']])) {
352
                    $mapping['id'] = true;
353
                }
354
355 13
                if (isset($oneToOneElement['fetch'])) {
356 3
                    $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $oneToOneElement['fetch']);
357
                }
358
359 13
                if (isset($oneToOneElement['mappedBy'])) {
360 3
                    $mapping['mappedBy'] = $oneToOneElement['mappedBy'];
361
                } else {
362 12
                    if (isset($oneToOneElement['inversedBy'])) {
363 12
                        $mapping['inversedBy'] = $oneToOneElement['inversedBy'];
364
                    }
365
366 12
                    $joinColumns = array();
367
368 12
                    if (isset($oneToOneElement['joinColumn'])) {
369 11
                        $joinColumns[] = $this->joinColumnToArray($oneToOneElement['joinColumn']);
370 1
                    } else if (isset($oneToOneElement['joinColumns'])) {
371 1
                        foreach ($oneToOneElement['joinColumns'] as $joinColumnName => $joinColumnElement) {
372 1
                            if ( ! isset($joinColumnElement['name'])) {
373 1
                                $joinColumnElement['name'] = $joinColumnName;
374
                            }
375
376 1
                            $joinColumns[] = $this->joinColumnToArray($joinColumnElement);
377
                        }
378
                    }
379
380 12
                    $mapping['joinColumns'] = $joinColumns;
381
                }
382
383 13
                if (isset($oneToOneElement['cascade'])) {
384 9
                    $mapping['cascade'] = $oneToOneElement['cascade'];
385
                }
386
387 13
                if (isset($oneToOneElement['orphanRemoval'])) {
388 5
                    $mapping['orphanRemoval'] = (bool) $oneToOneElement['orphanRemoval'];
389
                }
390
391
                // Evaluate second level cache
392 13
                if (isset($oneToOneElement['cache'])) {
393
                    $mapping['cache'] = $metadata->getAssociationCacheDefaults($mapping['fieldName'], $this->cacheToArray($oneToOneElement['cache']));
394
                }
395
396 13
                $metadata->mapOneToOne($mapping);
397
            }
398
        }
399
400
        // Evaluate oneToMany relationships
401 60
        if (isset($element['oneToMany'])) {
402 8
            foreach ($element['oneToMany'] as $name => $oneToManyElement) {
403
                $mapping = array(
404 8
                    'fieldName' => $name,
405 8
                    'targetEntity' => $oneToManyElement['targetEntity'],
406 8
                    'mappedBy' => $oneToManyElement['mappedBy']
407
                );
408
409 8
                if (isset($oneToManyElement['fetch'])) {
410 2
                    $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $oneToManyElement['fetch']);
411
                }
412
413 8
                if (isset($oneToManyElement['cascade'])) {
414 6
                    $mapping['cascade'] = $oneToManyElement['cascade'];
415
                }
416
417 8
                if (isset($oneToManyElement['orphanRemoval'])) {
418 6
                    $mapping['orphanRemoval'] = (bool) $oneToManyElement['orphanRemoval'];
419
                }
420
421 8
                if (isset($oneToManyElement['orderBy'])) {
422 8
                    $mapping['orderBy'] = $oneToManyElement['orderBy'];
423
                }
424
425 8
                if (isset($oneToManyElement['indexBy'])) {
426
                    $mapping['indexBy'] = $oneToManyElement['indexBy'];
427
                }
428
429
430
                // Evaluate second level cache
431 8
                if (isset($oneToManyElement['cache'])) {
432 2
                    $mapping['cache'] = $metadata->getAssociationCacheDefaults($mapping['fieldName'], $this->cacheToArray($oneToManyElement['cache']));
433
                }
434
435 8
                $metadata->mapOneToMany($mapping);
436
            }
437
        }
438
439
        // Evaluate manyToOne relationships
440 60
        if (isset($element['manyToOne'])) {
441 10
            foreach ($element['manyToOne'] as $name => $manyToOneElement) {
442
                $mapping = array(
443 10
                    'fieldName' => $name,
444 10
                    'targetEntity' => $manyToOneElement['targetEntity']
445
                );
446
447 10
                if (isset($associationIds[$mapping['fieldName']])) {
448
                    $mapping['id'] = true;
449
                }
450
451 10
                if (isset($manyToOneElement['fetch'])) {
452 1
                    $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $manyToOneElement['fetch']);
453
                }
454
455 10
                if (isset($manyToOneElement['inversedBy'])) {
456 2
                    $mapping['inversedBy'] = $manyToOneElement['inversedBy'];
457
                }
458
459 10
                $joinColumns = array();
460
461 10
                if (isset($manyToOneElement['joinColumn'])) {
462 4
                    $joinColumns[] = $this->joinColumnToArray($manyToOneElement['joinColumn']);
463 6
                } else if (isset($manyToOneElement['joinColumns'])) {
464 3
                    foreach ($manyToOneElement['joinColumns'] as $joinColumnName => $joinColumnElement) {
465 3
                        if ( ! isset($joinColumnElement['name'])) {
466 3
                            $joinColumnElement['name'] = $joinColumnName;
467
                        }
468
469 3
                        $joinColumns[] = $this->joinColumnToArray($joinColumnElement);
470
                    }
471
                }
472
473 10
                $mapping['joinColumns'] = $joinColumns;
474
475 10
                if (isset($manyToOneElement['cascade'])) {
476 5
                    $mapping['cascade'] = $manyToOneElement['cascade'];
477
                }
478
479
                // Evaluate second level cache
480 10
                if (isset($manyToOneElement['cache'])) {
481 2
                    $mapping['cache'] = $metadata->getAssociationCacheDefaults($mapping['fieldName'], $this->cacheToArray($manyToOneElement['cache']));
482
                }
483
484 10
                $metadata->mapManyToOne($mapping);
485
            }
486
        }
487
488
        // Evaluate manyToMany relationships
489 60
        if (isset($element['manyToMany'])) {
490 19
            foreach ($element['manyToMany'] as $name => $manyToManyElement) {
491
                $mapping = array(
492 19
                    'fieldName' => $name,
493 19
                    'targetEntity' => $manyToManyElement['targetEntity']
494
                );
495
496 19
                if (isset($manyToManyElement['fetch'])) {
497 2
                    $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $manyToManyElement['fetch']);
498
                }
499
500 19
                if (isset($manyToManyElement['mappedBy'])) {
501 4
                    $mapping['mappedBy'] = $manyToManyElement['mappedBy'];
502 15
                } else if (isset($manyToManyElement['joinTable'])) {
503
504 13
                    $joinTableElement = $manyToManyElement['joinTable'];
505
                    $joinTable = array(
506 13
                        'name' => $joinTableElement['name']
507
                    );
508
509 13
                    if (isset($joinTableElement['schema'])) {
510
                        $joinTable['schema'] = $joinTableElement['schema'];
511
                    }
512
513 13
                    if (isset($joinTableElement['joinColumns'])) {
514 13
                        foreach ($joinTableElement['joinColumns'] as $joinColumnName => $joinColumnElement) {
515 13
                            if ( ! isset($joinColumnElement['name'])) {
516 12
                                $joinColumnElement['name'] = $joinColumnName;
517
                            }
518 13
                            $joinTable['joinColumns'][] = $this->joinColumnToArray($joinColumnElement);
519
                        }
520
                    }
521
522 13
                    if (isset($joinTableElement['inverseJoinColumns'])) {
523 13
                        foreach ($joinTableElement['inverseJoinColumns'] as $joinColumnName => $joinColumnElement) {
524 13
                            if ( ! isset($joinColumnElement['name'])) {
525 12
                                $joinColumnElement['name'] = $joinColumnName;
526
                            }
527 13
                            $joinTable['inverseJoinColumns'][] = $this->joinColumnToArray($joinColumnElement);
528
                        }
529
                    }
530
531 13
                    $mapping['joinTable'] = $joinTable;
532
                }
533
534 19
                if (isset($manyToManyElement['inversedBy'])) {
535
                    $mapping['inversedBy'] = $manyToManyElement['inversedBy'];
536
                }
537
538 19
                if (isset($manyToManyElement['cascade'])) {
539 12
                    $mapping['cascade'] = $manyToManyElement['cascade'];
540
                }
541
542 19
                if (isset($manyToManyElement['orderBy'])) {
543
                    $mapping['orderBy'] = $manyToManyElement['orderBy'];
544
                }
545
546 19
                if (isset($manyToManyElement['indexBy'])) {
547
                    $mapping['indexBy'] = $manyToManyElement['indexBy'];
548
                }
549
550 19
                if (isset($manyToManyElement['orphanRemoval'])) {
551
                    $mapping['orphanRemoval'] = (bool) $manyToManyElement['orphanRemoval'];
552
                }
553
554
                // Evaluate second level cache
555 19
                if (isset($manyToManyElement['cache'])) {
556
                    $mapping['cache'] = $metadata->getAssociationCacheDefaults($mapping['fieldName'], $this->cacheToArray($manyToManyElement['cache']));
557
                }
558
559 19
                $metadata->mapManyToMany($mapping);
560
            }
561
        }
562
563
        // Evaluate associationOverride
564 60
        if (isset($element['associationOverride']) && is_array($element['associationOverride'])) {
565
566 6
            foreach ($element['associationOverride'] as $fieldName => $associationOverrideElement) {
567 6
                $override   = array();
568
569
                // Check for joinColumn
570 6
                if (isset($associationOverrideElement['joinColumn'])) {
571 4
                    $joinColumns = array();
572 4
                    foreach ($associationOverrideElement['joinColumn'] as $name => $joinColumnElement) {
573 4
                        if ( ! isset($joinColumnElement['name'])) {
574
                            $joinColumnElement['name'] = $name;
575
                        }
576 4
                        $joinColumns[] = $this->joinColumnToArray($joinColumnElement);
577
                    }
578 4
                    $override['joinColumns'] = $joinColumns;
579
                }
580
581
                // Check for joinTable
582 6
                if (isset($associationOverrideElement['joinTable'])) {
583
584 4
                    $joinTableElement   = $associationOverrideElement['joinTable'];
585
                    $joinTable          =  array(
586 4
                        'name' => $joinTableElement['name']
587
                    );
588
589 4
                    if (isset($joinTableElement['schema'])) {
590
                        $joinTable['schema'] = $joinTableElement['schema'];
591
                    }
592
593 4
                    foreach ($joinTableElement['joinColumns'] as $name => $joinColumnElement) {
594 4
                        if ( ! isset($joinColumnElement['name'])) {
595 4
                            $joinColumnElement['name'] = $name;
596
                        }
597
598 4
                        $joinTable['joinColumns'][] = $this->joinColumnToArray($joinColumnElement);
599
                    }
600
601 4
                    foreach ($joinTableElement['inverseJoinColumns'] as $name => $joinColumnElement) {
602 4
                        if ( ! isset($joinColumnElement['name'])) {
603 4
                            $joinColumnElement['name'] = $name;
604
                        }
605
606 4
                        $joinTable['inverseJoinColumns'][] = $this->joinColumnToArray($joinColumnElement);
607
                    }
608
609 4
                    $override['joinTable'] = $joinTable;
610
                }
611
612
                // Check for inversedBy
613 6
                if (isset($associationOverrideElement['inversedBy'])) {
614 2
                    $override['inversedBy'] = (string) $associationOverrideElement['inversedBy'];
615
                }
616
617
                // Check for `fetch`
618 6
                if (isset($associationOverrideElement['fetch'])) {
619
                    $override['fetch'] = (string) $associationOverrideElement['fetch'];
620
                }
621
622 6
                $metadata->setAssociationOverride($fieldName, $override);
623
            }
624
        }
625
626
        // Evaluate associationOverride
627 60
        if (isset($element['attributeOverride']) && is_array($element['attributeOverride'])) {
628
629 4
            foreach ($element['attributeOverride'] as $fieldName => $attributeOverrideElement) {
630 4
                $mapping = $this->columnToArray($fieldName, $attributeOverrideElement);
631 4
                $metadata->setAttributeOverride($fieldName, $mapping);
632
            }
633
        }
634
635
        // Evaluate lifeCycleCallbacks
636 60
        if (isset($element['lifecycleCallbacks'])) {
637 7
            foreach ($element['lifecycleCallbacks'] as $type => $methods) {
638 6
                foreach ($methods as $method) {
639 6
                    $metadata->addLifecycleCallback($method, constant('Doctrine\ORM\Events::' . $type));
640
                }
641
            }
642
        }
643
644
        // Evaluate entityListeners
645 60
        if (isset($element['entityListeners'])) {
646 8
            foreach ($element['entityListeners'] as $className => $entityListener) {
647
                // Evaluate the listener using naming convention.
648 8
                if (empty($entityListener)) {
649 4
                    EntityListenerBuilder::bindEntityListener($metadata, $className);
0 ignored issues
show
Compatibility introduced by
$metadata of type object<Doctrine\ORM\Mapping\ClassMetadataInfo> is not a sub-type of object<Doctrine\ORM\Mapping\ClassMetadata>. It seems like you assume a child class of the class Doctrine\ORM\Mapping\ClassMetadataInfo to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
650
651 4
                    continue;
652
                }
653
654 4
                foreach ($entityListener as $eventName => $callbackElement) {
655 4
                    foreach ($callbackElement as $methodName) {
656 4
                        $metadata->addEntityListener($eventName, $className, $methodName);
657
                    }
658
                }
659
            }
660
        }
661 60
    }
662
663
    /**
664
     * Constructs a joinColumn mapping array based on the information
665
     * found in the given join column element.
666
     *
667
     * @param array $joinColumnElement The array join column element.
668
     *
669
     * @return array The mapping array.
670
     */
671 19
    private function joinColumnToArray($joinColumnElement)
672
    {
673 19
        $joinColumn = array();
674 19
        if (isset($joinColumnElement['referencedColumnName'])) {
675 19
            $joinColumn['referencedColumnName'] = (string) $joinColumnElement['referencedColumnName'];
676
        }
677
678 19
        if (isset($joinColumnElement['name'])) {
679 15
            $joinColumn['name'] = (string) $joinColumnElement['name'];
680
        }
681
682 19
        if (isset($joinColumnElement['fieldName'])) {
683
            $joinColumn['fieldName'] = (string) $joinColumnElement['fieldName'];
684
        }
685
686 19
        if (isset($joinColumnElement['unique'])) {
687 6
            $joinColumn['unique'] = (bool) $joinColumnElement['unique'];
688
        }
689
690 19
        if (isset($joinColumnElement['nullable'])) {
691 6
            $joinColumn['nullable'] = (bool) $joinColumnElement['nullable'];
692
        }
693
694 19
        if (isset($joinColumnElement['onDelete'])) {
695 6
            $joinColumn['onDelete'] = $joinColumnElement['onDelete'];
696
        }
697
698 19
        if (isset($joinColumnElement['columnDefinition'])) {
699 6
            $joinColumn['columnDefinition'] = $joinColumnElement['columnDefinition'];
700
        }
701
702 19
        return $joinColumn;
703
    }
704
705
    /**
706
     * Parses the given column as array.
707
     *
708
     * @param string $fieldName
709
     * @param array  $column
710
     *
711
     * @return  array
712
     */
713 41
    private function columnToArray($fieldName, $column)
714
    {
715
        $mapping = array(
716 41
            'fieldName' => $fieldName
717
        );
718
719 41
        if (isset($column['type'])) {
720 35
            $params = explode('(', $column['type']);
721
722 35
            $column['type']  = $params[0];
723 35
            $mapping['type'] = $column['type'];
724
725 35
            if (isset($params[1])) {
726 2
                $column['length'] = (integer) substr($params[1], 0, strlen($params[1]) - 1);
727
            }
728
        }
729
730 41
        if (isset($column['column'])) {
731 13
            $mapping['columnName'] = $column['column'];
732
        }
733
734 41
        if (isset($column['length'])) {
735 23
            $mapping['length'] = $column['length'];
736
        }
737
738 41
        if (isset($column['precision'])) {
739
            $mapping['precision'] = $column['precision'];
740
        }
741
742 41
        if (isset($column['scale'])) {
743
            $mapping['scale'] = $column['scale'];
744
        }
745
746 41
        if (isset($column['unique'])) {
747 15
            $mapping['unique'] = (bool) $column['unique'];
748
        }
749
750 41
        if (isset($column['options'])) {
751 6
            $mapping['options'] = $column['options'];
752
        }
753
754 41
        if (isset($column['nullable'])) {
755 12
            $mapping['nullable'] = $column['nullable'];
756
        }
757
758 41
        if (isset($column['version']) && $column['version']) {
759 4
            $mapping['version'] = $column['version'];
760
        }
761
762 41
        if (isset($column['columnDefinition'])) {
763 8
            $mapping['columnDefinition'] = $column['columnDefinition'];
764
        }
765
766 41
        return $mapping;
767
    }
768
769
    /**
770
     * Parse / Normalize the cache configuration
771
     *
772
     * @param array $cacheMapping
773
     *
774
     * @return array
775
     */
776 2
    private function cacheToArray($cacheMapping)
777
    {
778 2
        $region = isset($cacheMapping['region']) ? (string) $cacheMapping['region'] : null;
779 2
        $usage  = isset($cacheMapping['usage']) ? strtoupper($cacheMapping['usage']) : null;
780
781 2
        if ($usage && ! defined('Doctrine\ORM\Mapping\ClassMetadata::CACHE_USAGE_' . $usage)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $usage of type string|null 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...
782
            throw new \InvalidArgumentException(sprintf('Invalid cache usage "%s"', $usage));
783
        }
784
785 2
        if ($usage) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $usage of type string|null 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...
786 2
            $usage = constant('Doctrine\ORM\Mapping\ClassMetadata::CACHE_USAGE_' . $usage);
787
        }
788
789
        return array(
790 2
            'usage'  => $usage,
791 2
            'region' => $region,
792
        );
793
    }
794
795
    /**
796
     * {@inheritDoc}
797
     */
798 64
    protected function loadMappingFile($file)
799
    {
800 64
        return Yaml::parse(file_get_contents($file));
0 ignored issues
show
Bug Best Practice introduced by
The return type of return \Symfony\Componen...e_get_contents($file)); (array|string|stdClass) is incompatible with the return type declared by the abstract method Doctrine\Common\Persiste...Driver::loadMappingFile of type array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
801
    }
802
}
803