Completed
Pull Request — master (#5800)
by Herberto
10:37
created

YamlDriver::columnToArray()   F

Complexity

Conditions 13
Paths 1536

Size

Total Lines 55
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 25
CRAP Score 13.0687

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 55
ccs 25
cts 27
cp 0.9259
rs 3.4502
cc 13
eloc 28
nc 1536
nop 2
crap 13.0687

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 67
    public function __construct($locator, $fileExtension = self::DEFAULT_FILE_EXTENSION)
45
    {
46 67
        parent::__construct($locator, $fileExtension);
47 67
    }
48
49
    /**
50
     * {@inheritDoc}
51
     */
52 62
    public function loadMetadataForClass($className, ClassMetadata $metadata)
53
    {
54
        /* @var $metadata \Doctrine\ORM\Mapping\ClassMetadataInfo */
55 62
        $element = $this->getElement($className);
56
57 60
        if ($element['type'] == 'entity') {
58 58
            if (isset($element['repositoryClass'])) {
59
                $metadata->setCustomRepositoryClass($element['repositoryClass']);
60
            }
61 58
            if (isset($element['collectionClass'])) {
62
                $metadata->setCustomCollectionClass($element['collectionClass']);
63
            }
64 58
            if (isset($element['readOnly']) && $element['readOnly'] == true) {
65 58
                $metadata->markReadOnly();
66
            }
67 14
        } else if ($element['type'] == 'mappedSuperclass') {
68 12
            $metadata->setCustomRepositoryClass(
69 12
                isset($element['repositoryClass']) ? $element['repositoryClass'] : null
70
            );
71 12
            $metadata->isMappedSuperclass = true;
72 2
        } else if ($element['type'] == 'embeddable') {
73
            $metadata->isEmbeddedClass = true;
74
        } else {
75 2
            throw MappingException::classIsNotAValidEntityOrMappedSuperClass($className);
76
        }
77
78
        // Evaluate root level properties
79 58
        $primaryTable = array();
80
81 58
        if (isset($element['table'])) {
82 24
            $primaryTable['name'] = $element['table'];
83
        }
84
85 58
        if (isset($element['schema'])) {
86 2
            $primaryTable['schema'] = $element['schema'];
87
        }
88
89
        // Evaluate second level cache
90 58
        if (isset($element['cache'])) {
91 2
            $metadata->enableCache($this->cacheToArray($element['cache']));
92
        }
93
94 58
        $metadata->setPrimaryTable($primaryTable);
95
96
        // Evaluate named queries
97 58
        if (isset($element['namedQueries'])) {
98 6
            foreach ($element['namedQueries'] as $name => $queryMapping) {
99 6
                if (is_string($queryMapping)) {
100 6
                    $queryMapping = array('query' => $queryMapping);
101
                }
102
103 6
                if ( ! isset($queryMapping['name'])) {
104 6
                    $queryMapping['name'] = $name;
105
                }
106
107 6
                $metadata->addNamedQuery($queryMapping);
108
            }
109
        }
110
111
        // Evaluate named native queries
112 58
        if (isset($element['namedNativeQueries'])) {
113 6
            foreach ($element['namedNativeQueries'] as $name => $mappingElement) {
114 6
                if (!isset($mappingElement['name'])) {
115 6
                    $mappingElement['name'] = $name;
116
                }
117 6
                $metadata->addNamedNativeQuery(array(
118 6
                    'name'              => $mappingElement['name'],
119 6
                    'query'             => isset($mappingElement['query']) ? $mappingElement['query'] : null,
120 6
                    'resultClass'       => isset($mappingElement['resultClass']) ? $mappingElement['resultClass'] : null,
121 6
                    'resultSetMapping'  => isset($mappingElement['resultSetMapping']) ? $mappingElement['resultSetMapping'] : null,
122
                ));
123
            }
124
        }
125
126
        // Evaluate sql result set mappings
127 58
        if (isset($element['sqlResultSetMappings'])) {
128 6
            foreach ($element['sqlResultSetMappings'] as $name => $resultSetMapping) {
129 6
                if (!isset($resultSetMapping['name'])) {
130 6
                    $resultSetMapping['name'] = $name;
131
                }
132
133 6
                $entities = array();
134 6
                $columns  = array();
135 6
                if (isset($resultSetMapping['entityResult'])) {
136 6
                    foreach ($resultSetMapping['entityResult'] as $entityResultElement) {
137
                        $entityResult = array(
138 6
                            'fields'                => array(),
139 6
                            'entityClass'           => isset($entityResultElement['entityClass']) ? $entityResultElement['entityClass'] : null,
140 6
                            'discriminatorColumn'   => isset($entityResultElement['discriminatorColumn']) ? $entityResultElement['discriminatorColumn'] : null,
141
                        );
142
143 6
                        if (isset($entityResultElement['fieldResult'])) {
144 6
                            foreach ($entityResultElement['fieldResult'] as $fieldResultElement) {
145 6
                                $entityResult['fields'][] = array(
146 6
                                    'name'      => isset($fieldResultElement['name']) ? $fieldResultElement['name'] : null,
147 6
                                    'column'    => isset($fieldResultElement['column']) ? $fieldResultElement['column'] : null,
148
                                );
149
                            }
150
                        }
151
152 6
                        $entities[] = $entityResult;
153
                    }
154
                }
155
156
157 6
                if (isset($resultSetMapping['columnResult'])) {
158 6
                    foreach ($resultSetMapping['columnResult'] as $columnResultAnnot) {
159 6
                        $columns[] = array(
160 6
                            'name' => isset($columnResultAnnot['name']) ? $columnResultAnnot['name'] : null,
161
                        );
162
                    }
163
                }
164
165 6
                $metadata->addSqlResultSetMapping(array(
166 6
                    'name'          => $resultSetMapping['name'],
167 6
                    'entities'      => $entities,
168 6
                    'columns'       => $columns
169
                ));
170
            }
171
        }
172
173 58
        if (isset($element['inheritanceType'])) {
174 18
            $metadata->setInheritanceType(constant('Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_' . strtoupper($element['inheritanceType'])));
175
176 18
            if ($metadata->inheritanceType != \Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_NONE) {
177
                // Evaluate discriminatorColumn
178 18
                if (isset($element['discriminatorColumn'])) {
179 12
                    $discrColumn = $element['discriminatorColumn'];
180 12
                    $metadata->setDiscriminatorColumn(array(
181 12
                        'name' => isset($discrColumn['name']) ? (string) $discrColumn['name'] : null,
182 12
                        'type' => isset($discrColumn['type']) ? (string) $discrColumn['type'] : 'string',
183 12
                        'length' => isset($discrColumn['length']) ? (string) $discrColumn['length'] : 255,
184 12
                        'columnDefinition' => isset($discrColumn['columnDefinition']) ? (string) $discrColumn['columnDefinition'] : null
185
                    ));
186
                } else {
187 12
                    $metadata->setDiscriminatorColumn(array('name' => 'dtype', 'type' => 'string', 'length' => 255));
188
                }
189
190
                // Evaluate discriminatorMap
191 18
                if (isset($element['discriminatorMap'])) {
192 18
                    $metadata->setDiscriminatorMap($element['discriminatorMap']);
193
                }
194
            }
195
        }
196
197
198
        // Evaluate changeTrackingPolicy
199 58
        if (isset($element['changeTrackingPolicy'])) {
200
            $metadata->setChangeTrackingPolicy(constant('Doctrine\ORM\Mapping\ClassMetadata::CHANGETRACKING_'
201
                . strtoupper($element['changeTrackingPolicy'])));
202
        }
203
204
        // Evaluate indexes
205 58
        if (isset($element['indexes'])) {
206 8
            foreach ($element['indexes'] as $name => $indexYml) {
207 8
                if ( ! isset($indexYml['name'])) {
208 8
                    $indexYml['name'] = $name;
209
                }
210
211 8
                if (is_string($indexYml['columns'])) {
212 8
                    $index = array('columns' => array_map('trim', explode(',', $indexYml['columns'])));
213
                } else {
214
                    $index = array('columns' => $indexYml['columns']);
215
                }
216
217 8
                if (isset($indexYml['flags'])) {
218 2
                    if (is_string($indexYml['flags'])) {
219 2
                        $index['flags'] = array_map('trim', explode(',', $indexYml['flags']));
220
                    } else {
221
                        $index['flags'] = $indexYml['flags'];
222
                    }
223
                }
224
225 8
                if (isset($indexYml['options'])) {
226 2
                    $index['options'] = $indexYml['options'];
227
                }
228
229 8
                $metadata->table['indexes'][$indexYml['name']] = $index;
230
            }
231
        }
232
233
        // Evaluate uniqueConstraints
234 58
        if (isset($element['uniqueConstraints'])) {
235 7
            foreach ($element['uniqueConstraints'] as $name => $uniqueYml) {
236 7
                if ( ! isset($uniqueYml['name'])) {
237 7
                    $uniqueYml['name'] = $name;
238
                }
239
240 7
                if (is_string($uniqueYml['columns'])) {
241 6
                    $unique = array('columns' => array_map('trim', explode(',', $uniqueYml['columns'])));
242
                } else {
243 1
                    $unique = array('columns' => $uniqueYml['columns']);
244
                }
245
246 7
                if (isset($uniqueYml['options'])) {
247 4
                    $unique['options'] = $uniqueYml['options'];
248
                }
249
250 7
                $metadata->table['uniqueConstraints'][$uniqueYml['name']] = $unique;
251
            }
252
        }
253
254 58
        if (isset($element['options'])) {
255 6
            $metadata->table['options'] = $element['options'];
256
        }
257
258 58
        $associationIds = array();
259 58
        if (isset($element['id'])) {
260
            // Evaluate identifier settings
261 54
            foreach ($element['id'] as $name => $idElement) {
262 54
                if (isset($idElement['associationKey']) && $idElement['associationKey'] == true) {
263
                    $associationIds[$name] = true;
264
                    continue;
265
                }
266
267
                $mapping = array(
268 54
                    'id' => true,
269 54
                    'fieldName' => $name
270
                );
271
272 54
                if (isset($idElement['type'])) {
273 34
                    $mapping['type'] = $idElement['type'];
274
                }
275
276 54
                if (isset($idElement['column'])) {
277 6
                    $mapping['columnName'] = $idElement['column'];
278
                }
279
280 54
                if (isset($idElement['length'])) {
281 6
                    $mapping['length'] = $idElement['length'];
282
                }
283
284 54
                if (isset($idElement['columnDefinition'])) {
285 2
                    $mapping['columnDefinition'] = $idElement['columnDefinition'];
286
                }
287
288 54
                if (isset($idElement['options'])) {
289 4
                    $mapping['options'] = $idElement['options'];
290
                }
291
292 54
                $metadata->mapField($mapping);
293
294 54
                if (isset($idElement['generator'])) {
295 51
                    $metadata->setIdGeneratorType(constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_'
296 51
                        . strtoupper($idElement['generator']['strategy'])));
297
                }
298
                // Check for SequenceGenerator/TableGenerator definition
299 54
                if (isset($idElement['sequenceGenerator'])) {
300 4
                    $metadata->setSequenceGeneratorDefinition($idElement['sequenceGenerator']);
301 50
                } else if (isset($idElement['customIdGenerator'])) {
302 4
                    $customGenerator = $idElement['customIdGenerator'];
303 4
                    $metadata->setCustomGeneratorDefinition(array(
304 4
                        'class' => (string) $customGenerator['class']
305
                    ));
306 46
                } else if (isset($idElement['tableGenerator'])) {
307 54
                    throw MappingException::tableIdGeneratorNotImplemented($className);
308
                }
309
            }
310
        }
311
312
        // Evaluate fields
313 58
        if (isset($element['fields'])) {
314 41
            foreach ($element['fields'] as $name => $fieldMapping) {
315
316 41
                $mapping = $this->columnToArray($name, $fieldMapping);
317
318 41
                if (isset($fieldMapping['id'])) {
319
                    $mapping['id'] = true;
320
                    if (isset($fieldMapping['generator']['strategy'])) {
321
                        $metadata->setIdGeneratorType(constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_'
322
                            . strtoupper($fieldMapping['generator']['strategy'])));
323
                    }
324
                }
325
326 41
                if (isset($mapping['version'])) {
327 4
                    $metadata->setVersionMapping($mapping);
328 4
                    unset($mapping['version']);
329
                }
330
331 41
                $metadata->mapField($mapping);
332
            }
333
        }
334
335 58
        if (isset($element['embedded'])) {
336
            foreach ($element['embedded'] as $name => $embeddedMapping) {
337
                $mapping = array(
338
                    'fieldName' => $name,
339
                    'class' => $embeddedMapping['class'],
340
                    'columnPrefix' => isset($embeddedMapping['columnPrefix']) ? $embeddedMapping['columnPrefix'] : null,
341
                );
342
                $metadata->mapEmbedded($mapping);
343
            }
344
        }
345
346
        // Evaluate oneToOne relationships
347 58
        if (isset($element['oneToOne'])) {
348 13
            foreach ($element['oneToOne'] as $name => $oneToOneElement) {
349
                $mapping = array(
350 13
                    'fieldName' => $name,
351 13
                    'targetEntity' => $oneToOneElement['targetEntity']
352
                );
353
354 13
                if (isset($associationIds[$mapping['fieldName']])) {
355
                    $mapping['id'] = true;
356
                }
357
358 13
                if (isset($oneToOneElement['fetch'])) {
359 3
                    $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $oneToOneElement['fetch']);
360
                }
361
362 13
                if (isset($oneToOneElement['mappedBy'])) {
363 1
                    $mapping['mappedBy'] = $oneToOneElement['mappedBy'];
364
                } else {
365 12
                    if (isset($oneToOneElement['inversedBy'])) {
366 12
                        $mapping['inversedBy'] = $oneToOneElement['inversedBy'];
367
                    }
368
369 12
                    $joinColumns = array();
370
371 12
                    if (isset($oneToOneElement['joinColumn'])) {
372 11
                        $joinColumns[] = $this->joinColumnToArray($oneToOneElement['joinColumn']);
373 1
                    } else if (isset($oneToOneElement['joinColumns'])) {
374 1
                        foreach ($oneToOneElement['joinColumns'] as $joinColumnName => $joinColumnElement) {
375 1
                            if ( ! isset($joinColumnElement['name'])) {
376 1
                                $joinColumnElement['name'] = $joinColumnName;
377
                            }
378
379 1
                            $joinColumns[] = $this->joinColumnToArray($joinColumnElement);
380
                        }
381
                    }
382
383 12
                    $mapping['joinColumns'] = $joinColumns;
384
                }
385
386 13
                if (isset($oneToOneElement['cascade'])) {
387 9
                    $mapping['cascade'] = $oneToOneElement['cascade'];
388
                }
389
390 13
                if (isset($oneToOneElement['orphanRemoval'])) {
391 5
                    $mapping['orphanRemoval'] = (bool) $oneToOneElement['orphanRemoval'];
392
                }
393
394
                // Evaluate second level cache
395 13
                if (isset($oneToOneElement['cache'])) {
396
                    $mapping['cache'] = $metadata->getAssociationCacheDefaults($mapping['fieldName'], $this->cacheToArray($oneToOneElement['cache']));
397
                }
398
399 13
                $metadata->mapOneToOne($mapping);
400
            }
401
        }
402
403
        // Evaluate oneToMany relationships
404 58
        if (isset($element['oneToMany'])) {
405 8
            foreach ($element['oneToMany'] as $name => $oneToManyElement) {
406
                $mapping = array(
407 8
                    'fieldName' => $name,
408 8
                    'targetEntity' => $oneToManyElement['targetEntity'],
409 8
                    'mappedBy' => $oneToManyElement['mappedBy']
410
                );
411
412 8
                if (isset($oneToManyElement['fetch'])) {
413 2
                    $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $oneToManyElement['fetch']);
414
                }
415
416 8
                if (isset($oneToManyElement['cascade'])) {
417 6
                    $mapping['cascade'] = $oneToManyElement['cascade'];
418
                }
419
420 8
                if (isset($oneToManyElement['orphanRemoval'])) {
421 6
                    $mapping['orphanRemoval'] = (bool) $oneToManyElement['orphanRemoval'];
422
                }
423
424 8
                if (isset($oneToManyElement['orderBy'])) {
425 8
                    $mapping['orderBy'] = $oneToManyElement['orderBy'];
426
                }
427
428 8
                if (isset($oneToManyElement['indexBy'])) {
429
                    $mapping['indexBy'] = $oneToManyElement['indexBy'];
430
                }
431
432
433
                // Evaluate second level cache
434 8
                if (isset($oneToManyElement['cache'])) {
435 2
                    $mapping['cache'] = $metadata->getAssociationCacheDefaults($mapping['fieldName'], $this->cacheToArray($oneToManyElement['cache']));
436
                }
437
438 8
                $metadata->mapOneToMany($mapping);
439
            }
440
        }
441
442
        // Evaluate manyToOne relationships
443 58
        if (isset($element['manyToOne'])) {
444 10
            foreach ($element['manyToOne'] as $name => $manyToOneElement) {
445
                $mapping = array(
446 10
                    'fieldName' => $name,
447 10
                    'targetEntity' => $manyToOneElement['targetEntity']
448
                );
449
450 10
                if (isset($associationIds[$mapping['fieldName']])) {
451
                    $mapping['id'] = true;
452
                }
453
454 10
                if (isset($manyToOneElement['fetch'])) {
455 1
                    $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $manyToOneElement['fetch']);
456
                }
457
458 10
                if (isset($manyToOneElement['inversedBy'])) {
459 2
                    $mapping['inversedBy'] = $manyToOneElement['inversedBy'];
460
                }
461
462 10
                $joinColumns = array();
463
464 10
                if (isset($manyToOneElement['joinColumn'])) {
465 4
                    $joinColumns[] = $this->joinColumnToArray($manyToOneElement['joinColumn']);
466 6
                } else if (isset($manyToOneElement['joinColumns'])) {
467 3
                    foreach ($manyToOneElement['joinColumns'] as $joinColumnName => $joinColumnElement) {
468 3
                        if ( ! isset($joinColumnElement['name'])) {
469 3
                            $joinColumnElement['name'] = $joinColumnName;
470
                        }
471
472 3
                        $joinColumns[] = $this->joinColumnToArray($joinColumnElement);
473
                    }
474
                }
475
476 10
                $mapping['joinColumns'] = $joinColumns;
477
478 10
                if (isset($manyToOneElement['cascade'])) {
479 5
                    $mapping['cascade'] = $manyToOneElement['cascade'];
480
                }
481
482
                // Evaluate second level cache
483 10
                if (isset($manyToOneElement['cache'])) {
484 2
                    $mapping['cache'] = $metadata->getAssociationCacheDefaults($mapping['fieldName'], $this->cacheToArray($manyToOneElement['cache']));
485
                }
486
487 10
                $metadata->mapManyToOne($mapping);
488
            }
489
        }
490
491
        // Evaluate manyToMany relationships
492 58
        if (isset($element['manyToMany'])) {
493 17
            foreach ($element['manyToMany'] as $name => $manyToManyElement) {
494
                $mapping = array(
495 17
                    'fieldName' => $name,
496 17
                    'targetEntity' => $manyToManyElement['targetEntity']
497
                );
498
499 17
                if (isset($manyToManyElement['fetch'])) {
500 2
                    $mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $manyToManyElement['fetch']);
501
                }
502
503 17
                if (isset($manyToManyElement['mappedBy'])) {
504 2
                    $mapping['mappedBy'] = $manyToManyElement['mappedBy'];
505 15
                } else if (isset($manyToManyElement['joinTable'])) {
506
507 13
                    $joinTableElement = $manyToManyElement['joinTable'];
508
                    $joinTable = array(
509 13
                        'name' => $joinTableElement['name']
510
                    );
511
512 13
                    if (isset($joinTableElement['schema'])) {
513
                        $joinTable['schema'] = $joinTableElement['schema'];
514
                    }
515
516 13
                    if (isset($joinTableElement['joinColumns'])) {
517 13
                        foreach ($joinTableElement['joinColumns'] as $joinColumnName => $joinColumnElement) {
518 13
                            if ( ! isset($joinColumnElement['name'])) {
519 12
                                $joinColumnElement['name'] = $joinColumnName;
520
                            }
521 13
                            $joinTable['joinColumns'][] = $this->joinColumnToArray($joinColumnElement);
522
                        }
523
                    }
524
525 13
                    if (isset($joinTableElement['inverseJoinColumns'])) {
526 13
                        foreach ($joinTableElement['inverseJoinColumns'] as $joinColumnName => $joinColumnElement) {
527 13
                            if ( ! isset($joinColumnElement['name'])) {
528 12
                                $joinColumnElement['name'] = $joinColumnName;
529
                            }
530 13
                            $joinTable['inverseJoinColumns'][] = $this->joinColumnToArray($joinColumnElement);
531
                        }
532
                    }
533
534 13
                    $mapping['joinTable'] = $joinTable;
535
                }
536
537 17
                if (isset($manyToManyElement['inversedBy'])) {
538
                    $mapping['inversedBy'] = $manyToManyElement['inversedBy'];
539
                }
540
541 17
                if (isset($manyToManyElement['cascade'])) {
542 12
                    $mapping['cascade'] = $manyToManyElement['cascade'];
543
                }
544
545 17
                if (isset($manyToManyElement['orderBy'])) {
546
                    $mapping['orderBy'] = $manyToManyElement['orderBy'];
547
                }
548
549 17
                if (isset($manyToManyElement['indexBy'])) {
550
                    $mapping['indexBy'] = $manyToManyElement['indexBy'];
551
                }
552
553 17
                if (isset($manyToManyElement['orphanRemoval'])) {
554
                    $mapping['orphanRemoval'] = (bool) $manyToManyElement['orphanRemoval'];
555
                }
556
557
                // Evaluate second level cache
558 17
                if (isset($manyToManyElement['cache'])) {
559
                    $mapping['cache'] = $metadata->getAssociationCacheDefaults($mapping['fieldName'], $this->cacheToArray($manyToManyElement['cache']));
560
                }
561
562 17
                $metadata->mapManyToMany($mapping);
563
            }
564
        }
565
566
        // Evaluate associationOverride
567 58
        if (isset($element['associationOverride']) && is_array($element['associationOverride'])) {
568
569 6
            foreach ($element['associationOverride'] as $fieldName => $associationOverrideElement) {
570 6
                $override   = array();
571
572
                // Check for joinColumn
573 6
                if (isset($associationOverrideElement['joinColumn'])) {
574 4
                    $joinColumns = array();
575 4
                    foreach ($associationOverrideElement['joinColumn'] as $name => $joinColumnElement) {
576 4
                        if ( ! isset($joinColumnElement['name'])) {
577
                            $joinColumnElement['name'] = $name;
578
                        }
579 4
                        $joinColumns[] = $this->joinColumnToArray($joinColumnElement);
580
                    }
581 4
                    $override['joinColumns'] = $joinColumns;
582
                }
583
584
                // Check for joinTable
585 6
                if (isset($associationOverrideElement['joinTable'])) {
586
587 4
                    $joinTableElement   = $associationOverrideElement['joinTable'];
588
                    $joinTable          =  array(
589 4
                        'name' => $joinTableElement['name']
590
                    );
591
592 4
                    if (isset($joinTableElement['schema'])) {
593
                        $joinTable['schema'] = $joinTableElement['schema'];
594
                    }
595
596 4
                    foreach ($joinTableElement['joinColumns'] as $name => $joinColumnElement) {
597 4
                        if ( ! isset($joinColumnElement['name'])) {
598 4
                            $joinColumnElement['name'] = $name;
599
                        }
600
601 4
                        $joinTable['joinColumns'][] = $this->joinColumnToArray($joinColumnElement);
602
                    }
603
604 4
                    foreach ($joinTableElement['inverseJoinColumns'] as $name => $joinColumnElement) {
605 4
                        if ( ! isset($joinColumnElement['name'])) {
606 4
                            $joinColumnElement['name'] = $name;
607
                        }
608
609 4
                        $joinTable['inverseJoinColumns'][] = $this->joinColumnToArray($joinColumnElement);
610
                    }
611
612 4
                    $override['joinTable'] = $joinTable;
613
                }
614
615
                // Check for inversedBy
616 6
                if (isset($associationOverrideElement['inversedBy'])) {
617 2
                    $override['inversedBy'] = (string) $associationOverrideElement['inversedBy'];
618
                }
619
620 6
                $metadata->setAssociationOverride($fieldName, $override);
621
            }
622
        }
623
624
        // Evaluate associationOverride
625 58
        if (isset($element['attributeOverride']) && is_array($element['attributeOverride'])) {
626
627 4
            foreach ($element['attributeOverride'] as $fieldName => $attributeOverrideElement) {
628 4
                $mapping = $this->columnToArray($fieldName, $attributeOverrideElement);
629 4
                $metadata->setAttributeOverride($fieldName, $mapping);
630
            }
631
        }
632
633
        // Evaluate lifeCycleCallbacks
634 58
        if (isset($element['lifecycleCallbacks'])) {
635 7
            foreach ($element['lifecycleCallbacks'] as $type => $methods) {
636 6
                foreach ($methods as $method) {
637 6
                    $metadata->addLifecycleCallback($method, constant('Doctrine\ORM\Events::' . $type));
638
                }
639
            }
640
        }
641
642
        // Evaluate entityListeners
643 58
        if (isset($element['entityListeners'])) {
644 8
            foreach ($element['entityListeners'] as $className => $entityListener) {
645
                // Evaluate the listener using naming convention.
646 8
                if (empty($entityListener)) {
647 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...
648
649 4
                    continue;
650
                }
651
652 4
                foreach ($entityListener as $eventName => $callbackElement) {
653 4
                    foreach ($callbackElement as $methodName) {
654 4
                        $metadata->addEntityListener($eventName, $className, $methodName);
655
                    }
656
                }
657
            }
658
        }
659 58
    }
660
661
    /**
662
     * Constructs a joinColumn mapping array based on the information
663
     * found in the given join column element.
664
     *
665
     * @param array $joinColumnElement The array join column element.
666
     *
667
     * @return array The mapping array.
668
     */
669 19
    private function joinColumnToArray($joinColumnElement)
670
    {
671 19
        $joinColumn = array();
672 19
        if (isset($joinColumnElement['referencedColumnName'])) {
673 19
            $joinColumn['referencedColumnName'] = (string) $joinColumnElement['referencedColumnName'];
674
        }
675
676 19
        if (isset($joinColumnElement['name'])) {
677 15
            $joinColumn['name'] = (string) $joinColumnElement['name'];
678
        }
679
680 19
        if (isset($joinColumnElement['fieldName'])) {
681
            $joinColumn['fieldName'] = (string) $joinColumnElement['fieldName'];
682
        }
683
684 19
        if (isset($joinColumnElement['unique'])) {
685 6
            $joinColumn['unique'] = (bool) $joinColumnElement['unique'];
686
        }
687
688 19
        if (isset($joinColumnElement['nullable'])) {
689 6
            $joinColumn['nullable'] = (bool) $joinColumnElement['nullable'];
690
        }
691
692 19
        if (isset($joinColumnElement['onDelete'])) {
693 6
            $joinColumn['onDelete'] = $joinColumnElement['onDelete'];
694
        }
695
696 19
        if (isset($joinColumnElement['columnDefinition'])) {
697 6
            $joinColumn['columnDefinition'] = $joinColumnElement['columnDefinition'];
698
        }
699
700 19
        return $joinColumn;
701
    }
702
703
    /**
704
     * Parses the given column as array.
705
     *
706
     * @param string $fieldName
707
     * @param array  $column
708
     *
709
     * @return  array
710
     */
711 41
    private function columnToArray($fieldName, $column)
712
    {
713
        $mapping = array(
714 41
            'fieldName' => $fieldName
715
        );
716
717 41
        if (isset($column['type'])) {
718 35
            $params = explode('(', $column['type']);
719
720 35
            $column['type']  = $params[0];
721 35
            $mapping['type'] = $column['type'];
722
723 35
            if (isset($params[1])) {
724 2
                $column['length'] = (integer) substr($params[1], 0, strlen($params[1]) - 1);
725
            }
726
        }
727
728 41
        if (isset($column['column'])) {
729 13
            $mapping['columnName'] = $column['column'];
730
        }
731
732 41
        if (isset($column['length'])) {
733 23
            $mapping['length'] = $column['length'];
734
        }
735
736 41
        if (isset($column['precision'])) {
737
            $mapping['precision'] = $column['precision'];
738
        }
739
740 41
        if (isset($column['scale'])) {
741
            $mapping['scale'] = $column['scale'];
742
        }
743
744 41
        if (isset($column['unique'])) {
745 15
            $mapping['unique'] = (bool) $column['unique'];
746
        }
747
748 41
        if (isset($column['options'])) {
749 6
            $mapping['options'] = $column['options'];
750
        }
751
752 41
        if (isset($column['nullable'])) {
753 12
            $mapping['nullable'] = $column['nullable'];
754
        }
755
756 41
        if (isset($column['version']) && $column['version']) {
757 4
            $mapping['version'] = $column['version'];
758
        }
759
760 41
        if (isset($column['columnDefinition'])) {
761 8
            $mapping['columnDefinition'] = $column['columnDefinition'];
762
        }
763
764 41
        return $mapping;
765
    }
766
767
    /**
768
     * Parse / Normalize the cache configuration
769
     *
770
     * @param array $cacheMapping
771
     *
772
     * @return array
773
     */
774 2
    private function cacheToArray($cacheMapping)
775
    {
776 2
        $region = isset($cacheMapping['region']) ? (string) $cacheMapping['region'] : null;
777 2
        $usage  = isset($cacheMapping['usage']) ? strtoupper($cacheMapping['usage']) : null;
778
779 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...
780
            throw new \InvalidArgumentException(sprintf('Invalid cache usage "%s"', $usage));
781
        }
782
783 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...
784 2
            $usage = constant('Doctrine\ORM\Mapping\ClassMetadata::CACHE_USAGE_' . $usage);
785
        }
786
787
        return array(
788 2
            'usage'  => $usage,
789 2
            'region' => $region,
790
        );
791
    }
792
793
    /**
794
     * {@inheritDoc}
795
     */
796 62
    protected function loadMappingFile($file)
797
    {
798 62
        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...
799
    }
800
}
801