Failed Conditions
Push — master ( 4bfa22...148895 )
by Guilherme
17:21 queued 09:56
created

buildUniqueConstraints()   B

Complexity

Conditions 7
Paths 9

Size

Total Lines 36
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 7.0572

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 20
nc 9
nop 1
dl 0
loc 36
ccs 17
cts 19
cp 0.8947
crap 7.0572
rs 8.6666
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 RuntimeException;
10
use function array_merge;
11
use function array_unique;
12
use function assert;
13
use function count;
14
use function reset;
15
use function sprintf;
16
17
class OneToOneAssociationMetadataBuilder extends ToOneAssociationMetadataBuilder
18
{
19
    /** @var Annotation\OneToOne */
20
    private $oneToOneAnnotation;
21
22 118
    public function withOneToOneAnnotation(Annotation\OneToOne $oneToOneAnnotation) : OneToOneAssociationMetadataBuilder
23
    {
24 118
        $this->oneToOneAnnotation = $oneToOneAnnotation;
25
26 118
        return $this;
27
    }
28
29
    /**
30
     * @internal Association metadata order of definition settings is important.
31
     */
32 118
    public function build() : Mapping\OneToOneAssociationMetadata
33
    {
34
        // Validate required fields
35 118
        assert($this->componentMetadata !== null);
36 118
        assert($this->oneToOneAnnotation !== null);
37 118
        assert($this->fieldName !== null);
38
39 118
        $componentClassName  = $this->componentMetadata->getClassName();
40 118
        $associationMetadata = new Mapping\OneToOneAssociationMetadata($this->fieldName);
41
42 118
        $associationMetadata->setSourceEntity($componentClassName);
43 118
        $associationMetadata->setTargetEntity($this->getTargetEntity($this->oneToOneAnnotation->targetEntity));
44 118
        $associationMetadata->setCascade($this->getCascade($this->oneToOneAnnotation->cascade));
45 118
        $associationMetadata->setFetchMode($this->getFetchMode($this->oneToOneAnnotation->fetch));
46
47 118
        if ($this->oneToOneAnnotation->orphanRemoval) {
48 7
            $associationMetadata->setOrphanRemoval($this->oneToOneAnnotation->orphanRemoval);
49
50
            // Orphan removal also implies a cascade remove
51 7
            $associationMetadata->setCascade(array_unique(array_merge($associationMetadata->getCascade(), ['remove'])));
52
        }
53
54 118
        if (! empty($this->oneToOneAnnotation->mappedBy)) {
55 43
            $associationMetadata->setMappedBy($this->oneToOneAnnotation->mappedBy);
56 43
            $associationMetadata->setOwningSide(false);
57
        }
58
59 118
        if (! empty($this->oneToOneAnnotation->inversedBy)) {
60 55
            $associationMetadata->setInversedBy($this->oneToOneAnnotation->inversedBy);
61 55
            $associationMetadata->setOwningSide(true);
62
        }
63
64 118
        $this->buildCache($associationMetadata);
65 118
        $this->buildPrimaryKey($associationMetadata);
66
67
        // Check for owning side to consider join column
68 118
        if (! $associationMetadata->isOwningSide()) {
69 43
            return $associationMetadata;
70
        }
71
72 110
        $this->buildJoinColumns($associationMetadata);
73
74
        // @todo guilhermeblanco The below block of code modifies component metadata properties, and it should be moved
75
        //                       to the component metadata builder instead of here.
76
77
        // Set unique constraint for owning side in all columns
78 110
        if ($associationMetadata->isOwningSide()) {
79 110
            $this->buildUniqueConstraints($associationMetadata);
80
        }
81
82 110
        return $associationMetadata;
83
    }
84
85 110
    private function buildUniqueConstraints(Mapping\OneToOneAssociationMetadata $associationMetadata) : void
86
    {
87 110
        $joinColumns = $associationMetadata->getJoinColumns();
88
89 110
        if (count($joinColumns) === 1) {
90 108
            $joinColumn = reset($joinColumns);
91
92 108
            if (! $associationMetadata->isPrimaryKey()) {
93 98
                $joinColumn->setUnique(true);
94
            }
95
96 108
            return;
97
        }
98
99 2
        $tableMetadata = $this->componentMetadata->table;
100
101 2
        if (! $tableMetadata) {
0 ignored issues
show
introduced by
$tableMetadata is of type Doctrine\ORM\Mapping\TableMetadata, thus it always evaluated to true.
Loading history...
102
            $exception = 'ClassMetadata::setTable() has to be called before defining a one to one relationship.';
103
104
            throw new RuntimeException($exception);
105
        }
106
107 2
        $uniqueConstraintColumns = [];
108
109 2
        foreach ($joinColumns as $joinColumnMetadata) {
110 2
            if ($this->componentMetadata->inheritanceType !== Mapping\InheritanceType::SINGLE_TABLE) {
111 2
                $uniqueConstraintColumns[] = $joinColumnMetadata->getColumnName();
112
            }
113
        }
114
115 2
        if ($uniqueConstraintColumns) {
116 2
            $tableMetadata->addUniqueConstraint([
117 2
                'name'    => sprintf('%s_uniq', $this->fieldName),
118 2
                'columns' => $uniqueConstraintColumns,
119
                'options' => [],
120
                'flags'   => [],
121
            ]);
122
        }
123 2
    }
124
}
125