Completed
Push — master ( da6cfc...b18a46 )
by Randy
01:30
created

ObjectFacade::isSet()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 2
eloc 2
nc 2
nop 1
crap 2
1
<?php
2
3
namespace Dgame\Object;
4
5
use Dgame\Variants\Variants;
6
use ReflectionClass;
7
use ReflectionMethod;
8
use ReflectionProperty;
9
use function Dgame\Ensurance\enforce;
10
11
/**
12
 * Class ObjectFacade
13
 * @package Dgame\Object
14
 */
15
class ObjectFacade
16
{
17
    /**
18
     * @var object
19
     */
20
    private $object;
21
    /**
22
     * @var ReflectionClass
23
     */
24
    private $reflection;
25
26
    /**
27
     * ObjectFacade constructor.
28
     *
29
     * @param object $object
30
     */
31 10
    public function __construct($object)
32
    {
33 10
        enforce(is_object($object))->orThrow('That is not a valid object');
34
35 10
        $this->object = $object;
36 10
    }
37
38
    /**
39
     * @return object
40
     */
41 3
    final public function getObject()
42
    {
43 3
        return $this->object;
44
    }
45
46
    /**
47
     * @return ReflectionClass
48
     */
49 10
    final public function getReflection(): ReflectionClass
50
    {
51 10
        if ($this->reflection === null) {
52 10
            $this->reflection = new ReflectionClass($this->object);
53
        }
54
55 10
        return $this->reflection;
56
    }
57
58
    /**
59
     * @param string $name
60
     * @param        $value
61
     *
62
     * @return bool
63
     */
64 2
    final public function setValue(string $name, $value): bool
65
    {
66 2
        foreach (Variants::ofArguments($name)->withCamelSnakeCase() as $attribute) {
67 2
            if ($this->setValueByProperty($attribute, $value) || $this->setValueByMethod($attribute, $value)) {
68 2
                return true;
69
            }
70
        }
71
72
        return $this->tryMagicSet($name, $value);
73
    }
74
75
    /**
76
     * @param string $name
77
     * @param        $value
78
     *
79
     * @return bool
80
     */
81
    private function tryMagicSet(string $name, $value): bool
82
    {
83
        if ($this->hasMethod('__set')) {
84
            $this->invokeMethod('__set', $name, $value);
85
86
            return true;
87
        }
88
89
        return false;
90
    }
91
92
    /**
93
     * @param string $name
94
     *
95
     * @return mixed|null
96
     */
97 2
    final public function getValue(string $name)
98
    {
99 2
        foreach (Variants::ofArguments($name)->withCamelSnakeCase() as $attribute) {
100 2
            $property = $this->getPropertyByName($attribute);
101 2
            if ($property !== null && Validator::new($this)->isValidProperty($property)) {
102 1
                return $property->getValue($this->object);
103
            }
104
105 1
            $method = $this->getGetterMethod($name);
106 1
            if ($method !== null && Validator::new($this)->isValidGetterMethod($method)) {
107 1
                return $method->invoke($this->object);
108
            }
109
        }
110
111
        return $this->invokeMethod('__get', $name);
112
    }
113
114
    /**
115
     * @param string $name
116
     * @param        $value
117
     *
118
     * @return bool
119
     */
120 2
    final public function setValueByProperty(string $name, $value): bool
121
    {
122 2
        $property = $this->getPropertyByName($name);
123 2
        if ($property !== null && Validator::new($this)->isValidProperty($property)) {
124 1
            $property->setValue($this->object, $value);
125
126 1
            return true;
127
        }
128
129 1
        return false;
130
    }
131
132
    /**
133
     * @param string $name
134
     * @param        $value
135
     *
136
     * @return bool
137
     */
138 1
    final public function setValueByMethod(string $name, $value): bool
139
    {
140 1
        $method = $this->getSetterMethod($name);
141 1
        if ($method !== null && Validator::new($this)->isValidSetterMethod($method, $value)) {
142 1
            $method->invoke($this->object, $value);
143
144 1
            return true;
145
        }
146
147 1
        return false;
148
    }
149
150
    /**
151
     * @param string $name
152
     *
153
     * @return mixed|null
154
     */
155 2
    final public function getValueByMethod(string $name)
156
    {
157 2
        $method = $this->getGetterMethod($name);
158 2
        if ($method !== null && Validator::new($this)->isValidGetterMethod($method)) {
159 2
            return $method->invoke($this->object);
160
        }
161
162 1
        return null;
163
    }
164
165
    /**
166
     * @param string $name
167
     *
168
     * @return mixed|null
169
     */
170 2
    final public function getValueByProperty(string $name)
171
    {
172 2
        $property = $this->getPropertyByName($name);
173 2
        if ($property !== null && Validator::new($this)->isValidProperty($property)) {
174 2
            return $property->getValue($this->object);
175
        }
176
177 1
        return null;
178
    }
179
180
    /**
181
     * @param string $postfix
182
     *
183
     * @return null|ReflectionMethod
184
     */
185 2
    final public function getSetterMethod(string $postfix)
186
    {
187 2
        return $this->getMethod($postfix, ['set', 'append']);
188
    }
189
190
    /**
191
     * @param string $postfix
192
     *
193
     * @return null|ReflectionMethod
194
     */
195 3
    final public function getGetterMethod(string $postfix)
196
    {
197 3
        return $this->getMethod($postfix, ['get']);
198
    }
199
200
    /**
201
     * @param string $postfix
202
     * @param array  $prefixe
203
     *
204
     * @return null|ReflectionMethod
205
     */
206 4
    final public function getMethod(string $postfix, array $prefixe)
207
    {
208 4
        foreach ($prefixe as $prefix) {
209 4
            $method = $this->getMethodByName($prefix . ucfirst($postfix));
210 4
            if ($method !== null) {
211 4
                return $method;
212
            }
213
        }
214
215 1
        return null;
216
    }
217
218
    /**
219
     * @param string $name
220
     * @param array  ...$args
221
     *
222
     * @return mixed|null
223
     */
0 ignored issues
show
Documentation introduced by
Consider making the type for parameter $args a bit more specific; maybe use array[].
Loading history...
224
    final public function invokeMethod(string $name, ...$args)
225
    {
226
        $method = $this->getMethodByName($name);
227
        if ($method !== null && Validator::new($this)->areValidMethodArguments($method, ...$args)) {
228
            return $method->invokeArgs($this->object, $args);
229
        }
230
231
        return null;
232
    }
233
234
    /**
235
     * @param string $name
236
     *
237
     * @return null|ReflectionMethod
238
     */
239 5
    final public function getMethodByName(string $name)
240
    {
241 5
        return $this->hasMethod($name) ? $this->getReflection()->getMethod($name) : null;
242
    }
243
244
    /**
245
     * @param string $name
246
     *
247
     * @return null|ReflectionProperty
248
     */
249 4
    final public function getPropertyByName(string $name)
250
    {
251 4
        return $this->hasProperty($name) ? $this->getReflection()->getProperty($name) : null;
252
    }
253
254
    /**
255
     * @param string $name
256
     *
257
     * @return bool
258
     */
259 5
    final public function hasProperty(string $name): bool
260
    {
261 5
        return $this->getReflection()->hasProperty($name);
262
    }
263
264
    /**
265
     * @param string $name
266
     *
267
     * @return bool
268
     */
269 6
    final public function isSet(string $name): bool
270
    {
271 6
        return $this->hasProperty($name) || $this->invokeMethod('__isset', $name) === true;
272
    }
273
274
    /**
275
     * @param string $name
276
     *
277
     * @return bool
278
     */
279
    final public function hasMethod(string $name): bool
280
    {
281
        return $this->getReflection()->hasMethod($name);
282
    }
283
}
284