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 ( 32e487...3fc4bd )
by SignpostMarv
02:14
created

DaftObjectFromJsonArray()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 40
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 22
CRAP Score 5.002

Importance

Changes 0
Metric Value
dl 0
loc 40
ccs 22
cts 23
cp 0.9565
rs 8.439
c 0
b 0
f 0
cc 5
eloc 24
nc 4
nop 2
crap 5.002
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 189
    public function __construct(array $data = [], bool $writeAll = false)
41
    {
42 189
        parent::__construct();
43
44 187
        if (true === $writeAll) {
45 60
            foreach ($data as $k => $v) {
46 60
                $this->__set($k, $v);
47
            }
48
        } else {
49 129
            foreach ($data as $k => $v) {
50 68
                $this->data[$k] = $v;
51
            }
52
        }
53 185
    }
54
55
    /**
56
    * {@inheritdoc}
57
    */
58 33
    public function __isset(string $property) : bool
59
    {
60
        return
61 33
            in_array($property, static::PROPERTIES, true) &&
62 33
            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::DaftObjectJsonProperties() as $k => $v) {
108 6
            $property = $v;
109 6
            if (is_string($k)) {
110 3
                $property = $k;
111
            }
112
113 6
            $val = $this->DoGetSet(
114 6
                $property,
115 6
                'Get' . ucfirst($property),
116 6
                PropertyNotReadableException::class,
117 6
                NotPublicGetterPropertyException::class
118
            );
119
120 6
            if (false === is_null($val)) {
121 6
                $out[$property] = $val;
122
            }
123
        }
124
125 6
        return $out;
126
    }
127
128
    /**
129
    * {@inheritdoc}
130
    */
131 22
    final public static function DaftObjectFromJsonArray(
132
        array $array,
133
        bool $writeAll = false
134
    ) : DaftJson {
135 22
        static::ThrowIfNotDaftJson();
136 6
        $array = static::ThrowIfJsonDefNotValid($array);
137 6
        $in = [];
138
139 6
        $jsonDef = static::DaftObjectJsonProperties();
140
141 6
        foreach (array_keys($array) as $prop) {
142 6
            if (isset($jsonDef[$prop])) {
143 3
                $jsonType = $jsonDef[$prop];
144
145 3
                if ('[]' === mb_substr($jsonType, -2)) {
146 1
                    $in[$prop] = static::DaftObjectFromJsonTypeArray(
147 1
                        mb_substr($jsonType, 0, -2),
148 1
                        $prop,
149 1
                        $array[$prop],
150 1
                        $writeAll
151
                    );
152
                } else {
153 2
                    $in[$prop] = static::DaftObjectFromJsonType(
154 2
                        $jsonType,
155 2
                        $array[$prop],
156 2
                        $writeAll
157
                    );
158
                }
159
            } else {
160 6
                $in[$prop] = $array[$prop];
161
            }
162
        }
163
164 6
        $out = new static($in, $writeAll);
165
166 6
        if ( ! ($out instanceof DaftJson)) { // here to trick phpstan
167
            exit;
168
        }
169
170 6
        return $out;
171
    }
172
173 22
    public static function DaftObjectFromJsonString(string $string) : DaftJson
174
    {
175 22
        static::ThrowIfNotDaftJson();
176
177 6
        return static::DaftObjectFromJsonArray(json_decode($string, true));
178
    }
179
180
    /**
181
    * @param mixed $propVal
182
    *
183
    * @return DaftJson
184
    */
185 2
    protected static function DaftObjectFromJsonType(
186
        string $jsonType,
187
        array $propVal,
188
        bool $writeAll
189
    ) {
190 2
        static::ThrowIfNotJsonType($jsonType);
191
192 2
        return static::ArrayToJsonType($jsonType, $propVal, $writeAll);
193
    }
194
195
    /**
196
    * @return DaftJson[]
197
    */
198 1
    protected static function DaftObjectFromJsonTypeArray(
199
        string $jsonType,
200
        string $prop,
201
        array $propVal,
202
        bool $writeAll
203
    ) : array {
204 1
        static::ThrowIfNotJsonType($jsonType);
205
206 1
        $out = [];
207
208 1
        foreach ($propVal as $val) {
209 1
            if (false === is_array($val)) {
210
                throw new PropertyNotJsonDecodableShouldBeArrayException(
211
                    $jsonType,
212
                    $prop
213
                );
214
            }
215 1
            $out[] = static::ArrayToJsonType(
216 1
                $jsonType,
217 1
                $val,
218 1
                $writeAll
219
            );
220
        }
221
222 1
        return $out;
223
    }
224
225
    /**
226
    * Retrieve a property from data.
227
    *
228
    * @param string $property the property being retrieved
229
    *
230
    * @throws PropertyNotNullableException if value is not set and $property is not listed as nullabe
231
    *
232
    * @return mixed the property value
233
    */
234 44
    protected function RetrievePropertyValueFromData(string $property)
235
    {
236
        if (
237 44
            false === array_key_exists($property, $this->data) &&
238 5
            false === in_array($property, static::NULLABLE_PROPERTIES, true)
239
        ) {
240 1
            throw new PropertyNotNullableException(static::class, $property);
241
        } elseif (
242 43
            in_array($property, static::NULLABLE_PROPERTIES, true)
243
        ) {
244 33
            return $this->data[$property] ?? null;
245
        }
246
247 43
        return $this->data[$property];
248
    }
249
250
    /**
251
    * {@inheritdoc}
252
    */
253 134
    protected function NudgePropertyValue(string $property, $value) : void
254
    {
255 134
        if (true !== in_array($property, static::PROPERTIES, true)) {
256 1
            throw new UndefinedPropertyException(static::class, $property);
257
        } elseif (
258 133
            true === is_null($value) &&
259 88
            true !== in_array($property, static::NULLABLE_PROPERTIES, true)
260
        ) {
261 58
            throw new PropertyNotNullableException(static::class, $property);
262
        } elseif (
263 75
            $this instanceof DaftObjectWorm &&
264
            (
265 50
                $this->HasPropertyChanged($property) ||
266
                (
267 50
                    isset($this->wormProperties[$property]) &&
0 ignored issues
show
Bug Best Practice introduced by
The property wormProperties does not exist on SignpostMarv\DaftObject\DaftObjectWorm. Since you implemented __get, consider adding a @property annotation.
Loading history...
268 2
                    true === $this->wormProperties[$property]
269
                )
270
            )
271
        ) {
272 50
            throw new PropertyNotRewriteableException(
273 50
                static::class,
274 50
                $property
275
            );
276
        }
277
278
        $isChanged = (
279 75
            false === array_key_exists($property, $this->data) ||
280 75
            $this->data[$property] !== $value
281
        );
282
283 75
        $this->data[$property] = $value;
284
285 75
        if ($isChanged && true !== isset($this->changedProperties[$property])) {
286 75
            $this->changedProperties[$property] = true;
287 75
            $this->wormProperties[$property] = true;
288
        }
289 75
    }
290
291 6
    private static function ThrowIfJsonDefNotValid(array $array) : array
292
    {
293 6
        $jsonProps = [];
294
295 6
        $props = static::DaftObjectJsonProperties();
296 6
        $jsonDef = static::DaftObjectJsonProperties();
297 6
        $nullableProps = static::DaftObjectNullableProperties();
298
299 6
        foreach ($jsonDef as $k => $v) {
300 6
            if (is_string($k)) {
301 3
                $jsonProps[] = $k;
302
            } else {
303 6
                $jsonProps[] = $v;
304
            }
305
        }
306
307 6
        foreach ($jsonProps as $prop) {
308
            if (
309
                (
310 6
                    false === isset($array[$prop]) ||
311 6
                    is_null($array[$prop])
312
                ) &&
313 2
                false === in_array($prop, $nullableProps, true)
314
            ) {
315
                throw new PropertyNotNullableException(static::class, $prop);
316
            }
317
        }
318
319 6
        $out = [];
320
321 6
        foreach (array_keys($array) as $prop) {
322
            if (
323 6
                false === in_array($prop, $props, true) &&
324 3
                false === isset($jsonDef[$prop])
325
            ) {
326
                throw new UndefinedPropertyException(static::class, $prop);
327
            } elseif (
328 6
                false === in_array($prop, $jsonProps, true)
329
            ) {
330
                throw new PropertyNotJsonDecodableException(
331
                    static::class,
332
                    $prop
333
                );
334 6
            } elseif (false === is_null($array[$prop])) {
335 6
                if (isset($jsonDef[$prop])) {
336 3
                    $jsonType = $jsonDef[$prop];
337
338 3
                    if (false === is_array($array[$prop])) {
339
                        if ('[]' === mb_substr($jsonType, -2)) {
340
                            throw new PropertyNotJsonDecodableShouldBeArrayException(
341
                                static::class,
342
                                $prop
343
                            );
344
                        }
345
                        throw new PropertyNotJsonDecodableShouldBeArrayException(
346
                            $jsonType,
347
                            $prop
348
                        );
349
                    }
350
                }
351 6
                $out[$prop] = $array[$prop];
352
            }
353
        }
354
355 6
        return $out;
356
    }
357
358 3
    private static function ThrowIfNotJsonType(string $jsonType) : void
359
    {
360 3
        if (false === is_a($jsonType, DaftJson::class, true)) {
361
            throw new ClassDoesNotImplementClassException(
362
                $jsonType,
363
                DaftJson::class
364
            );
365
        }
366 3
    }
367
368 3
    private static function ArrayToJsonType(
369
        string $jsonType,
370
        array $propVal,
371
        bool $writeAll
372
    ) : DaftJson {
373
        /**
374
        * @var DaftJson $jsonType
375
        */
376 3
        $jsonType = $jsonType;
377
378 3
        return $jsonType::DaftObjectFromJsonArray(
379 3
            $propVal,
380 3
            $writeAll
381
        );
382
    }
383
384 54 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...
385
    {
386 54
        if (false === is_a(static::class, DaftJson::class, true)) {
387 48
            throw new DaftObjectNotDaftJsonBadMethodCallException(
388 48
                static::class
389
            );
390
        }
391 6
    }
392
}
393