Failed Conditions
Push — master ( 6971e7...b11528 )
by Guilherme
08:44
created

JoinTableMetadataBuilder::__construct()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 6
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 2
nc 1
nop 2
dl 0
loc 6
ccs 3
cts 3
cp 1
crap 2
rs 10
c 1
b 0
f 0
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 JoinTableMetadataBuilder
12
{
13
    /** @var Mapping\ClassMetadataBuildingContext */
14
    private $metadataBuildingContext;
15
16
    /** @var JoinColumnMetadataBuilder */
17
    private $joinColumnMetadataBuilder;
18
19
    /** @var Mapping\ClassMetadata */
20
    private $componentMetadata;
21
22
    /** @var string */
23
    private $targetEntity;
24
25
    /** @var string */
26
    private $fieldName;
27
28
    /** @var Annotation\JoinTable|null */
29
    private $joinTableAnnotation;
30
31 89
    public function __construct(
32
        Mapping\ClassMetadataBuildingContext $metadataBuildingContext,
33
        ?JoinColumnMetadataBuilder $joinColumnMetadataBuilder = null
34
    ) {
35 89
        $this->metadataBuildingContext   = $metadataBuildingContext;
36 89
        $this->joinColumnMetadataBuilder = $joinColumnMetadataBuilder ?: new JoinColumnMetadataBuilder($metadataBuildingContext);
37 89
    }
38
39 89
    public function withComponentMetadata(Mapping\ClassMetadata $componentMetadata) : JoinTableMetadataBuilder
40
    {
41 89
        $this->componentMetadata = $componentMetadata;
42
43 89
        $this->joinColumnMetadataBuilder->withComponentMetadata($componentMetadata);
44
45 89
        return $this;
46
    }
47
48 89
    public function withTargetEntity(string $targetEntity) : JoinTableMetadataBuilder
49
    {
50 89
        $this->targetEntity = $targetEntity;
51
52 89
        return $this;
53
    }
54
55 89
    public function withFieldName(string $fieldName) : JoinTableMetadataBuilder
56
    {
57 89
        $this->fieldName = $fieldName;
58
59 89
        $this->joinColumnMetadataBuilder->withFieldName($fieldName);
60
61 89
        return $this;
62
    }
63
64 79
    public function withJoinTableAnnotation(?Annotation\JoinTable $joinTableAnnotation) : JoinTableMetadataBuilder
65
    {
66 79
        $this->joinTableAnnotation = $joinTableAnnotation;
67
68 79
        return $this;
69
    }
70
71 89
    public function build() : Mapping\JoinTableMetadata
72
    {
73
        // Validate required fields
74 89
        assert($this->componentMetadata !== null);
75 89
        assert($this->targetEntity !== null);
76 89
        assert($this->fieldName !== null);
77
78 89
        $namingStrategy    = $this->metadataBuildingContext->getNamingStrategy();
79 89
        $souceEntity       = $this->componentMetadata->getClassName();
80 89
        $joinTableMetadata = new Mapping\JoinTableMetadata();
81
82 89
        $joinTableMetadata->setName($namingStrategy->joinTableName($souceEntity, $this->targetEntity, $this->fieldName));
83
84 89
        if ($this->joinTableAnnotation !== null) {
85 79
            if (! empty($this->joinTableAnnotation->name)) {
86 77
                $joinTableMetadata->setName($this->joinTableAnnotation->name);
87
            }
88
89 79
            if (! empty($this->joinTableAnnotation->schema)) {
90
                $joinTableMetadata->setSchema($this->joinTableAnnotation->schema);
91
            }
92
93
            /** @var Annotation\JoinColumn $joinColumnAnnotation */
94 79
            foreach ($this->joinTableAnnotation->joinColumns as $joinColumnAnnotation) {
95
                // Auto-inject on-delete, column name and referenced column name if not present
96 78
                $referencedColumnName = $joinColumnAnnotation->referencedColumnName ?? $namingStrategy->referenceColumnName();
97 78
                $columnName           = $joinColumnAnnotation->name ?? $namingStrategy->joinKeyColumnName($souceEntity, $referencedColumnName);
98
99 78
                $joinColumnAnnotation->onDelete             = $joinColumnAnnotation->onDelete ?? 'CASCADE';
100 78
                $joinColumnAnnotation->referencedColumnName = $referencedColumnName;
101 78
                $joinColumnAnnotation->name                 = $columnName;
102
103 78
                $this->joinColumnMetadataBuilder->withJoinColumnAnnotation($joinColumnAnnotation);
104
105 78
                $joinTableMetadata->addJoinColumn($this->joinColumnMetadataBuilder->build());
106
            }
107
108 79
            foreach ($this->joinTableAnnotation->inverseJoinColumns as $joinColumnAnnotation) {
109
                // Auto-inject on-delete, column name and referenced column name if not present
110 78
                $referencedColumnName = $joinColumnAnnotation->referencedColumnName ?? $namingStrategy->referenceColumnName();
111 78
                $columnName           = $joinColumnAnnotation->name ?? $namingStrategy->joinKeyColumnName($this->targetEntity, $referencedColumnName);
112
113 78
                $joinColumnAnnotation->onDelete             = $joinColumnAnnotation->onDelete ?? 'CASCADE';
114 78
                $joinColumnAnnotation->referencedColumnName = $referencedColumnName;
115 78
                $joinColumnAnnotation->name                 = $columnName;
116
117 78
                $this->joinColumnMetadataBuilder->withJoinColumnAnnotation($joinColumnAnnotation);
118
119 78
                $joinTableMetadata->addInverseJoinColumn($this->joinColumnMetadataBuilder->build());
120
            }
121
        }
122
123 89
        $selfReferenceEntity = $souceEntity === $this->targetEntity;
124
125 89
        if (! $joinTableMetadata->getJoinColumns()) {
126 11
            $joinColumnAnnotation = new Annotation\JoinColumn();
127
128 11
            $joinColumnAnnotation->onDelete             = 'CASCADE';
129 11
            $joinColumnAnnotation->referencedColumnName = $namingStrategy->referenceColumnName();
130 11
            $joinColumnAnnotation->name                 = $namingStrategy->joinKeyColumnName(
131 11
                $souceEntity,
132 11
                $selfReferenceEntity ? 'source' : $joinColumnAnnotation->referencedColumnName
133
            );
134
135 11
            $this->joinColumnMetadataBuilder->withJoinColumnAnnotation($joinColumnAnnotation);
136
137 11
            $joinTableMetadata->addJoinColumn($this->joinColumnMetadataBuilder->build());
138
        }
139
140 89
        if (! $joinTableMetadata->getInverseJoinColumns()) {
141 11
            $joinColumnAnnotation = new Annotation\JoinColumn();
142
143 11
            $joinColumnAnnotation->onDelete             = 'CASCADE';
144 11
            $joinColumnAnnotation->referencedColumnName = $namingStrategy->referenceColumnName();
145 11
            $joinColumnAnnotation->name                 = $namingStrategy->joinKeyColumnName(
146 11
                $this->targetEntity,
147 11
                $selfReferenceEntity ? 'target' : $joinColumnAnnotation->referencedColumnName
148
            );
149
150 11
            $this->joinColumnMetadataBuilder->withJoinColumnAnnotation($joinColumnAnnotation);
151
152 11
            $joinTableMetadata->addInverseJoinColumn($this->joinColumnMetadataBuilder->build());
153
        }
154
155 89
        return $joinTableMetadata;
156
    }
157
}