AssociationPath::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Xsolve\Associate\AssociationPath;
4
5
class AssociationPath
6
{
7
    /**
8
     * @var string[]
9
     */
10
    protected $associationNames;
11
12
    /**
13
     * @param string[] $associationNames
14
     */
15
    public function __construct(array $associationNames)
16
    {
17
        $this->associationNames = $associationNames;
18
    }
19
20
    /**
21
     * @return string[]
22
     */
23
    public function getAssociationNames()
24
    {
25
        return $this->associationNames;
26
    }
27
28
    /**
29
     * @return int
30
     */
31
    public function getDepth()
32
    {
33
        return count($this->associationNames);
34
    }
35
36
    /**
37
     * @param self $anotherAssociationPath
38
     *
39
     * @return self
40
     *
41
     * @throws \Exception
42
     */
43
    public function getRelativeTo(self $anotherAssociationPath): self
44
    {
45
        if (
46
            $anotherAssociationPath->getDepth() > $this->getDepth()
47
            || !$this->isPartiallyEqual($anotherAssociationPath)
48
        ) {
49
            throw new \Exception();
50
        }
51
52
        return new self(array_slice($this->associationNames, $anotherAssociationPath->getDepth()));
53
    }
54
55
    /**
56
     * @return bool
57
     */
58
    public function isRoot(): bool
59
    {
60
        return empty($this->associationNames);
61
    }
62
63
    /**
64
     * @param AssociationPath $anotherAssociationPath
65
     *
66
     * @return bool
67
     */
68
    public function isPartiallyEqual(self $anotherAssociationPath): bool
69
    {
70
        $minDepth = min($this->getDepth(), $anotherAssociationPath->getDepth());
71
72
        return
73
            array_slice($this->associationNames, 0, $minDepth)
74
            === array_slice($anotherAssociationPath->associationNames, 0, $minDepth);
75
    }
76
77
    /**
78
     * @param AssociationPath $anotherAssociationPath
79
     *
80
     * @return bool
81
     */
82
    public function isEqual(self $anotherAssociationPath): bool
83
    {
84
        return $this->associationNames === $anotherAssociationPath->associationNames;
85
    }
86
87
    /**
88
     * @param self $associationPath1
89
     * @param self $associationPath2
90
     *
91
     * @return int
92
     *
93
     * @throws \Exception
94
     */
95
    public static function compare(self $associationPath1, self $associationPath2): int
96
    {
97
        if ($associationPath1->isEqual($associationPath2)) {
98
            return 0;
99
        }
100
101
        $comparison = $associationPath1->getDepth() <=> $associationPath2->getDepth();
102
103
        if (0 !== $comparison) {
104
            return $comparison;
105
        }
106
107
        $i = 0;
108
        $iMax = $associationPath1->getDepth();
109
        while ($i < $iMax) {
110
            $comparison = $associationPath1->associationNames[$i] <=> $associationPath2->associationNames[$i];
111
112
            if (0 !== $comparison) {
113
                return $comparison;
114
            }
115
116
            $i += 1;
117
        }
118
119
        throw new \Exception();
120
    }
121
122
    /**
123
     * @return string
124
     */
125
    public function __toString()
126
    {
127
        return implode('.', $this->associationNames);
128
    }
129
}
130