GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( ac587f...53bcfa )
by SignpostMarv
07:07
created

AbstractDaftObject::__unset()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 0
cts 3
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
* Base daft objects.
4
*
5
* @author SignpostMarv
6
*/
7
declare(strict_types=1);
8
9
namespace SignpostMarv\DaftObject;
10
11
use ReflectionClass;
12
use ReflectionMethod;
13
14
/**
15
* Base daft object.
16
*/
17
abstract class AbstractDaftObject implements DaftObject
18
{
19
    /**
20
    * List of properties that can be defined on an implementation.
21
    *
22
    * @var array<int, string>
23
    */
24
    const PROPERTIES = [];
25
26
    /**
27
    * List of nullable properties that can be defined on an implementation.
28
    *
29
    * @var array<int, string>
30
    */
31
    const NULLABLE_PROPERTIES = [];
32
33
    /**
34
    * List of exportable properties that can be defined on an implementation.
35
    *
36
    * @var array<int, string>
37
    */
38
    const EXPORTABLE_PROPERTIES = [];
39
40
    /**
41
    * import/export definition for DaftJson.
42
    *
43
    * @var array<int, string>
44
    */
45
    const JSON_PROPERTIES = [];
46
47
    /**
48
    * @var array<string, array<int, string>>
49
    */
50
    private static $publicGetters = [];
51
52
    /**
53
    * @var array<string, array<int, string>>
54
    */
55
    private static $publicSetters = [];
56
57
    /**
58
    * Does some sanity checking.
59
    *
60
    * @see DefinesOwnIdPropertiesInterface
61
    * @see self::CheckTypeDefinesOwnIdProperties()
62
    */
63
    public function __construct()
64
    {
65
        self::CheckTypeDefinesOwnIdProperties(
66
            static::class,
67
            ($this instanceof DefinesOwnIdPropertiesInterface)
68
        );
69
    }
70
71
    public function __get(string $property)
72
    {
73
        return $this->DoGetSet($property, false);
74
    }
75
76
    public function __set(string $property, $v)
77
    {
78
        return $this->DoGetSet($property, true, $v);
79
    }
80
81
    /**
82
    * @see static::NudgePropertyValue()
83
    */
84
    public function __unset(string $property) : void
85
    {
86
        $this->NudgePropertyValue($property, null);
87
    }
88
89
    /**
90
    * @return array<string, mixed>
91
    */
92
    public function __debugInfo() : array
93
    {
94
        $out = [];
95
        $publicGetters = static::DaftObjectPublicGetters();
96
        foreach (static::DaftObjectExportableProperties() as $prop) {
97
            $expectedMethod = 'Get' . ucfirst($prop);
98
            if ($this->__isset($prop) && in_array($prop, $publicGetters, true)) {
99
                $out[(string) $prop] = $this->$expectedMethod();
100
            }
101
        }
102
103
        return $out;
104
    }
105
106
    /**
107
    * List of properties that can be defined on an implementation.
108
    *
109
    * @return array<int, string>
110
    */
111
    final public static function DaftObjectProperties() : array
112
    {
113
        return static::PROPERTIES;
114
    }
115
116
    final public static function DaftObjectNullableProperties() : array
117
    {
118
        return static::NULLABLE_PROPERTIES;
119
    }
120
121
    final public static function DaftObjectExportableProperties() : array
122
    {
123
        return static::EXPORTABLE_PROPERTIES;
124
    }
125
126
    final public static function DaftObjectPublicGetters() : array
127
    {
128
        static::CachePublicGettersAndSetters();
129
130
        return self::$publicGetters[static::class];
131
    }
132
133
    final public static function DaftObjectPublicSetters() : array
134
    {
135
        static::CachePublicGettersAndSetters();
136
137
        return self::$publicSetters[static::class];
138
    }
139
140
    final public static function DaftObjectJsonProperties() : array
141
    {
142
        static::ThrowIfNotDaftJson();
143
144
        return static::JSON_PROPERTIES;
145
    }
146
147
    final public static function DaftObjectJsonPropertyNames() : array
148
    {
149
        $out = [];
150
151
        foreach (static::DaftObjectJsonProperties() as $k => $prop) {
152
            if (is_string($k)) {
153
                $prop = $k;
154
            }
155
156
            $out[] = $prop;
157
        }
158
159
        return $out;
160
    }
161
162
    protected static function ThrowIfNotDaftJson() : void
163
    {
164
        if (false === is_a(static::class, DaftJson::class, true)) {
165
            throw new DaftObjectNotDaftJsonBadMethodCallException(static::class);
166
        }
167
    }
168
169
    final protected static function HasPublicMethod(
170
        ReflectionClass $classReflection,
171
        string $method
172
    ) : bool {
173
        if (
174
            $classReflection->hasMethod($method)
175
        ) {
176
            $methodReflection = new ReflectionMethod(static::class, $method);
177
178
            return
179
                $methodReflection->isPublic() &&
180
                false === $methodReflection->isStatic();
181
        }
182
183
        return false;
184
    }
185
186
    final protected static function CachePublicGettersAndSetters() : void
187
    {
188
        if (false === isset(self::$publicGetters[static::class])) {
189
            self::$publicGetters[static::class] = [];
190
            self::$publicSetters[static::class] = [];
191
192
            if (is_a(static::class, DefinesOwnIdPropertiesInterface::class, true)) {
193
                self::$publicGetters[static::class][] = 'id';
194
            }
195
196
            $classReflection = new ReflectionClass(static::class);
197
198
            foreach (static::DaftObjectProperties() as $property) {
199
                if (static::HasPublicMethod(
200
                        $classReflection,
201
                        static::DaftObjectMethodNameFromProperty($property)
202
                )) {
203
                    self::$publicGetters[static::class][] = $property;
204
                }
205
206
                if (static::HasPublicMethod(
207
                        $classReflection,
208
                        static::DaftObjectMethodNameFromProperty($property, true)
209
                )) {
210
                    self::$publicSetters[static::class][] = $property;
211
                }
212
            }
213
        }
214
    }
215
216
    /**
217
    * Nudge the state of a given property, marking it as dirty.
218
    *
219
    * @param string $property property being nudged
220
    * @param mixed $value value to nudge property with
221
    *
222
    * @throws UndefinedPropertyException if $property is not in static::DaftObjectProperties()
223
    * @throws PropertyNotNullableException if $property is not in static::DaftObjectNullableProperties()
224
    * @throws PropertyNotRewriteableException if class is write-once read-many and $property was already changed
225
    */
226
    abstract protected function NudgePropertyValue(string $property, $value) : void;
227
228
    /**
229
    * Checks if a type correctly defines it's own id.
230
    *
231
    * @throws ClassDoesNotImplementClassException if $class is not an implementation of DefinesOwnIdPropertiesInterface
232
    * @throws ClassMethodReturnHasZeroArrayCountException if $class::DaftObjectIdProperties() does not contain at least one property
233
    * @throws ClassMethodReturnIsNotArrayOfStringsException if $class::DaftObjectIdProperties() is not string[]
234
    * @throws UndefinedPropertyException if an id property is not in $class::DaftObjectIdProperties()
235
    */
236
    final protected static function CheckTypeDefinesOwnIdProperties(
237
        string $class,
238
        bool $throwIfNotImplementation = false
239
    ) : void {
240
        $interfaceCheck = $class;
241
242
        if (is_a($interfaceCheck, DefinesOwnIdPropertiesInterface::class, true)) {
243
            $properties = $class::DaftObjectIdProperties();
244
245
            if (count($properties) < 1) {
246
                throw new ClassMethodReturnHasZeroArrayCountException(
247
                    $class,
248
                    'DaftObjectIdProperties'
249
                );
250
            }
251
252
            foreach ($properties as $property) {
253
                if (false === is_string($property)) {
254
                    throw new ClassMethodReturnIsNotArrayOfStringsException(
255
                        $class,
256
                        'DaftObjectIdProperties'
257
                    );
258
                }
259
            }
260
        } elseif ($throwIfNotImplementation) {
261
            throw new ClassDoesNotImplementClassException(
262
                $class,
263
                DefinesOwnIdPropertiesInterface::class
264
            );
265
        }
266
    }
267
268
    protected static function DaftObjectMethodNameFromProperty(
269
        string $property,
270
        bool $SetNotGet = false
271
    ) : string {
272
        return ($SetNotGet ? 'Set' : 'Get') . ucfirst($property);
273
    }
274
275
    /**
276
    * @param mixed $v
277
    *
278
    * @return mixed
279
    */
280
    protected function DoGetSet(string $property, bool $SetNotGet, $v = null)
281
    {
282
        $expectedMethod = static::DaftObjectMethodNameFromProperty($property, $SetNotGet);
283
        $thingers = static::DaftObjectPublicGetters();
284
285
        if ($SetNotGet) {
286
            $thingers = static::DaftObjectPublicSetters();
287
        }
288
289
        if (false === in_array($property, $thingers, true)) {
290
            if (false === in_array($property, static::DaftObjectProperties(), true)) {
291
                throw new UndefinedPropertyException(static::class, $property);
292
            } elseif ($SetNotGet) {
293
                throw new NotPublicSetterPropertyException(static::class, $property);
294
            }
295
296
            throw new NotPublicGetterPropertyException(static::class, $property);
297
        }
298
299
        return $this->$expectedMethod($v);
300
    }
301
}
302