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 ( 53bcfa...6873de )
by SignpostMarv
03:59
created

AbstractDaftObject::__unset()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
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 376
    public function __construct()
64
    {
65 376
        self::CheckTypeDefinesOwnIdProperties(
66 376
            static::class,
67 376
            ($this instanceof DefinesOwnIdPropertiesInterface)
68
        );
69 372
    }
70
71 82
    public function __get(string $property)
72
    {
73 82
        return $this->DoGetSet($property, false);
74
    }
75
76 158
    public function __set(string $property, $v)
77
    {
78 158
        return $this->DoGetSet($property, true, $v);
79
    }
80
81
    /**
82
    * @see static::NudgePropertyValue()
83
    */
84 40
    public function __unset(string $property) : void
85
    {
86 40
        $this->NudgePropertyValue($property, null);
87 36
    }
88
89
    /**
90
    * @return array<string, mixed>
91
    */
92 62
    public function __debugInfo() : array
93
    {
94 62
        $out = [];
95 62
        $publicGetters = static::DaftObjectPublicGetters();
96 62
        foreach (static::DaftObjectExportableProperties() as $prop) {
97 60
            $expectedMethod = 'Get' . ucfirst($prop);
98 60
            if ($this->__isset($prop) && in_array($prop, $publicGetters, true)) {
99 60
                $out[(string) $prop] = $this->$expectedMethod();
100
            }
101
        }
102
103 62
        return $out;
104
    }
105
106
    /**
107
    * List of properties that can be defined on an implementation.
108
    *
109
    * @return array<int, string>
110
    */
111 256
    final public static function DaftObjectProperties() : array
112
    {
113 256
        return static::PROPERTIES;
114
    }
115
116 90
    final public static function DaftObjectNullableProperties() : array
117
    {
118 90
        return static::NULLABLE_PROPERTIES;
119
    }
120
121 120
    final public static function DaftObjectExportableProperties() : array
122
    {
123 120
        return static::EXPORTABLE_PROPERTIES;
124
    }
125
126 216
    final public static function DaftObjectPublicGetters() : array
127
    {
128 216
        static::CachePublicGettersAndSetters();
129
130 216
        return self::$publicGetters[static::class];
131
    }
132
133 158
    final public static function DaftObjectPublicSetters() : array
134
    {
135 158
        static::CachePublicGettersAndSetters();
136
137 158
        return self::$publicSetters[static::class];
138
    }
139
140 68
    final public static function DaftObjectJsonProperties() : array
141
    {
142 68
        static::ThrowIfNotDaftJson();
143
144 36
        return static::JSON_PROPERTIES;
145
    }
146
147 36
    final public static function DaftObjectJsonPropertyNames() : array
148
    {
149 36
        $out = [];
150
151 36
        foreach (static::DaftObjectJsonProperties() as $k => $prop) {
152 36
            if (is_string($k)) {
153 24
                $prop = $k;
154
            }
155
156 36
            $out[] = $prop;
157
        }
158
159 36
        return $out;
160
    }
161
162 164
    protected static function ThrowIfNotDaftJson() : void
163
    {
164 164
        if (false === is_a(static::class, DaftJson::class, true)) {
165 128
            throw new DaftObjectNotDaftJsonBadMethodCallException(static::class);
166
        }
167 36
    }
168
169 26
    final protected static function HasPublicMethod(
170
        ReflectionClass $classReflection,
171
        string $method
172
    ) : bool {
173
        if (
174 26
            $classReflection->hasMethod($method)
175
        ) {
176 26
            $methodReflection = new ReflectionMethod(static::class, $method);
177
178
            return
179 26
                $methodReflection->isPublic() &&
180 26
                false === $methodReflection->isStatic();
181
        }
182
183 8
        return false;
184
    }
185
186 216
    final protected static function CachePublicGettersAndSetters() : void
187
    {
188 216
        if (false === isset(self::$publicGetters[static::class])) {
189 26
            self::$publicGetters[static::class] = [];
190 26
            self::$publicSetters[static::class] = [];
191
192 26
            if (is_a(static::class, DefinesOwnIdPropertiesInterface::class, true)) {
193 14
                self::$publicGetters[static::class][] = 'id';
194
            }
195
196 26
            $classReflection = new ReflectionClass(static::class);
197
198 26
            foreach (static::DaftObjectProperties() as $property) {
199 26
                if (static::HasPublicMethod(
200 26
                        $classReflection,
201 26
                        static::DaftObjectMethodNameFromProperty($property)
202
                )) {
203 22
                    self::$publicGetters[static::class][] = $property;
204
                }
205
206 26
                if (static::HasPublicMethod(
207 26
                        $classReflection,
208 26
                        static::DaftObjectMethodNameFromProperty($property, true)
209
                )) {
210 26
                    self::$publicSetters[static::class][] = $property;
211
                }
212
            }
213
        }
214 216
    }
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 376
    final protected static function CheckTypeDefinesOwnIdProperties(
237
        string $class,
238
        bool $throwIfNotImplementation = false
239
    ) : void {
240 376
        $interfaceCheck = $class;
241
242 376
        if (is_a($interfaceCheck, DefinesOwnIdPropertiesInterface::class, true)) {
243 232
            $properties = $class::DaftObjectIdProperties();
244
245 232
            if (count($properties) < 1) {
246 2
                throw new ClassMethodReturnHasZeroArrayCountException(
247 2
                    $class,
248 2
                    'DaftObjectIdProperties'
249
                );
250
            }
251
252 230
            foreach ($properties as $property) {
253 230
                if (false === is_string($property)) {
254 2
                    throw new ClassMethodReturnIsNotArrayOfStringsException(
255 2
                        $class,
256 230
                        'DaftObjectIdProperties'
257
                    );
258
                }
259
            }
260 150
        } elseif ($throwIfNotImplementation) {
261 2
            throw new ClassDoesNotImplementClassException(
262 2
                $class,
263 2
                DefinesOwnIdPropertiesInterface::class
264
            );
265
        }
266 372
    }
267
268 216
    protected static function DaftObjectMethodNameFromProperty(
269
        string $property,
270
        bool $SetNotGet = false
271
    ) : string {
272 216
        return ($SetNotGet ? 'Set' : 'Get') . ucfirst($property);
273
    }
274
275
    /**
276
    * @param mixed $v
277
    *
278
    * @return mixed
279
    */
280 216
    protected function DoGetSet(string $property, bool $SetNotGet, $v = null)
281
    {
282 216
        $expectedMethod = static::DaftObjectMethodNameFromProperty($property, $SetNotGet);
283 216
        $thingers = static::DaftObjectPublicGetters();
284
285 216
        if ($SetNotGet) {
286 158
            $thingers = static::DaftObjectPublicSetters();
287
        }
288
289 216
        if (false === in_array($property, $thingers, true)) {
290 10
            if (false === in_array($property, static::DaftObjectProperties(), true)) {
291 6
                throw new UndefinedPropertyException(static::class, $property);
292 4
            } elseif ($SetNotGet) {
293 2
                throw new NotPublicSetterPropertyException(static::class, $property);
294
            }
295
296 2
            throw new NotPublicGetterPropertyException(static::class, $property);
297
        }
298
299 206
        return $this->$expectedMethod($v);
300
    }
301
}
302