Passed
Push — master ( da1161...08d06f )
by Smoren
02:13
created

ObjectAccess::setPropertyValue()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 4
nc 2
nop 3
dl 0
loc 8
ccs 5
cts 5
cp 1
crap 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Smoren\TypeTools;
6
7
use ReflectionMethod;
8
use ReflectionProperty;
9
use stdClass;
10
11
/**
12
 * Tool for reflecting and accessing object properties and methods.
13
 */
14
class ObjectAccess
15
{
16
    /**
17
     * Returns value of the object property.
18
     *
19
     * Can access property by its name or by getter.
20
     *
21
     * @param object $object
22
     * @param string $propertyName
23
     *
24
     * @return mixed
25
     */
26 30
    public static function getPropertyValue(object $object, string $propertyName)
27
    {
28 30
        if(static::hasPublicProperty($object, $propertyName)) {
29 24
            return $object->{$propertyName};
30
        }
31
32 6
        return static::getPropertyValueByGetter($object, $propertyName);
33
    }
34
35
    /**
36
     * Returns value of the object property.
37
     *
38
     * Can access property by its name or by getter.
39
     *
40
     * @param object $object
41
     * @param string $propertyName
42
     * @param mixed $value
43
     *
44
     * @return void
45
     */
46 20
    public static function setPropertyValue(object $object, string $propertyName, $value): void
47
    {
48 20
        if(static::hasPublicProperty($object, $propertyName) || $object instanceof stdClass) {
49 18
            $object->{$propertyName} = $value;
50 18
            return;
51
        }
52
53 2
        static::setPropertyValueBySetter($object, $propertyName, $value);
54
    }
55
56
    /**
57
     * Returns true if object has property that is accessible to read by name or by getter.
58
     *
59
     * @param object $object
60
     * @param string $propertyName
61
     *
62
     * @return bool
63
     */
64 73
    public static function hasReadableProperty(object $object, string $propertyName): bool
65
    {
66 73
        return static::hasPublicProperty($object, $propertyName)
67 73
            || static::hasPropertyAccessibleByGetter($object, $propertyName);
68
    }
69
70
    /**
71
     * Returns true if object has property that is accessible to write by name or by setter.
72
     *
73
     * @param object $object
74
     * @param string $propertyName
75
     *
76
     * @return bool
77
     */
78 23
    public static function hasWritableProperty(object $object, string $propertyName): bool
79
    {
80 23
        return static::hasPublicProperty($object, $propertyName)
81 23
            || static::hasPropertyAccessibleBySetter($object, $propertyName);
82
    }
83
84
    /**
85
     * Returns true if object has public property.
86
     *
87
     * @param object $object
88
     * @param string $propertyName
89
     *
90
     * @return bool
91
     */
92 76
    public static function hasPublicProperty(object $object, string $propertyName): bool
93
    {
94 76
        if ($object instanceof stdClass) {
95 42
            return static::hasProperty($object, $propertyName);
96
        }
97
98 34
        return
99 34
            static::hasProperty($object, $propertyName) &&
100 34
            static::getReflectionProperty($object, $propertyName)->isPublic();
101
    }
102
103
    /**
104
     * Returns true if object has property.
105
     *
106
     * @param object $object
107
     * @param string $propertyName
108
     *
109
     * @return bool
110
     */
111 76
    public static function hasProperty(object $object, string $propertyName): bool
112
    {
113 76
        return property_exists($object, $propertyName);
114
    }
115
116
    /**
117
     * Returns true if object has public method.
118
     *
119
     * @param object $object
120
     * @param string $methodName
121
     *
122
     * @return bool
123
     */
124 62
    public static function hasPublicMethod(object $object, string $methodName): bool
125
    {
126 62
        return
127 62
            static::hasMethod($object, $methodName) &&
128 62
            static::getReflectionMethod($object, $methodName)->isPublic();
129
    }
130
131
    /**
132
     * Returns true if object has method.
133
     *
134
     * @param object $object
135
     * @param string $methodName
136
     *
137
     * @return bool
138
     */
139 62
    public static function hasMethod(object $object, string $methodName): bool
140
    {
141 62
        return method_exists($object, $methodName);
142
    }
143
144
    /**
145
     * Returns true if object has property that is accessible by getter.
146
     *
147
     * @param object $object
148
     * @param string $propertyName
149
     *
150
     * @return bool
151
     */
152 45
    protected static function hasPropertyAccessibleByGetter(object $object, string $propertyName): bool
153
    {
154 45
        return static::hasPublicMethod($object, static::getPropertyGetterName($propertyName));
155
    }
156
157
    /**
158
     * Returns true if object has property that is accessible by setter.
159
     *
160
     * @param object $object
161
     * @param string $propertyName
162
     *
163
     * @return bool
164
     */
165 19
    protected static function hasPropertyAccessibleBySetter(object $object, string $propertyName): bool
166
    {
167 19
        return static::hasPublicMethod($object, static::getPropertySetterName($propertyName));
168
    }
169
170
    /**
171
     * Returns property value by getter.
172
     *
173
     * @param object $object
174
     * @param string $propertyName
175
     *
176
     * @return mixed
177
     */
178 6
    protected static function getPropertyValueByGetter(object $object, string $propertyName)
179
    {
180 6
        return $object->{static::getPropertyGetterName($propertyName)}();
181
    }
182
183
    /**
184
     * Sets property value by setter.
185
     *
186
     * @param object $object
187
     * @param string $propertyName
188
     * @param mixed $value
189
     *
190
     * @return void
191
     */
192 2
    protected static function setPropertyValueBySetter(object $object, string $propertyName, $value): void
193
    {
194 2
        $object->{static::getPropertySetterName($propertyName)}($value);
195
    }
196
197
    /**
198
     * Returns reflection object of the object property.
199
     *
200
     * @param object $object
201
     * @param string $propertyName
202
     *
203
     * @return ReflectionProperty
204
     */
205 24
    protected static function getReflectionProperty(object $object, string $propertyName): ReflectionProperty
206
    {
207 24
        return new ReflectionProperty(get_class($object), $propertyName);
208
    }
209
210
    /**
211
     * Returns reflection object of the object method.
212
     *
213
     * @param object $object
214
     * @param string $methodName
215
     *
216
     * @return ReflectionMethod
217
     */
218 8
    protected static function getReflectionMethod(object $object, string $methodName): ReflectionMethod
219
    {
220 8
        return new ReflectionMethod(get_class($object), $methodName);
221
    }
222
223
    /**
224
     * Returns property getter name.
225
     *
226
     * @param string $propertyName
227
     *
228
     * @return string
229
     */
230 45
    protected static function getPropertyGetterName(string $propertyName): string
231
    {
232 45
        return 'get'.ucfirst($propertyName);
233
    }
234
235
    /**
236
     * Returns property setter name.
237
     *
238
     * @param string $propertyName
239
     *
240
     * @return string
241
     */
242 19
    protected static function getPropertySetterName(string $propertyName): string
243
    {
244 19
        return 'set'.ucfirst($propertyName);
245
    }
246
}
247