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.
Passed
Push — master ( 1b9cd3...7cef4d )
by SignpostMarv
01:45
created

DaftObjectFromJsonArrayTyped()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 30
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 30
ccs 13
cts 13
cp 1
rs 8.8571
c 0
b 0
f 0
cc 2
eloc 12
nc 2
nop 4
crap 2
1
<?php
2
/**
3
* Base daft objects.
4
*
5
* @author SignpostMarv
6
*/
7
declare(strict_types=1);
8
9
namespace SignpostMarv\DaftObject;
10
11
/**
12
* Array-backed daft objects.
13
*/
14
abstract class AbstractArrayBackedDaftObject extends AbstractDaftObject implements DaftObjectCreatedByArray
15
{
16
    /**
17
    * data for this instance.
18
    *
19
    * @var array
20
    */
21
    private $data = [];
22
23
    /**
24
    * List of changed properties.
25
    *
26
    * @var bool[]
27
    */
28
    private $changedProperties = [];
29
30
    /**
31
    * List of changed properties, for write-once read-many.
32
    *
33
    * @var bool[]
34
    */
35
    private $wormProperties = [];
36
37
    /**
38
    * {@inheritdoc}
39
    */
40 188
    public function __construct(array $data = [], bool $writeAll = false)
41
    {
42 188
        parent::__construct();
43
44 186
        if (true === $writeAll) {
45 61
            foreach ($data as $k => $v) {
46 61
                $this->__set($k, $v);
47
            }
48
        } else {
49 127
            foreach ($data as $k => $v) {
50 66
                $this->data[$k] = $v;
51
            }
52
        }
53 184
    }
54
55
    /**
56
    * {@inheritdoc}
57
    */
58 31
    public function __isset(string $property) : bool
59
    {
60
        return
61 31
            in_array($property, static::PROPERTIES, true) &&
62 31
            isset($this->data, $this->data[$property]);
63
    }
64
65
    /**
66
    * {@inheritdoc}
67
    */
68 29
    public function ChangedProperties() : array
69
    {
70
        /**
71
        * @var string[] $out
72
        */
73 29
        $out = array_keys($this->changedProperties);
74
75 29
        return $out;
76
    }
77
78
    /**
79
    * {@inheritdoc}
80
    */
81 33
    public function MakePropertiesUnchanged(string ...$properties) : void
82
    {
83 33
        foreach ($properties as $property) {
84 33
            unset($this->changedProperties[$property]);
85
        }
86 33
    }
87
88
    /**
89
    * {@inheritdoc}
90
    */
91 82
    public function HasPropertyChanged(string $property) : bool
92
    {
93
        return
94 82
            isset($this->changedProperties[$property]) &&
95 82
            true === $this->changedProperties[$property];
96
    }
97
98
    /**
99
    * {@inheritdoc}
100
    */
101 22
    public function jsonSerialize() : array
102
    {
103 22
        static::ThrowIfNotDaftJson();
104
105 6
        $out = [];
106
107 6
        foreach (static::DaftObjectJsonPropertyNames() as $property) {
108 6
            $val = $this->DoGetSet(
109 6
                $property,
110 6
                false,
111 6
                NotPublicGetterPropertyException::class
112
            );
113
114 6
            if (false === is_null($val)) {
115 6
                $out[$property] = $val;
116
            }
117
        }
118
119 6
        return $out;
120
    }
121
122
    /**
123
    * {@inheritdoc}
124
    */
125 28
    final public static function DaftObjectFromJsonArray(
126
        array $array,
127
        bool $writeAll = false
128
    ) : DaftJson {
129 28
        static::ThrowIfNotDaftJson();
130 12
        $array = static::ThrowIfJsonDefNotValid($array);
131 9
        $in = [];
132
133 9
        $jsonDef = static::DaftObjectJsonProperties();
134
135 9
        foreach (array_keys($array) as $prop) {
136 8
            if (isset($jsonDef[$prop])) {
137 5
                $in[$prop] = static::DaftObjectFromJsonArrayTyped(
138 5
                    $jsonDef[$prop],
139 5
                    $prop,
140 5
                    $array,
141 5
                    $writeAll
142
                );
143
            } else {
144 6
                $in[$prop] = $array[$prop];
145
            }
146
        }
147
148
        /**
149
        * @var DaftJson $out
150
        */
151 7
        $out = new static($in, $writeAll);
152
153 7
        return $out;
154
    }
155
156 22
    public static function DaftObjectFromJsonString(string $string) : DaftJson
157
    {
158 22
        static::ThrowIfNotDaftJson();
159
160 6
        return static::DaftObjectFromJsonArray(json_decode($string, true));
161
    }
162
163 75
    public function DaftObjectWormPropertyWritten(string $property) : bool
164
    {
165 75
        $wormProperties = $this->wormProperties;
166
167
        return
168 75
            ($this instanceof DaftObjectWorm) &&
169
            (
170 50
                $this->HasPropertyChanged($property) ||
171 75
                false === empty($wormProperties[$property])
172
            );
173
    }
174
175
    /**
176
    * @return DaftJson|DaftJson[]
177
    */
178 5
    final protected static function DaftObjectFromJsonArrayTyped(
179
        string $jsonType,
180
        string $prop,
181
        array $array,
182
        bool $writeAll = false
183
    ) {
184 5
        if ('[]' === mb_substr($jsonType, -2)) {
185
            /**
186
            * @var DaftJson[] $out
187
            */
188 3
            $out = static::DaftObjectFromJsonTypeArray(
189 3
                mb_substr($jsonType, 0, -2),
190 3
                $prop,
191 3
                $array[$prop],
192 3
                $writeAll
193
            );
194
195 1
            return $out;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $out returns the type SignpostMarv\DaftObject\DaftJson[] which is incompatible with the documented return type SignpostMarv\DaftObject\...arv\DaftObject\DaftJson.
Loading history...
196
        }
197
198
        /**
199
        * @var DaftJson $out
200
        */
201 2
        $out = static::DaftObjectFromJsonType(
202 2
            $jsonType,
203 2
            $array[$prop],
204 2
            $writeAll
205
        );
206
207 2
        return $out;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $out returns the type SignpostMarv\DaftObject\DaftJson which is incompatible with the documented return type SignpostMarv\DaftObject\...arv\DaftObject\DaftJson.
Loading history...
208
    }
209
210
    /**
211
    * @param mixed $propVal
212
    *
213
    * @return DaftJson
214
    */
215 2
    protected static function DaftObjectFromJsonType(
216
        string $jsonType,
217
        array $propVal,
218
        bool $writeAll
219
    ) {
220 2
        static::ThrowIfNotJsonType($jsonType);
221
222 2
        return static::ArrayToJsonType($jsonType, $propVal, $writeAll);
223
    }
224
225
    /**
226
    * @return DaftJson[]
227
    */
228 3
    protected static function DaftObjectFromJsonTypeArray(
229
        string $jsonType,
230
        string $prop,
231
        array $propVal,
232
        bool $writeAll
233
    ) : array {
234 3
        static::ThrowIfNotJsonType($jsonType);
235
236 2
        $out = [];
237
238 2
        foreach ($propVal as $val) {
239 2
            if (false === is_array($val)) {
240 1
                throw new PropertyNotJsonDecodableShouldBeArrayException(
241 1
                    $jsonType,
242 1
                    $prop
243
                );
244
            }
245 1
            $out[] = static::ArrayToJsonType(
246 1
                $jsonType,
247 1
                $val,
248 1
                $writeAll
249
            );
250
        }
251
252 1
        return $out;
253
    }
254
255
    /**
256
    * Retrieve a property from data.
257
    *
258
    * @param string $property the property being retrieved
259
    *
260
    * @throws PropertyNotNullableException if value is not set and $property is not listed as nullabe
261
    *
262
    * @return mixed the property value
263
    */
264 45
    protected function RetrievePropertyValueFromData(string $property)
265
    {
266
        if (
267 45
            false === array_key_exists($property, $this->data) &&
268 6
            false === in_array($property, static::NULLABLE_PROPERTIES, true)
269
        ) {
270 2
            throw new PropertyNotNullableException(static::class, $property);
271
        } elseif (
272 43
            in_array($property, static::NULLABLE_PROPERTIES, true)
273
        ) {
274 33
            return $this->data[$property] ?? null;
275
        }
276
277 43
        return $this->data[$property];
278
    }
279
280
    /**
281
    * {@inheritdoc}
282
    */
283 134
    protected function NudgePropertyValue(string $property, $value) : void
284
    {
285 134
        $this->MaybeThrowOnNudge($property, $value);
286
287
        $isChanged = (
288 75
            false === array_key_exists($property, $this->data) ||
289 75
            $this->data[$property] !== $value
290
        );
291
292 75
        $this->data[$property] = $value;
293
294 75
        if ($isChanged && true !== isset($this->changedProperties[$property])) {
295 75
            $this->changedProperties[$property] = true;
296 75
            $this->wormProperties[$property] = true;
297
        }
298 75
    }
299
300
    /**
301
    * @param mixed $value
302
    *
303
    * @see AbstractArrayBackedDaftObject::NudgePropertyValue()
304
    */
305 134
    private function MaybeThrowOnNudge(string $property, $value) : void
306
    {
307 134
        if (true !== in_array($property, static::PROPERTIES, true)) {
308 1
            throw new UndefinedPropertyException(static::class, $property);
309
        } elseif (
310 133
            true === is_null($value) &&
311 88
            true !== in_array($property, static::NULLABLE_PROPERTIES, true)
312
        ) {
313 58
            throw new PropertyNotNullableException(static::class, $property);
314 75
        } elseif ($this->DaftObjectWormPropertyWritten($property)) {
315 50
            throw new PropertyNotRewriteableException(
316 50
                static::class,
317 50
                $property
318
            );
319
        }
320 75
    }
321
322 12
    private static function ThrowIfJsonDefNotValid(array $array) : array
323
    {
324 12
        $jsonProps = static::DaftObjectJsonPropertyNames();
325
326 12
        $jsonDef = static::DaftObjectJsonProperties();
327
328 12
        $out = [];
329
330 12
        foreach ($array as $prop => $propVal) {
331
            if (
332 12
                false === in_array($prop, $jsonProps, true)
333
            ) {
334 1
                throw new PropertyNotJsonDecodableException(
335 1
                    static::class,
336 1
                    $prop
337
                );
338 12
            } elseif (false === is_null($propVal)) {
339 11
                if (isset($jsonDef[$prop])) {
340 8
                    $jsonType = $jsonDef[$prop];
341
342 8
                    if (false === is_array($propVal)) {
343 2
                        static::ThrowBecauseArrayJsonTypeNotValid(
344 2
                            $jsonType,
345 2
                            $prop
346
                        );
347
                    }
348
                }
349 9
                $out[$prop] = $propVal;
350
            }
351
        }
352
353 9
        return $out;
354
    }
355
356 2
    private static function ThrowBecauseArrayJsonTypeNotValid(
357
        string $jsonType,
358
        string $prop
359
    ) : void {
360 2
        if ('[]' === mb_substr($jsonType, -2)) {
361 1
            throw new PropertyNotJsonDecodableShouldBeArrayException(
362 1
                static::class,
363 1
                $prop
364
            );
365
        }
366 1
        throw new PropertyNotJsonDecodableShouldBeArrayException(
367 1
            $jsonType,
368 1
            $prop
369
        );
370
    }
371
372 5
    private static function ThrowIfNotJsonType(string $jsonType) : void
373
    {
374 5
        if (false === is_a($jsonType, DaftJson::class, true)) {
375 1
            throw new ClassDoesNotImplementClassException(
376 1
                $jsonType,
377 1
                DaftJson::class
378
            );
379
        }
380 4
    }
381
382 3
    private static function ArrayToJsonType(
383
        string $jsonType,
384
        array $propVal,
385
        bool $writeAll
386
    ) : DaftJson {
387
        /**
388
        * @var DaftJson $jsonType
389
        */
390 3
        $jsonType = $jsonType;
391
392 3
        return $jsonType::DaftObjectFromJsonArray(
393 3
            $propVal,
394 3
            $writeAll
395
        );
396
    }
397
398 60 View Code Duplication
    private static function ThrowIfNotDaftJson() : void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
399
    {
400 60
        if (false === is_a(static::class, DaftJson::class, true)) {
401 48
            throw new DaftObjectNotDaftJsonBadMethodCallException(
402 48
                static::class
403
            );
404
        }
405 12
    }
406
}
407