Failed Conditions
Push — master ( b07393...21bc80 )
by Guilherme
09:49
created

ClassMetadataBuilder::buildTable()   A

Complexity

Conditions 5
Paths 3

Size

Total Lines 24
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 16
c 0
b 0
f 0
nc 3
nop 1
dl 0
loc 24
ccs 15
cts 15
cp 1
crap 5
rs 9.4222
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
use function constant;
11
use function sprintf;
12
13
class ClassMetadataBuilder
14
{
15
    /** @var Mapping\ClassMetadataBuildingContext */
16
    private $metadataBuildingContext;
17
18
    /** @var TableMetadataBuilder */
19
    protected $tableMetadataBuilder;
20
21
    /** @var CacheMetadataBuilder */
22
    protected $cacheMetadataBuilder;
23
24
    /** @var DiscriminatorColumnMetadataBuilder */
25
    protected $discriminatorColumnMetadataBuilder;
26
27
    /** @var string */
28
    private $className;
29
30
    /** @var Mapping\ComponentMetadata|null */
31
    private $parentMetadata;
32
33
    /** @var Annotation\Entity|null */
34
    protected $entityAnnotation;
35
36
    /** @var Annotation\Embeddable|null */
37
    protected $embeddableAnnotation;
38
39
    /** @var Annotation\MappedSuperclass|null */
40
    protected $mappedSuperclassAnnotation;
41
42
    /** @var Annotation\InheritanceType|null */
43
    protected $inheritanceTypeAnnotation;
44
45
    /** @var Annotation\Table|null */
46
    protected $tableAnnotation;
47
48
    /** @var Annotation\Cache|null */
49
    protected $cacheAnnotation;
50
51
    /** @var Annotation\ChangeTrackingPolicy|null */
52
    protected $changeTrackingPolicyAnnotation;
53
54
    /** @var Annotation\DiscriminatorColumn|null */
55
    protected $discriminatorColumnAnnotation;
56
57
    /** @var Annotation\DiscriminatorMap|null */
58
    protected $discriminatorMapAnnotation;
59
60 413
    public function __construct(
61
        Mapping\ClassMetadataBuildingContext $metadataBuildingContext,
62
        ?TableMetadataBuilder $tableMetadataBuilder = null,
63
        ?CacheMetadataBuilder $cacheMetadataBuilder = null,
64
        ?DiscriminatorColumnMetadataBuilder $discriminatorColumnMetadataBuilder = null
65
    ) {
66 413
        $this->metadataBuildingContext            = $metadataBuildingContext;
67 413
        $this->tableMetadataBuilder               = $tableMetadataBuilder ?: new TableMetadataBuilder($metadataBuildingContext);
68 413
        $this->cacheMetadataBuilder               = $cacheMetadataBuilder ?: new CacheMetadataBuilder($metadataBuildingContext);
69 413
        $this->discriminatorColumnMetadataBuilder = $discriminatorColumnMetadataBuilder?: new DiscriminatorColumnMetadataBuilder($metadataBuildingContext);
70 413
    }
71
72 413
    public function withClassName(string $className) : ClassMetadataBuilder
73
    {
74 413
        $this->className = $className;
75
76 413
        return $this;
77
    }
78
79 413
    public function withParentMetadata(?Mapping\ComponentMetadata $parentMetadata) : ClassMetadataBuilder
80
    {
81 413
        $this->parentMetadata = $parentMetadata;
82
83 413
        return $this;
84
    }
85
86 413
    public function withEntityAnnotation(?Annotation\Entity $entityAnnotation) : ClassMetadataBuilder
87
    {
88 413
        $this->entityAnnotation = $entityAnnotation;
89
90 413
        return $this;
91
    }
92
93 413
    public function withEmbeddableAnnotation(?Annotation\Embeddable $embeddableAnnotation) : ClassMetadataBuilder
94
    {
95 413
        $this->embeddableAnnotation = $embeddableAnnotation;
96
97 413
        return $this;
98
    }
99
100 413
    public function withMappedSuperclassAnnotation(?Annotation\MappedSuperclass $mappedSuperclassAnnotation) : ClassMetadataBuilder
101
    {
102 413
        $this->mappedSuperclassAnnotation = $mappedSuperclassAnnotation;
103
104 413
        return $this;
105
    }
106
107 413
    public function withInheritanceTypeAnnotation(?Annotation\InheritanceType $inheritanceTypeAnnotation) : ClassMetadataBuilder
108
    {
109 413
        $this->inheritanceTypeAnnotation = $inheritanceTypeAnnotation;
110
111 413
        return $this;
112
    }
113
114 413
    public function withTableAnnotation(?Annotation\Table $tableAnnotation) : ClassMetadataBuilder
115
    {
116 413
        $this->tableAnnotation = $tableAnnotation;
117
118 413
        if ($tableAnnotation !== null) {
119 225
            $this->tableMetadataBuilder->withTableAnnotation($tableAnnotation);
120
        }
121
122 413
        return $this;
123
    }
124
125 413
    public function withCacheAnnotation(?Annotation\Cache $cacheAnnotation) : ClassMetadataBuilder
126
    {
127 413
        $this->cacheAnnotation = $cacheAnnotation;
128
129 413
        if ($cacheAnnotation !== null) {
130 20
            $this->cacheMetadataBuilder->withCacheAnnotation($cacheAnnotation);
131
        }
132
133 413
        return $this;
134
    }
135
136 413
    public function withChangeTrackingPolicyAnnotation(?Annotation\ChangeTrackingPolicy $changeTrackingPolicyAnnotation) : ClassMetadataBuilder
137
    {
138 413
        $this->changeTrackingPolicyAnnotation = $changeTrackingPolicyAnnotation;
139
140 413
        return $this;
141
    }
142
143 413
    public function withDiscriminatorColumnAnnotation(?Annotation\DiscriminatorColumn $discriminatorColumnAnnotation) : ClassMetadataBuilder
144
    {
145 413
        $this->discriminatorColumnAnnotation = $discriminatorColumnAnnotation;
146
147 413
        if ($discriminatorColumnAnnotation !== null) {
148 70
            $this->discriminatorColumnMetadataBuilder->withDiscriminatorColumnAnnotation($discriminatorColumnAnnotation);
149
        }
150
151 413
        return $this;
152
    }
153
154 413
    public function withDiscriminatorMapAnnotation(?Annotation\DiscriminatorMap $discriminatorMapAnnotation) : ClassMetadataBuilder
155
    {
156 413
        $this->discriminatorMapAnnotation = $discriminatorMapAnnotation;
157
158 413
        return $this;
159
    }
160
161 413
    public function build() : Mapping\ClassMetadata
162
    {
163 413
        assert($this->className !== null);
164
165 413
        $reflectionService = $this->metadataBuildingContext->getReflectionService();
166 413
        $reflectionClass   = $reflectionService->getClass($this->className);
167 413
        $className         = $reflectionClass ? $reflectionClass->getName() : $this->className;
168
169 413
        $classMetadata = new Mapping\ClassMetadata($className, $this->parentMetadata);
170
171 413
        switch (true) {
172 413
            case $this->entityAnnotation !== null:
173 406
                $this->buildEntityClassMetadata($classMetadata);
174 406
                break;
175
176 34
            case $this->mappedSuperclassAnnotation !== null:
177 28
                $this->buildMappedSuperclassMetadata($classMetadata);
178 28
                break;
179
180 6
            case $this->embeddableAnnotation !== null:
181
                $this->buildEmbeddableMetadata($classMetadata);
182
                break;
183
184
            default:
185 6
                throw Mapping\MappingException::classIsNotAValidEntityOrMappedSuperClass($this->className);
186
        }
187
188 407
        $this->buildCache($classMetadata);
189
190 407
        return $classMetadata;
191
    }
192
193 406
    protected function buildEntityClassMetadata(Mapping\ClassMetadata $classMetadata) : void
194
    {
195 406
        $classMetadata->isMappedSuperclass = false;
196 406
        $classMetadata->isEmbeddedClass    = false;
197
198 406
        if ($this->entityAnnotation->repositoryClass !== null) {
199 3
            $classMetadata->setCustomRepositoryClassName($this->entityAnnotation->repositoryClass);
200
        }
201
202 406
        if ($this->entityAnnotation->readOnly) {
203 1
            $classMetadata->asReadOnly();
204
        }
205
206 406
        $this->buildTable($classMetadata);
207 406
        $this->buildInheritance($classMetadata);
208 406
        $this->buildChangeTrackingPolicy($classMetadata);
209 406
    }
210
211 28
    protected function buildMappedSuperclassMetadata(Mapping\ClassMetadata $classMetadata) : void
212
    {
213 28
        $classMetadata->isMappedSuperclass = true;
214 28
        $classMetadata->isEmbeddedClass    = false;
215
216 28
        if ($this->mappedSuperclassAnnotation->repositoryClass !== null) {
217 3
            $classMetadata->setCustomRepositoryClassName($this->mappedSuperclassAnnotation->repositoryClass);
218
        }
219 28
    }
220
221
    protected function buildEmbeddableMetadata(Mapping\ClassMetadata $classMetadata) : void
222
    {
223
        $classMetadata->isMappedSuperclass = false;
224
        $classMetadata->isEmbeddedClass    = true;
225
    }
226
227 406
    protected function buildTable(Mapping\ClassMetadata $classMetadata) : void
228
    {
229 406
        $parentMetadata = $classMetadata->getParent();
230 406
        $tableMetadata  = null;
231
232 406
        if ($parentMetadata instanceof Mapping\ClassMetadata
233 406
            && $parentMetadata->inheritanceType === Mapping\InheritanceType::SINGLE_TABLE) {
234
            // Handle the case where a middle mapped super class inherits from a single table inheritance tree.
235
            do {
236 31
                if (! $parentMetadata->isMappedSuperclass) {
237 31
                    $tableMetadata = $parentMetadata->table;
238 31
                    break;
239
                }
240
241 4
                $parentMetadata = $parentMetadata->getParent();
242 31
            } while ($parentMetadata !== null);
243
        } else {
244 406
            $tableMetadata = $this->tableMetadataBuilder
245 406
                ->withEntityClassMetadata($classMetadata)
246 406
                ->withTableAnnotation($this->tableAnnotation)
247 406
                ->build();
248
        }
249
250 406
        $classMetadata->setTable($tableMetadata);
0 ignored issues
show
Bug introduced by
It seems like $tableMetadata can also be of type null; however, parameter $table of Doctrine\ORM\Mapping\ClassMetadata::setTable() does only seem to accept Doctrine\ORM\Mapping\TableMetadata, 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

250
        $classMetadata->setTable(/** @scrutinizer ignore-type */ $tableMetadata);
Loading history...
251 406
    }
252
253 406
    protected function buildInheritance(Mapping\ClassMetadata $classMetadata) : void
254
    {
255 406
        if ($this->inheritanceTypeAnnotation !== null) {
256 90
            $typeName = $this->inheritanceTypeAnnotation->value;
257 90
            $type     = constant(sprintf('%s::%s', Mapping\InheritanceType::class, $typeName));
258
259 90
            $classMetadata->setInheritanceType($type);
260
261 90
            if ($type !== Mapping\InheritanceType::NONE) {
262 90
                $discriminatorColumn = $this->discriminatorColumnMetadataBuilder
263 90
                    ->withComponentMetadata($classMetadata)
264 90
                    ->withDiscriminatorColumnAnnotation($this->discriminatorColumnAnnotation)
265 90
                    ->build();
266
267 90
                $classMetadata->setDiscriminatorColumn($discriminatorColumn);
268
269 90
                if ($this->discriminatorMapAnnotation !== null) {
270 87
                    $classMetadata->setDiscriminatorMap($this->discriminatorMapAnnotation->value);
271
                }
272
            }
273
        }
274 406
    }
275
276 407
    protected function buildCache(Mapping\ClassMetadata $classMetadata) : void
277
    {
278 407
        if ($this->cacheAnnotation !== null) {
279 20
            $cacheMetadata = $this->cacheMetadataBuilder
280 20
                ->withComponentMetadata($classMetadata)
281 20
                ->build();
282
283 20
            $classMetadata->setCache($cacheMetadata);
284
        }
285 407
    }
286
287 406
    protected function buildChangeTrackingPolicy(Mapping\ClassMetadata $classMetadata) : void
288
    {
289 406
        if ($this->changeTrackingPolicyAnnotation !== null) {
290 6
            $policyName = $this->changeTrackingPolicyAnnotation->value;
291 6
            $policy     = constant(sprintf('%s::%s', Mapping\ChangeTrackingPolicy::class, $policyName));
292
293 6
            $classMetadata->setChangeTrackingPolicy($policy);
294
        }
295 406
    }
296
}
297