schemator-php

Форк
0
/
ObjectAccessHelper.php 
289 строк · 7.8 Кб
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Smoren\Schemator\Helpers;
6

7
use ReflectionMethod;
8
use ReflectionProperty;
9
use Smoren\Schemator\Interfaces\ProxyInterface;
10
use Smoren\Schemator\Structs\ObjectPropertyProxy;
11
use stdClass;
12

13
/**
14
 * Tool for reflecting and accessing object properties and methods.
15
 */
16
class ObjectAccessHelper
17
{
18
    /**
19
     * Returns value of the object property.
20
     *
21
     * Can access property by its name or by getter.
22
     *
23
     * @param object $object
24
     * @param string $propertyName
25
     *
26
     * @return mixed
27
     *
28
     * @throws \InvalidArgumentException
29
     */
30
    public static function getPropertyValue(object $object, string $propertyName)
31
    {
32
        if (static::hasPropertyAccessibleByGetter($object, $propertyName)) {
33
            return static::getPropertyValueByGetter($object, $propertyName);
34
        }
35

36
        if (static::hasPublicProperty($object, $propertyName)) {
37
            return $object->{$propertyName};
38
        }
39

40
        $className = get_class($object);
41
        throw new \InvalidArgumentException("Property '{$className}::{$propertyName}' is not readable");
42
    }
43

44
    /**
45
     * Returns reference to the object property.
46
     *
47
     * @param object $object
48
     * @param string $propertyName
49
     * @param mixed $defaultValue
50
     *
51
     * @return mixed|ProxyInterface<object>
52
     *
53
     * @throws \InvalidArgumentException
54
     */
55
    public static function &getPropertyRef(object &$object, string $propertyName, $defaultValue = null)
56
    {
57
        if (static::hasPublicProperty($object, $propertyName)) {
58
            return $object->{$propertyName};
59
        }
60

61
        if ($object instanceof stdClass) {
62
            $object->{$propertyName} = $defaultValue;
63
            return $object->{$propertyName};
64
        }
65

66
        $proxy = new ObjectPropertyProxy($object, $propertyName);
67
        return $proxy;
68
    }
69

70
    /**
71
     * Returns value of the object property.
72
     *
73
     * Can access property by its name or by getter.
74
     *
75
     * @param object $object
76
     * @param string $propertyName
77
     * @param mixed $value
78
     *
79
     * @return void
80
     *
81
     * @throws \InvalidArgumentException
82
     */
83
    public static function setPropertyValue(object $object, string $propertyName, $value): void
84
    {
85
        if (static::hasPropertyAccessibleBySetter($object, $propertyName)) {
86
            static::setPropertyValueBySetter($object, $propertyName, $value);
87
            return;
88
        }
89

90
        if (static::hasPublicProperty($object, $propertyName) || $object instanceof stdClass) {
91
            $object->{$propertyName} = $value;
92
            return;
93
        }
94

95
        $className = get_class($object);
96
        throw new \InvalidArgumentException("Property '{$className}::{$propertyName}' is not writable");
97
    }
98

99
    /**
100
     * Returns true if object has property that is accessible to read by name or by getter.
101
     *
102
     * @param object $object
103
     * @param string $propertyName
104
     *
105
     * @return bool
106
     */
107
    public static function hasReadableProperty(object $object, string $propertyName): bool
108
    {
109
        return static::hasPublicProperty($object, $propertyName)
110
            || static::hasPropertyAccessibleByGetter($object, $propertyName);
111
    }
112

113
    /**
114
     * Returns true if object has property that is accessible to write by name or by setter.
115
     *
116
     * @param object $object
117
     * @param string $propertyName
118
     *
119
     * @return bool
120
     */
121
    public static function hasWritableProperty(object $object, string $propertyName): bool
122
    {
123
        return static::hasPublicProperty($object, $propertyName)
124
            || static::hasPropertyAccessibleBySetter($object, $propertyName);
125
    }
126

127
    /**
128
     * Returns true if object has public property.
129
     *
130
     * @param object $object
131
     * @param string $propertyName
132
     *
133
     * @return bool
134
     */
135
    public static function hasPublicProperty(object $object, string $propertyName): bool
136
    {
137
        if ($object instanceof stdClass) {
138
            return static::hasProperty($object, $propertyName);
139
        }
140

141
        return
142
            static::hasProperty($object, $propertyName) &&
143
            static::getReflectionProperty($object, $propertyName)->isPublic();
144
    }
145

146
    /**
147
     * Returns true if object has property.
148
     *
149
     * @param object $object
150
     * @param string $propertyName
151
     *
152
     * @return bool
153
     */
154
    public static function hasProperty(object $object, string $propertyName): bool
155
    {
156
        return property_exists($object, $propertyName);
157
    }
158

159
    /**
160
     * Returns true if object has public method.
161
     *
162
     * @param object $object
163
     * @param string $methodName
164
     *
165
     * @return bool
166
     */
167
    public static function hasPublicMethod(object $object, string $methodName): bool
168
    {
169
        return
170
            static::hasMethod($object, $methodName) &&
171
            static::getReflectionMethod($object, $methodName)->isPublic();
172
    }
173

174
    /**
175
     * Returns true if object has method.
176
     *
177
     * @param object $object
178
     * @param string $methodName
179
     *
180
     * @return bool
181
     */
182
    public static function hasMethod(object $object, string $methodName): bool
183
    {
184
        return method_exists($object, $methodName);
185
    }
186

187
    /**
188
     * Returns true if object has property that is accessible by getter.
189
     *
190
     * @param object $object
191
     * @param string $propertyName
192
     *
193
     * @return bool
194
     */
195
    protected static function hasPropertyAccessibleByGetter(object $object, string $propertyName): bool
196
    {
197
        return static::hasPublicMethod($object, static::getPropertyGetterName($propertyName));
198
    }
199

200
    /**
201
     * Returns true if object has property that is accessible by setter.
202
     *
203
     * @param object $object
204
     * @param string $propertyName
205
     *
206
     * @return bool
207
     */
208
    protected static function hasPropertyAccessibleBySetter(object $object, string $propertyName): bool
209
    {
210
        return static::hasPublicMethod($object, static::getPropertySetterName($propertyName));
211
    }
212

213
    /**
214
     * Returns property value by getter.
215
     *
216
     * @param object $object
217
     * @param string $propertyName
218
     *
219
     * @return mixed
220
     */
221
    protected static function getPropertyValueByGetter(object $object, string $propertyName)
222
    {
223
        return $object->{static::getPropertyGetterName($propertyName)}();
224
    }
225

226
    /**
227
     * Sets property value by setter.
228
     *
229
     * @param object $object
230
     * @param string $propertyName
231
     * @param mixed $value
232
     *
233
     * @return void
234
     */
235
    protected static function setPropertyValueBySetter(object $object, string $propertyName, $value): void
236
    {
237
        $object->{static::getPropertySetterName($propertyName)}($value);
238
    }
239

240
    /**
241
     * Returns reflection object of the object property.
242
     *
243
     * @param object $object
244
     * @param string $propertyName
245
     *
246
     * @return ReflectionProperty
247
     */
248
    protected static function getReflectionProperty(object $object, string $propertyName): ReflectionProperty
249
    {
250
        return new ReflectionProperty(get_class($object), $propertyName);
251
    }
252

253
    /**
254
     * Returns reflection object of the object method.
255
     *
256
     * @param object $object
257
     * @param string $methodName
258
     *
259
     * @return ReflectionMethod
260
     */
261
    protected static function getReflectionMethod(object $object, string $methodName): ReflectionMethod
262
    {
263
        return new ReflectionMethod(get_class($object), $methodName);
264
    }
265

266
    /**
267
     * Returns property getter name.
268
     *
269
     * @param string $propertyName
270
     *
271
     * @return string
272
     */
273
    protected static function getPropertyGetterName(string $propertyName): string
274
    {
275
        return 'get' . ucfirst($propertyName);
276
    }
277

278
    /**
279
     * Returns property setter name.
280
     *
281
     * @param string $propertyName
282
     *
283
     * @return string
284
     */
285
    protected static function getPropertySetterName(string $propertyName): string
286
    {
287
        return 'set' . ucfirst($propertyName);
288
    }
289
}
290

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.