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 ( 6098c5...3efc04 )
by SignpostMarv
02:38
created

AbstractDaftObject::__debugInfo()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 24
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 5.3073

Importance

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