Failed Conditions
Push — master ( a3e53b...559253 )
by Guilherme
14:58
created

PropertyMetadataBuilder   B

Complexity

Total Complexity 44

Size/Duplication

Total Lines 425
Duplicated Lines 0 %

Test Coverage

Coverage 93.57%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 177
dl 0
loc 425
ccs 160
cts 171
cp 0.9357
rs 8.8798
c 1
b 0
f 0
wmc 44

20 Methods

Rating   Name   Duplication   Size   Complexity  
A withJoinTableAnnotation() 0 7 1
A withIdAnnotation() 0 10 1
A withOneToOneAnnotation() 0 16 2
A withVersionAnnotation() 0 7 1
A withOrderByAnnotation() 0 8 1
A withOneToManyAnnotation() 0 16 2
A withComponentMetadata() 0 13 1
B __construct() 0 18 8
A withColumnAnnotation() 0 16 2
A withJoinColumnAnnotation() 0 8 1
A withCacheAnnotation() 0 10 1
A withManyToOneAnnotation() 0 16 2
A withManyToManyAnnotation() 0 16 2
A withCustomIdGeneratorAnnotation() 0 7 1
A withJoinColumnsAnnotation() 0 8 1
A withEmbeddedAnnotation() 0 16 2
C build() 0 88 12
A withSequenceGeneratorAnnotation() 0 7 1
A withFieldName() 0 13 1
A withGeneratedValueAnnotation() 0 7 1

How to fix   Complexity   

Complex Class

Complex classes like PropertyMetadataBuilder often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use PropertyMetadataBuilder, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\ORM\Mapping\Builder;
6
7
use Doctrine\ORM\Annotation;
8
use Doctrine\ORM\Mapping;
9
use function assert;
10
11
class PropertyMetadataBuilder
12
{
13
    /** @var Mapping\ClassMetadataBuildingContext */
14
    private $metadataBuildingContext;
15
16
    /** @var FieldMetadataBuilder */
17
    private $fieldMetadataBuilder;
18
19
    /** @var OneToOneAssociationMetadataBuilder */
20
    private $oneToOneAssociationMetadataBuilder;
21
22
    /** @var ManyToOneAssociationMetadataBuilder */
23
    private $manyToOneAssociationMetadataBuilder;
24
25
    /** @var OneToManyAssociationMetadataBuilder */
26
    private $oneToManyAssociationMetadataBuilder;
27
28
    /** @var ManyToManyAssociationMetadataBuilder */
29
    private $manyToManyAssociationMetadataBuilder;
30
31
    /** @var EmbeddedMetadataBuilder */
32
    private $embeddedMetadataBuilder;
33
34
    /** @var TransientMetadataBuilder */
35
    private $transientMetadataBuilder;
36
37
    /** @var Mapping\ClassMetadata */
38
    private $componentMetadata;
39
40
    /** @var string */
41
    private $fieldName;
42
43
    /** @var Annotation\Id|null */
44
    private $idAnnotation;
45
46
    /** @var Annotation\Version|null */
47
    private $versionAnnotation;
48
49
    /** @var Annotation\Cache|null */
50
    private $cacheAnnotation;
51
52
    /** @var Annotation\Column|null */
53
    private $columnAnnotation;
54
55
    /** @var Annotation\Embedded|null */
56
    private $embeddedAnnotation;
57
58
    /** @var Annotation\OneToOne|null */
59
    private $oneToOneAnnotation;
60
61
    /** @var Annotation\ManyToOne|null */
62
    private $manyToOneAnnotation;
63
64
    /** @var Annotation\OneToMany|null */
65
    private $oneToManyAnnotation;
66
67
    /** @var Annotation\ManyToMany|null */
68
    private $manyToManyAnnotation;
69
70
    /** @var Annotation\JoinTable|null */
71
    private $joinTableAnnotation;
72
73
    /** @var Annotation\JoinColumns|null */
74
    private $joinColumnsAnnotation;
75
76
    /** @var Annotation\JoinColumn|null */
77
    private $joinColumnAnnotation;
78
79
    /** @var Annotation\OrderBy|null */
80
    private $orderByAnnotation;
81
82
    /** @var Annotation\GeneratedValue|null */
83
    private $generatedValueAnnotation;
84
85
    /** @var Annotation\SequenceGenerator|null */
86
    private $sequenceGeneratorAnnotation;
87
88
    /** @var Annotation\CustomIdGenerator|null */
89
    private $customIdGeneratorAnnotation;
90
91 408
    public function __construct(
92
        Mapping\ClassMetadataBuildingContext $metadataBuildingContext,
93
        ?FieldMetadataBuilder $fieldMetadataBuilder = null,
94
        ?OneToOneAssociationMetadataBuilder $oneToOneAssociationMetadataBuilder = null,
95
        ?ManyToOneAssociationMetadataBuilder $manyToOneAssociationMetadataBuilder = null,
96
        ?OneToManyAssociationMetadataBuilder $oneToManyAssociationMetadataBuilder = null,
97
        ?ManyToManyAssociationMetadataBuilder $manyToManyAssociationMetadataBuilder = null,
98
        ?EmbeddedMetadataBuilder $embeddedMetadataBuilder = null,
99
        ?TransientMetadataBuilder $transientMetadataBuilder = null
100
    ) {
101 408
        $this->metadataBuildingContext              = $metadataBuildingContext;
102 408
        $this->fieldMetadataBuilder                 = $fieldMetadataBuilder ?: new FieldMetadataBuilder($metadataBuildingContext);
103 408
        $this->oneToOneAssociationMetadataBuilder   = $oneToOneAssociationMetadataBuilder ?: new OneToOneAssociationMetadataBuilder($metadataBuildingContext);
104 408
        $this->manyToOneAssociationMetadataBuilder  = $manyToOneAssociationMetadataBuilder ?: new ManyToOneAssociationMetadataBuilder($metadataBuildingContext);
105 408
        $this->oneToManyAssociationMetadataBuilder  = $oneToManyAssociationMetadataBuilder ?: new OneToManyAssociationMetadataBuilder($metadataBuildingContext);
106 408
        $this->manyToManyAssociationMetadataBuilder = $manyToManyAssociationMetadataBuilder ?: new ManyToManyAssociationMetadataBuilder($metadataBuildingContext);
107 408
        $this->embeddedMetadataBuilder              = $embeddedMetadataBuilder ?: new EmbeddedMetadataBuilder($metadataBuildingContext);
108 408
        $this->transientMetadataBuilder             = $transientMetadataBuilder ?: new TransientMetadataBuilder($metadataBuildingContext);
109 408
    }
110
111 407
    public function withComponentMetadata(Mapping\ClassMetadata $componentMetadata) : PropertyMetadataBuilder
112
    {
113 407
        $this->componentMetadata = $componentMetadata;
114
115 407
        $this->fieldMetadataBuilder->withComponentMetadata($componentMetadata);
116 407
        $this->oneToOneAssociationMetadataBuilder->withComponentMetadata($componentMetadata);
117 407
        $this->manyToOneAssociationMetadataBuilder->withComponentMetadata($componentMetadata);
118 407
        $this->oneToManyAssociationMetadataBuilder->withComponentMetadata($componentMetadata);
119 407
        $this->manyToManyAssociationMetadataBuilder->withComponentMetadata($componentMetadata);
120 407
        $this->embeddedMetadataBuilder->withComponentMetadata($componentMetadata);
121 407
        $this->transientMetadataBuilder->withComponentMetadata($componentMetadata);
122
123 407
        return $this;
124
    }
125
126 407
    public function withFieldName(string $fieldName) : PropertyMetadataBuilder
127
    {
128 407
        $this->fieldName = $fieldName;
129
130 407
        $this->fieldMetadataBuilder->withFieldName($fieldName);
131 407
        $this->oneToOneAssociationMetadataBuilder->withFieldName($fieldName);
132 407
        $this->manyToOneAssociationMetadataBuilder->withFieldName($fieldName);
133 407
        $this->oneToManyAssociationMetadataBuilder->withFieldName($fieldName);
134 407
        $this->manyToManyAssociationMetadataBuilder->withFieldName($fieldName);
135 407
        $this->embeddedMetadataBuilder->withFieldName($fieldName);
136 407
        $this->transientMetadataBuilder->withFieldName($fieldName);
137
138 407
        return $this;
139
    }
140
141 407
    public function withIdAnnotation(?Annotation\Id $idAnnotation) : PropertyMetadataBuilder
142
    {
143 407
        $this->idAnnotation = $idAnnotation;
144
145 407
        $this->fieldMetadataBuilder->withIdAnnotation($idAnnotation);
146 407
        $this->oneToOneAssociationMetadataBuilder->withIdAnnotation($idAnnotation);
147 407
        $this->manyToOneAssociationMetadataBuilder->withIdAnnotation($idAnnotation);
148 407
        $this->embeddedMetadataBuilder->withIdAnnotation($idAnnotation);
149
150 407
        return $this;
151
    }
152
153 390
    public function withCacheAnnotation(?Annotation\Cache $cacheAnnotation) : PropertyMetadataBuilder
154
    {
155 390
        $this->cacheAnnotation = $cacheAnnotation;
156
157 390
        $this->oneToOneAssociationMetadataBuilder->withCacheAnnotation($cacheAnnotation);
158 390
        $this->manyToOneAssociationMetadataBuilder->withCacheAnnotation($cacheAnnotation);
159 390
        $this->oneToManyAssociationMetadataBuilder->withCacheAnnotation($cacheAnnotation);
160 390
        $this->manyToManyAssociationMetadataBuilder->withCacheAnnotation($cacheAnnotation);
161
162 390
        return $this;
163
    }
164
165 403
    public function withColumnAnnotation(?Annotation\Column $columnAnnotation) : PropertyMetadataBuilder
166
    {
167 403
        $this->columnAnnotation = $columnAnnotation;
168
169 403
        if ($columnAnnotation !== null) {
170
            // Make sure all other property type annotations are cleared
171 398
            $this->embeddedAnnotation   = null;
172 398
            $this->oneToOneAnnotation   = null;
173 398
            $this->manyToOneAnnotation  = null;
174 398
            $this->oneToManyAnnotation  = null;
175 398
            $this->manyToManyAnnotation = null;
176
177 398
            $this->fieldMetadataBuilder->withColumnAnnotation($columnAnnotation);
178
        }
179
180 403
        return $this;
181
    }
182
183 373
    public function withEmbeddedAnnotation(?Annotation\Embedded $embeddedAnnotation) : PropertyMetadataBuilder
184
    {
185 373
        $this->embeddedAnnotation = $embeddedAnnotation;
186
187 373
        if ($embeddedAnnotation !== null) {
188
            // Make sure all other property type annotations are cleared
189
            $this->columnAnnotation     = null;
190
            $this->oneToOneAnnotation   = null;
191
            $this->manyToOneAnnotation  = null;
192
            $this->oneToManyAnnotation  = null;
193
            $this->manyToManyAnnotation = null;
194
195
            $this->embeddedMetadataBuilder->withEmbeddedAnnotation($embeddedAnnotation);
196
        }
197
198 373
        return $this;
199
    }
200
201 380
    public function withOneToOneAnnotation(?Annotation\OneToOne $oneToOneAnnotation) : PropertyMetadataBuilder
202
    {
203 380
        $this->oneToOneAnnotation = $oneToOneAnnotation;
204
205 380
        if ($oneToOneAnnotation !== null) {
206
            // Make sure all other property type annotations are cleared
207 118
            $this->columnAnnotation     = null;
208 118
            $this->embeddedAnnotation   = null;
209 118
            $this->manyToOneAnnotation  = null;
210 118
            $this->oneToManyAnnotation  = null;
211 118
            $this->manyToManyAnnotation = null;
212
213 118
            $this->oneToOneAssociationMetadataBuilder->withOneToOneAnnotation($oneToOneAnnotation);
214
        }
215
216 380
        return $this;
217
    }
218
219 381
    public function withManyToOneAnnotation(?Annotation\ManyToOne $manyToOneAnnotation) : PropertyMetadataBuilder
220
    {
221 381
        $this->manyToOneAnnotation = $manyToOneAnnotation;
222
223 381
        if ($manyToOneAnnotation !== null) {
224
            // Make sure all other property type annotations are cleared
225 149
            $this->columnAnnotation     = null;
226 149
            $this->embeddedAnnotation   = null;
227 149
            $this->oneToOneAnnotation   = null;
228 149
            $this->oneToManyAnnotation  = null;
229 149
            $this->manyToManyAnnotation = null;
230
231 149
            $this->manyToOneAssociationMetadataBuilder->withManyToOneAnnotation($manyToOneAnnotation);
232
        }
233
234 381
        return $this;
235
    }
236
237 382
    public function withOneToManyAnnotation(?Annotation\OneToMany $oneToManyAnnotation) : PropertyMetadataBuilder
238
    {
239 382
        $this->oneToManyAnnotation = $oneToManyAnnotation;
240
241 382
        if ($oneToManyAnnotation !== null) {
242
            // Make sure all other property type annotations are cleared
243 118
            $this->columnAnnotation     = null;
244 118
            $this->embeddedAnnotation   = null;
245 118
            $this->oneToOneAnnotation   = null;
246 118
            $this->manyToOneAnnotation  = null;
247 118
            $this->manyToManyAnnotation = null;
248
249 118
            $this->oneToManyAssociationMetadataBuilder->withOneToManyAnnotation($oneToManyAnnotation);
250
        }
251
252 382
        return $this;
253
    }
254
255 387
    public function withManyToManyAnnotation(?Annotation\ManyToMany $manyToManyAnnotation) : PropertyMetadataBuilder
256
    {
257 387
        $this->manyToManyAnnotation = $manyToManyAnnotation;
258
259 387
        if ($manyToManyAnnotation !== null) {
260
            // Make sure all other property type annotations are cleared
261 103
            $this->columnAnnotation    = null;
262 103
            $this->embeddedAnnotation  = null;
263 103
            $this->oneToOneAnnotation  = null;
264 103
            $this->manyToOneAnnotation = null;
265 103
            $this->oneToManyAnnotation = null;
266
267 103
            $this->manyToManyAssociationMetadataBuilder->withManyToManyAnnotation($manyToManyAnnotation);
268
        }
269
270 387
        return $this;
271
    }
272
273 387
    public function withJoinTableAnnotation(?Annotation\JoinTable $joinTableAnnotation) : PropertyMetadataBuilder
274
    {
275 387
        $this->joinTableAnnotation = $joinTableAnnotation;
276
277 387
        $this->manyToManyAssociationMetadataBuilder->withJoinTableAnnotation($joinTableAnnotation);
278
279 387
        return $this;
280
    }
281
282 386
    public function withJoinColumnsAnnotation(?Annotation\JoinColumns $joinColumnsAnnotation) : PropertyMetadataBuilder
283
    {
284 386
        $this->joinColumnsAnnotation = $joinColumnsAnnotation;
285
286 386
        $this->oneToOneAssociationMetadataBuilder->withJoinColumnsAnnotation($joinColumnsAnnotation);
287 386
        $this->manyToOneAssociationMetadataBuilder->withJoinColumnsAnnotation($joinColumnsAnnotation);
288
289 386
        return $this;
290
    }
291
292 386
    public function withJoinColumnAnnotation(?Annotation\JoinColumn $joinColumnAnnotation) : PropertyMetadataBuilder
293
    {
294 386
        $this->joinColumnAnnotation = $joinColumnAnnotation;
295
296 386
        $this->oneToOneAssociationMetadataBuilder->withJoinColumnAnnotation($joinColumnAnnotation);
297 386
        $this->manyToOneAssociationMetadataBuilder->withJoinColumnAnnotation($joinColumnAnnotation);
298
299 386
        return $this;
300
    }
301
302 388
    public function withOrderByAnnotation(?Annotation\OrderBy $orderByAnnotation) : PropertyMetadataBuilder
303
    {
304 388
        $this->orderByAnnotation = $orderByAnnotation;
305
306 388
        $this->oneToManyAssociationMetadataBuilder->withOrderByAnnotation($orderByAnnotation);
307 388
        $this->manyToManyAssociationMetadataBuilder->withOrderByAnnotation($orderByAnnotation);
308
309 388
        return $this;
310
    }
311
312 407
    public function withVersionAnnotation(?Annotation\Version $versionAnnotation) : PropertyMetadataBuilder
313
    {
314 407
        $this->versionAnnotation = $versionAnnotation;
315
316 407
        $this->fieldMetadataBuilder->withVersionAnnotation($versionAnnotation);
317
318 407
        return $this;
319
    }
320
321 401
    public function withGeneratedValueAnnotation(?Annotation\GeneratedValue $generatedValueAnnotation) : PropertyMetadataBuilder
322
    {
323 401
        $this->generatedValueAnnotation = $generatedValueAnnotation;
324
325 401
        $this->fieldMetadataBuilder->withGeneratedValueAnnotation($this->generatedValueAnnotation);
326
327 401
        return $this;
328
    }
329
330 401
    public function withSequenceGeneratorAnnotation(?Annotation\SequenceGenerator $sequenceGeneratorAnnotation) : PropertyMetadataBuilder
331
    {
332 401
        $this->sequenceGeneratorAnnotation = $sequenceGeneratorAnnotation;
333
334 401
        $this->fieldMetadataBuilder->withSequenceGeneratorAnnotation($this->sequenceGeneratorAnnotation);
335
336 401
        return $this;
337
    }
338
339 401
    public function withCustomIdGeneratorAnnotation(?Annotation\CustomIdGenerator $customIdGeneratorAnnotation) : PropertyMetadataBuilder
340
    {
341 401
        $this->customIdGeneratorAnnotation = $customIdGeneratorAnnotation;
342
343 401
        $this->fieldMetadataBuilder->withCustomIdGeneratorAnnotation($this->customIdGeneratorAnnotation);
344
345 401
        return $this;
346
    }
347
348 407
    public function build() : Mapping\Property
349
    {
350
        // Validate required fields
351 407
        assert($this->componentMetadata !== null);
352 407
        assert($this->fieldName !== null);
353
354 407
        $componentClassName = $this->componentMetadata->getClassName();
355
356 407
        switch (true) {
357 407
            case $this->columnAnnotation !== null:
358 398
                $propertyMetadata = $this->fieldMetadataBuilder->build();
359
360
                // Prevent column duplication
361 398
                $columnName = $propertyMetadata->getColumnName();
362
363 398
                if ($this->componentMetadata->checkPropertyDuplication($columnName)) {
0 ignored issues
show
Bug introduced by
It seems like $columnName can also be of type null; however, parameter $columnName of Doctrine\ORM\Mapping\Cla...ckPropertyDuplication() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

363
                if ($this->componentMetadata->checkPropertyDuplication(/** @scrutinizer ignore-type */ $columnName)) {
Loading history...
364
                    throw Mapping\MappingException::duplicateColumnName($componentClassName, $columnName);
365
                }
366
367 398
                return $propertyMetadata;
368 272
            case $this->embeddedAnnotation !== null:
369
                return $this->embeddedMetadataBuilder->build();
370
371
                // Prevent column duplication
372
                // @todo guilhermeblanco Open an issue to discuss making this scenario impossible.
373
//                $classMetadataFactory = $this->metadataBuildingContext->getClassMetadataFactory();
374
//                $targetEmbeddable     = $classMetadataFactory->getMetadataFor($embeddedMetadata->getTargetEntity());
375
//
376
//                foreach ($targetEmbeddable->getColumnsIterator() as $columnMetadata) {
377
//                    $columnName = ($embeddedMetadata->getColumnPrefix() ?: '') . $columnMetadata->getColumnName();
378
//
379
//                    if ($this->componentMetadata->checkPropertyDuplication($columnName)) {
380
//                        throw Mapping\MappingException::duplicateColumnName($componentClassName, $columnName);
381
//                }
382
//
383
//                return $embeddedMetadata;
384 272
            case $this->oneToOneAnnotation !== null:
385 118
                return $this->oneToOneAssociationMetadataBuilder->build();
386
387
                // Prevent column duplication
388
                // @todo guilhermeblanco Open an issue to discuss making this scenario impossible.
389
//                foreach ($propertyMetadata->getJoinColumns() as $joinColumnMetadata) {
390
//                    $columnName = $joinColumnMetadata->getColumnName();
391
//
392
//                    if ($this->componentMetadata->checkPropertyDuplication($columnName)) {
393
//                        throw Mapping\MappingException::duplicateColumnName($componentClassName, $columnName);
394
//                    }
395
//                }
396
//
397
//                return $propertyMetadata;
398 219
            case $this->manyToOneAnnotation !== null:
399 149
                return $this->manyToOneAssociationMetadataBuilder->build();
400
401
                // Prevent column duplication
402
                // @todo guilhermeblanco Open an issue to discuss making this scenario impossible.
403
//                foreach ($propertyMetadata->getJoinColumns() as $joinColumnMetadata) {
404
//                    $columnName = $joinColumnMetadata->getColumnName();
405
//
406
//                    if ($this->componentMetadata->checkPropertyDuplication($columnName)) {
407
//                        throw Mapping\MappingException::duplicateColumnName($componentClassName, $columnName);
408
//                    }
409
//                }
410
//
411
//                return $propertyMetadata;
412 179
            case $this->oneToManyAnnotation !== null:
413 118
                $propertyMetadata = $this->oneToManyAssociationMetadataBuilder->build();
414
415 118
                if ($this->componentMetadata->isMappedSuperclass && ! $propertyMetadata->isOwningSide()) {
416
                    throw Mapping\MappingException::illegalToManyAssociationOnMappedSuperclass(
417
                        $componentClassName,
418
                        $this->fieldName
419
                    );
420
                }
421
422 118
                return $propertyMetadata;
423 119
            case $this->manyToManyAnnotation !== null:
424 103
                $propertyMetadata = $this->manyToManyAssociationMetadataBuilder->build();
425
426 103
                if ($this->componentMetadata->isMappedSuperclass && ! $propertyMetadata->isOwningSide()) {
427 1
                    throw Mapping\MappingException::illegalToManyAssociationOnMappedSuperclass(
428 1
                        $componentClassName,
429 1
                        $this->fieldName
430
                    );
431
                }
432
433 102
                return $propertyMetadata;
434
            default:
435 30
                return $this->transientMetadataBuilder->build();
436
        }
437
    }
438
}
439