Failed Conditions
Pull Request — master (#6959)
by Matthew
12:20
created

completeFieldIdentifierGeneratorMapping()   C

Complexity

Conditions 14
Paths 21

Size

Total Lines 70
Code Lines 43

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 26
CRAP Score 24.84

Importance

Changes 0
Metric Value
cc 14
eloc 43
nc 21
nop 1
dl 0
loc 70
ccs 26
cts 42
cp 0.619
crap 24.84
rs 5.6188
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
declare(strict_types=1);
4
5
namespace Doctrine\ORM\Mapping;
6
7
use Doctrine\DBAL\Platforms;
8
use Doctrine\ORM\EntityManagerInterface;
9
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
10
use Doctrine\ORM\Event\OnClassMetadataNotFoundEventArgs;
11
use Doctrine\ORM\Events;
12
use Doctrine\ORM\ORMException;
13
use Doctrine\ORM\Sequencing;
14
use Doctrine\ORM\Sequencing\Planning\ColumnValueGeneratorExecutor;
15
use Doctrine\ORM\Sequencing\Planning\CompositeValueGenerationPlan;
16
use Doctrine\ORM\Sequencing\Planning\NoopValueGenerationPlan;
17
use Doctrine\ORM\Sequencing\Planning\SingleValueGenerationPlan;
18
use ReflectionException;
19
20
/**
21
 * The ClassMetadataFactory is used to create ClassMetadata objects that contain all the
22
 * metadata mapping information of a class which describes how a class should be mapped
23
 * to a relational database.
24
 */
25
class ClassMetadataFactory extends AbstractClassMetadataFactory
26
{
27
    /**
28
     * @var EntityManagerInterface|null
29
     */
30
    private $em;
31
32
    /**
33
     * @var \Doctrine\DBAL\Platforms\AbstractPlatform
34
     */
35
    private $targetPlatform;
36
37
    /**
38
     * @var Driver\MappingDriver
39
     */
40
    private $driver;
41
42
    /**
43
     * @var \Doctrine\Common\EventManager
44
     */
45
    private $evm;
46
47
    /**
48
     * {@inheritdoc}
49
     */
50 386
    protected function loadMetadata(string $name, ClassMetadataBuildingContext $metadataBuildingContext) : array
51
    {
52 386
        $loaded = parent::loadMetadata($name, $metadataBuildingContext);
53
54 359
        array_map([$this, 'resolveDiscriminatorValue'], $loaded);
55
56 359
        return $loaded;
57
    }
58
59 2275
    public function setEntityManager(EntityManagerInterface $em)
60
    {
61 2275
        $this->em = $em;
62 2275
    }
63
64
    /**
65
     * {@inheritdoc}
66
     *
67
     * @throws ORMException
68
     */
69 453
    protected function initialize() : void
70
    {
71 453
        $this->driver      = $this->em->getConfiguration()->getMetadataDriverImpl();
0 ignored issues
show
Bug introduced by
The method getConfiguration() does not exist on null. ( Ignorable by Annotation )

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

71
        $this->driver      = $this->em->/** @scrutinizer ignore-call */ getConfiguration()->getMetadataDriverImpl();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
72 453
        $this->evm         = $this->em->getEventManager();
73 453
        $this->initialized = true;
74 453
    }
75
76
    /**
77
     * {@inheritdoc}
78
     */
79 19
    protected function onNotFoundMetadata(
80
        string $className,
81
        ClassMetadataBuildingContext $metadataBuildingContext
82
    ) : ?ClassMetadata {
83 19
        if (! $this->evm->hasListeners(Events::onClassMetadataNotFound)) {
84 17
            return null;
85
        }
86
87 2
        $eventArgs = new OnClassMetadataNotFoundEventArgs($className, $metadataBuildingContext, $this->em);
0 ignored issues
show
Bug introduced by
It seems like $this->em can also be of type null; however, parameter $entityManager of Doctrine\ORM\Event\OnCla...ventArgs::__construct() does only seem to accept Doctrine\ORM\EntityManagerInterface, 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

87
        $eventArgs = new OnClassMetadataNotFoundEventArgs($className, $metadataBuildingContext, /** @scrutinizer ignore-type */ $this->em);
Loading history...
88
89 2
        $this->evm->dispatchEvent(Events::onClassMetadataNotFound, $eventArgs);
90
91 2
        return $eventArgs->getFoundMetadata();
92
    }
93
94
    /**
95
     * {@inheritdoc}
96
     *
97
     * @throws MappingException
98
     * @throws ORMException
99
     */
100 367
    protected function doLoadMetadata(
101
        string $className,
102
        ?ClassMetadata $parent,
103
        ClassMetadataBuildingContext $metadataBuildingContext
104
    ) : ClassMetadata {
105 367
        $classMetadata = new ClassMetadata($className, $metadataBuildingContext);
106
107 367
        if ($parent) {
108 100
            $classMetadata->setParent($parent);
109
110 100
            $this->addInheritedProperties($classMetadata, $parent);
111
112 99
            $classMetadata->setInheritanceType($parent->inheritanceType);
0 ignored issues
show
Bug introduced by
$parent->inheritanceType of type string is incompatible with the type integer expected by parameter $type of Doctrine\ORM\Mapping\Cla...a::setInheritanceType(). ( Ignorable by Annotation )

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

112
            $classMetadata->setInheritanceType(/** @scrutinizer ignore-type */ $parent->inheritanceType);
Loading history...
113 99
            $classMetadata->setIdentifier($parent->identifier);
114
115 99
            if ($parent->discriminatorColumn) {
116 72
                $classMetadata->setDiscriminatorColumn($parent->discriminatorColumn);
117 72
                $classMetadata->setDiscriminatorMap($parent->discriminatorMap);
118
            }
119
120 99
            $classMetadata->setLifecycleCallbacks($parent->lifecycleCallbacks);
121 99
            $classMetadata->setChangeTrackingPolicy($parent->changeTrackingPolicy);
122
123 99
            if ($parent->isMappedSuperclass) {
124 29
                $classMetadata->setCustomRepositoryClassName($parent->getCustomRepositoryClassName());
125
            }
126
        }
127
128
        // Invoke driver
129
        try {
130 367
            $this->driver->loadMetadataForClass($classMetadata->getClassName(), $classMetadata, $metadataBuildingContext);
131 2
        } catch (ReflectionException $e) {
132
            throw MappingException::reflectionFailure($classMetadata->getClassName(), $e);
133
        }
134
135 365
        $this->completeIdentifierGeneratorMappings($classMetadata);
136
137 365
        if ($parent) {
138 99
            $this->addInheritedNamedQueries($classMetadata, $parent);
139
140 99
            $parentCache = $parent->getCache();
141
            
142 99
            if ($parentCache) {
143 3
                $classMetadata->setCache(clone $parentCache);
144
            }
145
146 99
            if (! empty($parent->namedNativeQueries)) {
147 7
                $this->addInheritedNamedNativeQueries($classMetadata, $parent);
148
            }
149
150 99
            if (! empty($parent->sqlResultSetMappings)) {
151 7
                $this->addInheritedSqlResultSetMappings($classMetadata, $parent);
152
            }
153
154 99
            if (! empty($parent->entityListeners) && empty($classMetadata->entityListeners)) {
155 7
                $classMetadata->entityListeners = $parent->entityListeners;
156
            }
157
        }
158
159 365
        if (! $classMetadata->discriminatorMap && $classMetadata->inheritanceType !== InheritanceType::NONE && $classMetadata->isRootEntity()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $classMetadata->discriminatorMap of type string[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

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

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

Loading history...
160 1
            $this->addDefaultDiscriminatorMap($classMetadata);
161
        }
162
163 365
        $this->completeRuntimeMetadata($classMetadata, $parent);
164
165 365
        if ($this->evm->hasListeners(Events::loadClassMetadata)) {
166 6
            $eventArgs = new LoadClassMetadataEventArgs($classMetadata, $this->em);
0 ignored issues
show
Bug introduced by
It seems like $this->em can also be of type null; however, parameter $entityManager of Doctrine\ORM\Event\LoadC...ventArgs::__construct() does only seem to accept Doctrine\ORM\EntityManagerInterface, 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

166
            $eventArgs = new LoadClassMetadataEventArgs($classMetadata, /** @scrutinizer ignore-type */ $this->em);
Loading history...
167
168 6
            $this->evm->dispatchEvent(Events::loadClassMetadata, $eventArgs);
169
        }
170
171 364
        $this->buildValueGenerationPlan($classMetadata);
172 364
        $this->validateRuntimeMetadata($classMetadata, $parent);
173
174 361
        return $classMetadata;
175
    }
176
177 365
    protected function completeRuntimeMetadata(ClassMetadata $class, ?ClassMetadata $parent = null) : void
178
    {
179 365
        if (! $parent || ! $parent->isMappedSuperclass) {
180 365
            return;
181
        }
182
183 29
        if ($class->isMappedSuperclass) {
184 1
            return;
185
        }
186
187 29
        $tableName = $class->getTableName();
188
189
        // Resolve column table names
190 29
        foreach ($class->getDeclaredPropertiesIterator() as $property) {
191 29
            if ($property instanceof FieldMetadata) {
192 29
                $property->setTableName($property->getTableName() ?? $tableName);
193
194 29
                continue;
195
            }
196
197 12
            if (! ($property instanceof ToOneAssociationMetadata)) {
198 12
                continue;
199
            }
200
201
            // Resolve association join column table names
202 9
            foreach ($property->getJoinColumns() as $joinColumn) {
203
                /** @var JoinColumnMetadata $joinColumn */
204 9
                $joinColumn->setTableName($joinColumn->getTableName() ?? $tableName);
205
            }
206
        }
207 29
    }
208
209
    /**
210
     * Validate runtime metadata is correctly defined.
211
     *
212
     * @throws MappingException
213
     */
214 364
    protected function validateRuntimeMetadata(ClassMetadata $class, ?ClassMetadata $parent = null) : void
215
    {
216 364
        if (! $class->getReflectionClass()) {
217
            // only validate if there is a reflection class instance
218
            return;
219
        }
220
221 364
        $class->validateIdentifier();
222 361
        $class->validateAssociations();
223 361
        $class->validateLifecycleCallbacks($this->getReflectionService());
224
225
        // verify inheritance
226 361
        if (! $class->isMappedSuperclass && $class->inheritanceType !== InheritanceType::NONE) {
227 75
            if (! $parent) {
228 73
                if (! $class->discriminatorMap) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $class->discriminatorMap of type string[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

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

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

Loading history...
229
                    throw MappingException::missingDiscriminatorMap($class->getClassName());
230
                }
231
232 73
                if (! $class->discriminatorColumn) {
233 75
                    throw MappingException::missingDiscriminatorColumn($class->getClassName());
234
                }
235
            }
236 325
        } elseif (($class->discriminatorMap || $class->discriminatorColumn) && $class->isMappedSuperclass && $class->isRootEntity()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $class->discriminatorMap of type string[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

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

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

Loading history...
237
            // second condition is necessary for mapped superclasses in the middle of an inheritance hierarchy
238
            throw MappingException::noInheritanceOnMappedSuperClass($class->getClassName());
239
        }
240 361
    }
241
242
    /**
243
     * {@inheritdoc}
244
     */
245 1971
    protected function newClassMetadataBuildingContext() : ClassMetadataBuildingContext
246
    {
247 1971
        return new ClassMetadataBuildingContext(
248 1971
            $this,
249 1971
            $this->getReflectionService(),
250 1971
            $this->em->getConfiguration()->getNamingStrategy()
251
        );
252
    }
253
254
    /**
255
     * Populates the discriminator value of the given metadata (if not set) by iterating over discriminator
256
     * map classes and looking for a fitting one.
257
     *
258
     * @throws \InvalidArgumentException
259
     * @throws \ReflectionException
260
     * @throws MappingException
261
     */
262 359
    private function resolveDiscriminatorValue(ClassMetadata $metadata) : void
263
    {
264 359
        if ($metadata->discriminatorValue || ! $metadata->discriminatorMap || $metadata->isMappedSuperclass ||
0 ignored issues
show
Bug Best Practice introduced by
The expression $metadata->discriminatorMap of type string[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

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

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

Loading history...
265 359
            ! $metadata->getReflectionClass() || $metadata->getReflectionClass()->isAbstract()) {
266 359
            return;
267
        }
268
269
        // minor optimization: avoid loading related metadata when not needed
270 4
        foreach ($metadata->discriminatorMap as $discriminatorValue => $discriminatorClass) {
271 4
            if ($discriminatorClass === $metadata->getClassName()) {
272 3
                $metadata->discriminatorValue = $discriminatorValue;
273
274 4
                return;
275
            }
276
        }
277
278
        // iterate over discriminator mappings and resolve actual referenced classes according to existing metadata
279 1
        foreach ($metadata->discriminatorMap as $discriminatorValue => $discriminatorClass) {
280 1
            if ($metadata->getClassName() === $this->getMetadataFor($discriminatorClass)->getClassName()) {
281
                $metadata->discriminatorValue = $discriminatorValue;
282
283 1
                return;
284
            }
285
        }
286
287 1
        throw MappingException::mappedClassNotPartOfDiscriminatorMap($metadata->getClassName(), $metadata->getRootClassName());
288
    }
289
290
    /**
291
     * Adds a default discriminator map if no one is given
292
     *
293
     * If an entity is of any inheritance type and does not contain a
294
     * discriminator map, then the map is generated automatically. This process
295
     * is expensive computation wise.
296
     *
297
     * The automatically generated discriminator map contains the lowercase short name of
298
     * each class as key.
299
     *
300
     * @throws MappingException
301
     */
302 1
    private function addDefaultDiscriminatorMap(ClassMetadata $class) : void
303
    {
304 1
        $allClasses = $this->driver->getAllClassNames();
305 1
        $fqcn       = $class->getClassName();
306 1
        $map        = [$this->getShortName($fqcn) => $fqcn];
307 1
        $duplicates = [];
308
309 1
        foreach ($allClasses as $subClassCandidate) {
310 1
            if (is_subclass_of($subClassCandidate, $fqcn)) {
311 1
                $shortName = $this->getShortName($subClassCandidate);
312
313 1
                if (isset($map[$shortName])) {
314
                    $duplicates[] = $shortName;
315
                }
316
317 1
                $map[$shortName] = $subClassCandidate;
318
            }
319
        }
320
321 1
        if ($duplicates) {
322
            throw MappingException::duplicateDiscriminatorEntry($class->getClassName(), $duplicates, $map);
323
        }
324
325 1
        $class->setDiscriminatorMap($map);
326 1
    }
327
328
    /**
329
     * Gets the lower-case short name of a class.
330
     *
331
     * @param string $className
332
     */
333 1
    private function getShortName($className) : string
334
    {
335 1
        if (strpos($className, '\\') === false) {
336
            return strtolower($className);
337
        }
338
339 1
        $parts = explode('\\', $className);
340
341 1
        return strtolower(end($parts));
342
    }
343
344
    /**
345
     * Adds inherited fields to the subclass mapping.
346
     *
347
     * @throws MappingException
348
     */
349 100
    private function addInheritedProperties(ClassMetadata $subClass, ClassMetadata $parentClass) : void
350
    {
351 100
        $isAbstract = $parentClass->isMappedSuperclass;
352
353 100
        foreach ($parentClass->getDeclaredPropertiesIterator() as $fieldName => $property) {
354 99
            if ($isAbstract && $property instanceof ToManyAssociationMetadata && ! $property->isOwningSide()) {
355 1
                throw MappingException::illegalToManyAssociationOnMappedSuperclass($parentClass->getClassName(), $fieldName);
356
            }
357
358 98
            $subClass->addInheritedProperty($property);
359
        }
360 99
    }
361
362
    /**
363
     * Adds inherited named queries to the subclass mapping.
364
     *
365
     * @throws MappingException
366
     */
367 99
    private function addInheritedNamedQueries(ClassMetadata $subClass, ClassMetadata $parentClass) : void
368
    {
369 99
        foreach ($parentClass->getNamedQueries() as $name => $query) {
370 1
            if ($subClass->hasNamedQuery($name)) {
371 1
                continue;
372
            }
373
374 1
            $subClass->addNamedQuery($name, $query);
375
        }
376 99
    }
377
378
    /**
379
     * Adds inherited named native queries to the subclass mapping.
380
     *
381
     * @throws MappingException
382
     */
383 7
    private function addInheritedNamedNativeQueries(ClassMetadata $subClass, ClassMetadata $parentClass) : void
384
    {
385 7
        foreach ($parentClass->namedNativeQueries as $name => $query) {
386 7
            if (isset($subClass->namedNativeQueries[$name])) {
387 4
                continue;
388
            }
389
390 7
            $subClass->addNamedNativeQuery(
391 7
                $name,
392 7
                $query['query'],
393
                [
394 7
                    'resultSetMapping' => $query['resultSetMapping'],
395 7
                    'resultClass'      => $query['resultClass'],
396
                ]
397
            );
398
        }
399 7
    }
400
401
    /**
402
     * Adds inherited sql result set mappings to the subclass mapping.
403
     *
404
     * @throws MappingException
405
     */
406 7
    private function addInheritedSqlResultSetMappings(ClassMetadata $subClass, ClassMetadata $parentClass) : void
407
    {
408 7
        foreach ($parentClass->sqlResultSetMappings as $name => $mapping) {
409 7
            if (isset($subClass->sqlResultSetMappings[$name])) {
410 4
                continue;
411
            }
412
413 7
            $entities = [];
414
415 7
            foreach ($mapping['entities'] as $entity) {
416 7
                $entities[] = [
417 7
                    'fields'              => $entity['fields'],
418 7
                    'discriminatorColumn' => $entity['discriminatorColumn'],
419 7
                    'entityClass'         => $entity['entityClass'],
420
                ];
421
            }
422
423 7
            $subClass->addSqlResultSetMapping(
424
                [
425 7
                    'name'     => $mapping['name'],
426 7
                    'columns'  => $mapping['columns'],
427 7
                    'entities' => $entities,
428
                ]
429
            );
430
        }
431 7
    }
432
433
    /**
434
     * Completes the ID generator mapping. If "auto" is specified we choose the generator
435
     * most appropriate for the targeted database platform.
436
     *
437
     * @throws ORMException
438
     */
439 365
    private function completeIdentifierGeneratorMappings(ClassMetadata $class) : void
440
    {
441 365
        foreach ($class->getDeclaredPropertiesIterator() as $property) {
442 362
            if (! $property instanceof FieldMetadata /*&& ! $property instanceof AssocationMetadata*/) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
45% 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...
443 250
                continue;
444
            }
445
446 359
            $this->completeFieldIdentifierGeneratorMapping($property);
447
        }
448 365
    }
449
450 359
    private function completeFieldIdentifierGeneratorMapping(FieldMetadata $field)
451
    {
452 359
        if (! $field->hasValueGenerator()) {
453 279
            return;
454
        }
455
456 287
        $platform  = $this->getTargetPlatform();
457 287
        $class     = $field->getDeclaringClass();
0 ignored issues
show
Unused Code introduced by
The assignment to $class is dead and can be removed.
Loading history...
458 287
        $generator = $field->getValueGenerator();
459
460 287
        if ($generator->getType() === GeneratorType::AUTO) {
461 276
            $generator = new ValueGeneratorMetadata(
462 276
                $platform->prefersSequences()
463
                    ? GeneratorType::SEQUENCE
464 276
                    : ($platform->prefersIdentityColumns()
465 276
                        ? GeneratorType::IDENTITY
466 276
                        : GeneratorType::TABLE
467
                ),
468 276
                $field->getValueGenerator()->getDefinition()
469
            );
470 276
            $field->setValueGenerator($generator);
471
        }
472
473
        // Validate generator definition and set defaults where needed
474 287
        switch ($generator->getType()) {
475 287
            case GeneratorType::SEQUENCE:
476
                // If there is no sequence definition yet, create a default definition
477 6
                if ($generator->getDefinition()) {
478 6
                    break;
479
                }
480
481
                // @todo guilhermeblanco Move sequence generation to DBAL
482
                $sequencePrefix = $platform->getSequencePrefix($field->getTableName(), $field->getSchemaName());
0 ignored issues
show
Bug introduced by
The method getSchemaName() does not exist on Doctrine\ORM\Mapping\FieldMetadata. ( Ignorable by Annotation )

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

482
                $sequencePrefix = $platform->getSequencePrefix($field->getTableName(), $field->/** @scrutinizer ignore-call */ getSchemaName());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
483
                $idSequenceName = sprintf('%s_%s_seq', $sequencePrefix, $field->getColumnName());
484
                $sequenceName   = $platform->fixSchemaElementName($idSequenceName);
485
486
                $field->setValueGenerator(
487
                    new ValueGeneratorMetadata(
488
                        $generator->getType(),
489
                        [
490
                            'sequenceName'   => $sequenceName,
491
                            'allocationSize' => 1,
492
                        ]
493
                    )
494
                );
495
496
                break;
497
498 281
            case GeneratorType::TABLE:
499
                throw new ORMException('TableGenerator not yet implemented.');
500
                break;
501
502 281
            case GeneratorType::CUSTOM:
503 1
                $definition = $generator->getDefinition();
504 1
                if (! isset($definition['class'])) {
505
                    throw new ORMException(sprintf('Cannot instantiate custom generator, no class has been defined'));
506
                }
507 1
                if (! class_exists($definition['class'])) {
508
                    throw new ORMException(sprintf('Cannot instantiate custom generator : %s', var_export($definition, true))); //$definition['class']));
0 ignored issues
show
Unused Code Comprehensibility introduced by
100% 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...
509
                }
510
511 1
                break;
512
513 280
            case GeneratorType::IDENTITY:
514
            case GeneratorType::NONE:
515
            case GeneratorType::UUID:
516 280
                break;
517
518
            default:
519
                throw new ORMException('Unknown generator type: ' . $generator->getType());
520
        }
521 287
    }
522
523
    /**
524
     * {@inheritDoc}
525
     */
526 4
    protected function getFqcnFromAlias($namespaceAlias, $simpleClassName) : string
527
    {
528 4
        return $this->em->getConfiguration()->getEntityNamespace($namespaceAlias) . '\\' . $simpleClassName;
529
    }
530
531
    /**
532
     * {@inheritDoc}
533
     */
534 199
    protected function getDriver() : Driver\MappingDriver
535
    {
536 199
        return $this->driver;
537
    }
538
539
    /**
540
     * {@inheritDoc}
541
     */
542
    protected function isEntity(ClassMetadata $class) : bool
543
    {
544
        return isset($class->isMappedSuperclass) && $class->isMappedSuperclass === false;
545
    }
546
547 287
    private function getTargetPlatform() : Platforms\AbstractPlatform
548
    {
549 287
        if (! $this->targetPlatform) {
550 287
            $this->targetPlatform = $this->em->getConnection()->getDatabasePlatform();
551
        }
552
553 287
        return $this->targetPlatform;
554
    }
555
556 364
    private function buildValueGenerationPlan(ClassMetadata $class) : void
557
    {
558
        /** @var LocalColumnMetadata[] $generatedProperties */
559 364
        $generatedProperties = [];
560
561 364
        foreach ($class->getDeclaredPropertiesIterator() as $property) {
562 361
            if (! ($property instanceof LocalColumnMetadata && $property->hasValueGenerator())) {
563 331
                continue;
564
            }
565
566 286
            $generatedProperties[] = $property;
567
        }
568
569 364
        switch (count($generatedProperties)) {
570 364
            case 0:
571 117
                $class->setValueGenerationPlan(new NoopValueGenerationPlan());
572 117
                break;
573
574 286
            case 1:
575 286
                $property = reset($generatedProperties);
576 286
                $executor = new ColumnValueGeneratorExecutor($property, $this->createPropertyValueGenerator($class, $property));
577
578 286
                $class->setValueGenerationPlan(new SingleValueGenerationPlan($class, $executor));
579 286
                break;
580
581
            default:
582
                $executors = [];
583
584
                foreach ($generatedProperties as $property) {
585
                    $executors[] = new ColumnValueGeneratorExecutor($property, $this->createPropertyValueGenerator($class, $property));
586
                }
587
588
                $class->setValueGenerationPlan(new CompositeValueGenerationPlan($class, $executors));
589
                break;
590
        }
591 364
    }
592
593 286
    private function createPropertyValueGenerator(
594
        ClassMetadata $class,
595
        LocalColumnMetadata $property
596
    ) : Sequencing\Generator {
597 286
        $platform = $this->getTargetPlatform();
598
599 286
        switch ($property->getValueGenerator()->getType()) {
600 286
            case GeneratorType::IDENTITY:
601 279
                $sequenceName = null;
602
603
                // Platforms that do not have native IDENTITY support need a sequence to emulate this behaviour.
604 279
                if ($platform->usesSequenceEmulatedIdentityColumns()) {
605
                    $sequencePrefix = $platform->getSequencePrefix($class->getTableName(), $class->getSchemaName());
606
                    $idSequenceName = $platform->getIdentitySequenceName($sequencePrefix, $property->getColumnName());
607
                    $sequenceName   = $platform->quoteIdentifier($platform->fixSchemaElementName($idSequenceName));
608
                }
609
610 279
                return $property->getTypeName() === 'bigint'
611 1
                    ? new Sequencing\BigIntegerIdentityGenerator($sequenceName)
612 279
                    : new Sequencing\IdentityGenerator($sequenceName);
613
614 7
            case GeneratorType::SEQUENCE:
615 6
                $definition = $property->getValueGenerator()->getDefinition();
616 6
                return new Sequencing\SequenceGenerator(
617 6
                    $platform->quoteIdentifier($definition['sequenceName']),
618 6
                    $definition['allocationSize']
619
                );
620
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
621
622 1
            case GeneratorType::UUID:
623
                return new Sequencing\UuidGenerator();
624
                break;
625
626 1
            case GeneratorType::CUSTOM:
627 1
                $class = $property->getValueGenerator()->getDefinition()['class'];
628 1
                return new $class();
629
                break;
630
        }
631
    }
632
}
633