Completed
Push — develop ( 3f9c00...d25215 )
by Nate
02:35
created

ElementMutatorTrait::resolveElement()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 0
cts 7
cp 0
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 0
crap 6
1
<?php
2
3
/**
4
 * @copyright  Copyright (c) Flipbox Digital Limited
5
 * @license    https://github.com/flipboxfactory/craft-ember/blob/master/LICENSE
6
 * @link       https://github.com/flipboxfactory/craft-ember/
7
 */
8
9
namespace flipbox\craft\ember\objects;
10
11
use Craft;
12
use craft\base\Element;
13
use craft\base\ElementInterface;
14
15
/**
16
 * This trait accepts both an ElementInterface or and Element Id and ensures that the both
17
 * the ElementInterface and the Id are in sync. If one changes (and does not match the other) it
18
 * resolves (removes / updates) the other.
19
 *
20
 * In addition, this trait is primarily useful when a new Element is set and saved; the Element
21
 * Id can be retrieved without needing to explicitly set the newly created Id.
22
 *
23
 * @property Element|ElementInterface|null $element
24
 *
25
 * @author Flipbox Factory <[email protected]>
26
 * @since 2.0.0
27
 */
28
trait ElementMutatorTrait
29
{
30
    /**
31
     * @var Element|null
32
     */
33
    private $element;
34
35
    /**
36
     * Internally set the Element Id.  This can be overridden. A record for example
37
     * should use `setAttribute`.
38
     *
39
     * @param int|null $id
40
     * @return $this
41
     */
42
    abstract protected function internalSetElementId(int $id = null);
43
44
    /**
45
     * Internally get the Element Id.  This can be overridden.  A record for example
46
     * should use `getAttribute`.
47
     *
48
     * @return int|null
49
     */
50
    abstract protected function internalGetElementId();
51
52
    /**
53
     * @return bool
54
     */
55
    public function isElementSet(): bool
56
    {
57
        return null !== $this->element;
58
    }
59
60
    /**
61
     * Set associated elementId
62
     *
63
     * @param $id
64
     * @return $this
65
     */
66
    public function setElementId(int $id = null)
67
    {
68
        $this->internalSetElementId($id);
69
70
        if (null !== $this->element && $id !== $this->element->id) {
71
            $this->element = null;
72
        }
73
74
        return $this;
75
    }
76
77
    /**
78
     * Get associated elementId
79
     *
80
     * @return int|null
81
     */
82
    public function getElementId()
83
    {
84
        if (null === $this->internalGetElementId() && null !== $this->element) {
85
            $this->setElementId($this->element->id);
86
        }
87
88
        return $this->internalGetElementId();
89
    }
90
91
    /**
92
     * Associate a element
93
     *
94
     * @param mixed $element
95
     * @return $this
96
     */
97
    public function setElement($element = null)
98
    {
99
        $this->element = null;
100
        $this->internalSetElementId(null);
101
102
        if (null !== ($element = $this->verifyElement($element))) {
103
            $this->element = $element;
0 ignored issues
show
Documentation Bug introduced by
It seems like $element of type object<craft\base\ElementInterface> is incompatible with the declared type object<craft\base\Element>|null of property $element.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
104
            $this->internalSetElementId($element->id);
105
        }
106
107
        return $this;
108
    }
109
110
    /**
111
     * @return ElementInterface|null
112
     */
113
    public function getElement()
114
    {
115
        if ($this->element === null) {
116
            $element = $this->resolveElement();
117
            $this->setElement($element);
118
            return $element;
119
        }
120
121
        $elementId = $this->internalGetElementId();
122
        if ($elementId !== null && $elementId !== $this->element->id) {
123
            $this->element = null;
124
            return $this->getElement();
125
        }
126
127
        return $this->element;
128
    }
129
130
    /**
131
     * @return ElementInterface|null
132
     */
133
    protected function resolveElement()
134
    {
135
        if ($element = $this->resolveElementFromId()) {
136
            return $element;
137
        }
138
139
        return null;
140
    }
141
142
    /**
143
     * @return ElementInterface|null
144
     */
145
    private function resolveElementFromId()
146
    {
147
        if (null === ($elementId = $this->internalGetElementId())) {
148
            return null;
149
        }
150
151
        return Craft::$app->getElements()->getElementById($elementId);
152
    }
153
154
    /**
155
     * @param mixed $element
156
     * @return ElementInterface|Element|null
157
     */
158
    protected function verifyElement($element = null)
159
    {
160
        if (null === $element) {
161
            return null;
162
        }
163
164
        if ($element instanceof ElementInterface) {
165
            return $element;
166
        }
167
168
        if (is_numeric($element)) {
169
            return Craft::$app->getElements()->getElementById($element);
170
        }
171
172
        if (is_string($element)) {
173
            return Craft::$app->getElements()->getElementByUri($element);
174
        }
175
176
        return null;
177
    }
178
}
179