Failed Conditions
Push — master ( fa7802...d60694 )
by Guilherme
09:27
created

ValueGeneratorMetadataBuilder::build()   D

Complexity

Conditions 17
Paths 136

Size

Total Lines 93
Code Lines 58

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 44
CRAP Score 18.4148

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 17
eloc 58
c 1
b 0
f 0
nc 136
nop 0
dl 0
loc 93
ccs 44
cts 53
cp 0.8302
crap 18.4148
rs 4.9166

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\Builder;
6
7
use Doctrine\DBAL\Types\Type;
8
use Doctrine\ORM\Annotation;
9
use Doctrine\ORM\Mapping;
10
use Doctrine\ORM\Mapping\Exception\TableGeneratorNotImplementedYet;
11
use Doctrine\ORM\Mapping\Exception\UnknownGeneratorType;
12
use Doctrine\ORM\Mapping\GeneratorType;
13
use Doctrine\ORM\Sequencing\Generator;
14
use ReflectionClass;
15
use ReflectionException;
16
use function assert;
17
use function constant;
18
use function in_array;
19
use function sprintf;
20
use function strtoupper;
21
22
class ValueGeneratorMetadataBuilder
23
{
24
    /** @var Mapping\ClassMetadataBuildingContext */
25
    private $metadataBuildingContext;
26
27
    /** @var Mapping\ClassMetadata */
28
    private $componentMetadata;
29
30
    /** @var string */
31
    private $fieldName;
32
33
    /** @var Type */
34
    private $fieldType;
35
36
    /** @var Annotation\GeneratedValue|null */
37
    private $generatedValueAnnotation;
38
39
    /** @var Annotation\SequenceGenerator|null */
40
    private $sequenceGeneratorAnnotation;
41
42
    /** @var Annotation\CustomIdGenerator|null */
43
    private $customIdGeneratorAnnotation;
44
45 401
    public function __construct(Mapping\ClassMetadataBuildingContext $metadataBuildingContext)
46
    {
47 401
        $this->metadataBuildingContext = $metadataBuildingContext;
48 401
    }
49
50 391
    public function withComponentMetadata(Mapping\ClassMetadata $componentMetadata) : ValueGeneratorMetadataBuilder
51
    {
52 391
        $this->componentMetadata = $componentMetadata;
53
54 391
        return $this;
55
    }
56
57 391
    public function withFieldName(string $fieldName) : ValueGeneratorMetadataBuilder
58
    {
59 391
        $this->fieldName = $fieldName;
60
61 391
        return $this;
62
    }
63
64 391
    public function withFieldType(Type $fieldType) : ValueGeneratorMetadataBuilder
65
    {
66 391
        $this->fieldType = $fieldType;
67
68 391
        return $this;
69
    }
70
71 391
    public function withGeneratedValueAnnotation(
72
        ?Annotation\GeneratedValue $generatedValueAnnotation
73
    ) : ValueGeneratorMetadataBuilder {
74 391
        $this->generatedValueAnnotation = $generatedValueAnnotation;
75
76 391
        return $this;
77
    }
78
79 391
    public function withSequenceGeneratorAnnotation(
80
        ?Annotation\SequenceGenerator $sequenceGeneratorAnnotation
81
    ) : ValueGeneratorMetadataBuilder {
82 391
        $this->sequenceGeneratorAnnotation = $sequenceGeneratorAnnotation;
83
84 391
        return $this;
85
    }
86
87 391
    public function withCustomIdGeneratorAnnotation(
88
        ?Annotation\CustomIdGenerator $customIdGeneratorAnnotation
89
    ) : ValueGeneratorMetadataBuilder {
90 391
        $this->customIdGeneratorAnnotation = $customIdGeneratorAnnotation;
91
92 391
        return $this;
93
    }
94
95 391
    public function build() : ?Mapping\ValueGeneratorMetadata
96
    {
97
        // Validate required fields
98 391
        assert($this->componentMetadata !== null);
99 391
        assert($this->fieldName !== null);
100 391
        assert($this->fieldType !== null);
101
102 391
        if (! $this->generatedValueAnnotation) {
103 74
            return null;
104
        }
105
106 338
        $platform      = $this->metadataBuildingContext->getTargetPlatform();
107 338
        $strategy      = strtoupper($this->generatedValueAnnotation->strategy);
108 338
        $generatorType = constant(sprintf('%s::%s', Mapping\GeneratorType::class, $strategy));
109
110 338
        if (in_array($generatorType, [Mapping\GeneratorType::AUTO, Mapping\GeneratorType::IDENTITY], true)) {
111 300
            $generatorType = $platform->prefersSequences() || $platform->usesSequenceEmulatedIdentityColumns()
112 15
                ? Mapping\GeneratorType::SEQUENCE
113 300
                : ($platform->prefersIdentityColumns() ? Mapping\GeneratorType::IDENTITY : Mapping\GeneratorType::TABLE);
114
        }
115
116
        switch ($generatorType) {
117 338
            case Mapping\GeneratorType::IDENTITY:
118 285
                $generator = $this->fieldType->getName() === 'bigint'
119 1
                    ? new Generator\BigIntegerIdentityGenerator()
120 285
                    : new Generator\IdentityGenerator();
121
122 285
                return new Mapping\ValueGeneratorMetadata($generatorType, $generator);
123
124
                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...
125
126 56
            case Mapping\GeneratorType::SEQUENCE:
127 21
                $sequenceName   = null;
128 21
                $allocationSize = 1;
129
130 21
                if ($this->sequenceGeneratorAnnotation) {
131 12
                    $sequenceName   = $this->sequenceGeneratorAnnotation->sequenceName ?? null;
132 12
                    $allocationSize = $this->sequenceGeneratorAnnotation->allocationSize ?? 1;
133
                }
134
135 21
                if (empty($sequenceName)) {
136 9
                    $sequenceName = $platform->fixSchemaElementName(
137 9
                        sprintf(
138 9
                            '%s_%s_seq',
139 9
                            $platform->getSequencePrefix(
140 9
                                $this->componentMetadata->getTableName(),
141 9
                                $this->componentMetadata->getSchemaName()
142
                            ),
143 9
                            $this->fieldName
144
                        )
145
                    );
146
                }
147
148 21
                $generator = new Generator\SequenceGenerator($sequenceName, $allocationSize);
149
150 21
                return new Mapping\ValueGeneratorMetadata($generatorType, $generator);
151
152
                break;
153
154 35
            case Mapping\GeneratorType::CUSTOM:
155 5
                assert($this->customIdGeneratorAnnotation !== null);
156
157 5
                if (empty($this->customIdGeneratorAnnotation->class)) {
158
                    $message = 'Cannot instantiate custom generator, no class has been defined';
159
160
                    throw new Mapping\MappingException($message);
161
                }
162
163
                try {
164 5
                    $reflectionClass = new ReflectionClass($this->customIdGeneratorAnnotation->class);
165 5
                    $generator       = $reflectionClass->newInstanceArgs($this->customIdGeneratorAnnotation->arguments);
166
167 5
                    return new Mapping\ValueGeneratorMetadata($generatorType, $generator);
168
                } catch (ReflectionException $exception) {
169
                    $message = sprintf(
170
                        'Cannot instantiate custom generator : %s',
171
                        $this->customIdGeneratorAnnotation->class
172
                    );
173
174
                    throw new Mapping\MappingException($message);
175
                }
176
177
                break;
178
179 30
            case GeneratorType::TABLE:
180
                throw TableGeneratorNotImplementedYet::create();
181
182 30
            case null: // Function constant() returns null if it is not defined in class.
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $generatorType of type mixed|string against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
183
                throw UnknownGeneratorType::create($strategy);
184
185 30
            case Mapping\GeneratorType::NONE:
186
            default:
187 30
                return null;
188
        }
189
    }
190
}
191