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 ( 7ac43b...fdcfe6 )
by SignpostMarv
05:29
created

RetrievePropertyValueFromDataExpectFloatish()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 1
dl 0
loc 6
ccs 5
cts 5
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 Closure;
12
13
/**
14
* Array-backed daft objects.
15
*/
16
abstract class AbstractArrayBackedDaftObject extends AbstractDaftObject implements DaftObjectCreatedByArray
17
{
18
    const BOOL_DEFAULT_WRITEALL = false;
19
20
    const BOOL_DEFAULT_AUTOTRIMSTRINGS = false;
21
22
    const BOOL_DEFAULT_THROWIFNOTUNIQUE = false;
23
24
    /**
25
    * data for this instance.
26
    *
27
    * @var array<string, scalar|array|object|null>
28
    */
29
    private $data = [];
30
31
    /**
32
    * List of changed properties.
33
    *
34
    * @var array<string, bool>
35
    */
36
    private $changedProperties = [];
37
38
    /**
39
    * List of changed properties, for write-once read-many.
40
    *
41
    * @var array<string, bool>
42
    */
43
    private $wormProperties = [];
44
45
    /**
46
    * @param array<string, scalar|array|object|null> $data
47
    */
48 1152
    public function __construct(array $data = [], bool $writeAll = false)
49
    {
50 1152
        if (true === $writeAll) {
51 192
            foreach ($data as $k => $v) {
52 192
                $this->__set($k, $v);
53
            }
54
        } else {
55 960
            foreach ($data as $k => $v) {
56 300
                $this->data[$k] = $v;
57
            }
58
        }
59 1152
    }
60
61 80
    public function __isset(string $property) : bool
62
    {
63
        return
64 80
            in_array(
65 60
                $property,
66 80
                static::DaftObjectProperties(),
67 80
                DefinitionAssistant::IN_ARRAY_STRICT_MODE
68
            ) &&
69 80
            isset($this->data, $this->data[$property]);
70
    }
71
72 88
    public function ChangedProperties() : array
73
    {
74 88
        return array_keys($this->changedProperties);
75
    }
76
77 88
    public function MakePropertiesUnchanged(string ...$properties) : void
78
    {
79 88
        foreach ($properties as $property) {
80 88
            unset($this->changedProperties[$property]);
81
        }
82 88
    }
83
84 280
    public function HasPropertyChanged(string $property) : bool
85
    {
86 280
        return $this->changedProperties[$property] ?? false;
87
    }
88
89 124
    public function jsonSerialize() : array
90
    {
91
        /**
92
        * @var array<int, string>
93
        */
94 124
        $properties = static::DaftObjectJsonPropertyNames();
95
96
        /**
97
        * @var array<string, string>
98
        */
99 52
        $properties = array_combine($properties, $properties);
100
101 52
        return array_filter(
102 39
            array_map(
103
                /**
104
                * @return scalar|array|object|null
105
                */
106
                function (string $property) {
107 52
                    return $this->DoGetSet($property, false);
108 52
                },
109 26
                $properties
110
            ),
111
            /**
112
            * @param scalar|array|object|null $maybe
113
            */
114
            function ($maybe) : bool {
115 52
                return ! is_null($maybe);
116 52
            }
117
        );
118
    }
119
120
    /**
121
    * @param array<int|string, scalar|(scalar|array|object|null)[]|object|null> $array
122
    */
123 124
    final public static function DaftObjectFromJsonArray(
124
        array $array,
125
        bool $writeAll = self::BOOL_DEFAULT_WRITEALL
126
    ) : DaftJson {
127 124
        $type = JsonTypeUtilities::ThrowIfNotDaftJson(static::class);
128
129 52
        $array = JsonTypeUtilities::ThrowIfJsonDefNotValid($type, $array);
130
131
        /**
132
        * @var array<int, string>
133
        */
134 52
        $props = array_keys($array);
135 52
        $mapper = static::DaftJsonClosure($array, $writeAll);
136
137
        /**
138
        * @var array<int, scalar|object|array|null>
139
        */
140 52
        $vals = array_map($mapper, $props);
141
142 52
        return new $type(array_combine($props, $vals), $writeAll);
143
    }
144
145 196
    public static function DaftObjectFromJsonString(string $string) : DaftJson
146
    {
147
        /**
148
        * @var scalar|array<int|string, scalar|(scalar|array|object|null)[]|object|null>|object|null
149
        */
150 196
        $decoded = json_decode($string, true);
151
152 196
        return JsonTypeUtilities::ThrowIfNotDaftJson(static::class)::DaftObjectFromJsonArray(
153 52
            is_array($decoded) ? $decoded : [$decoded]
154
        );
155
    }
156
157 324
    public function DaftObjectWormPropertyWritten(string $property) : bool
158
    {
159 324
        $wormProperties = $this->wormProperties;
160
161
        return
162 324
            ($this instanceof DaftObjectWorm) &&
163
            (
164 192
                $this->HasPropertyChanged($property) ||
165 324
                isset($wormProperties[$property])
166
            );
167
    }
168
169
    /**
170
    * Retrieve a property from data.
171
    *
172
    * @param string $property the property being retrieved
173
    *
174
    * @throws Exceptions\PropertyNotNullableException if value is not set and $property is not listed as nullabe
175
    *
176
    * @return scalar|array|object|null the property value
177
    */
178 216
    protected function RetrievePropertyValueFromData(string $property)
179
    {
180 216
        $isNullable = in_array(
181 162
            $property,
182 216
            static::DaftObjectNullableProperties(),
183 216
            DefinitionAssistant::IN_ARRAY_STRICT_MODE
184
        );
185
186 216
        if ( ! array_key_exists($property, $this->data) && ! $isNullable) {
187 4
            throw Exceptions\Factory::PropertyNotNullableException(static::class, $property);
188 212
        } elseif ($isNullable) {
189 128
            return $this->data[$property] ?? null;
190
        }
191
192 152
        return $this->data[$property];
193
    }
194
195 76
    protected function RetrievePropertyValueFromDataExpectString(string $property) : string
196
    {
197 76
        return TypeUtilities::ExpectRetrievedValueIsString(
198 57
            $property,
199 76
            $this->RetrievePropertyValueFromData($property),
200 76
            static::class
201
        );
202
    }
203
204 4
    protected function RetrievePropertyValueFromDataExpectStringOrNull(string $property) : ? string
205
    {
206 4
        $value = $this->RetrievePropertyValueFromData($property);
207
208 4
        if (is_null($value)) {
209 4
            return null;
210
        }
211
212 4
        return TypeUtilities::ExpectRetrievedValueIsString($property, $value, static::class);
213
    }
214
215 4
    protected function RetrievePropertyValueFromDataExpectArray(string $property) : array
216
    {
217 4
        return TypeUtilities::ExpectRetrievedValueIsArray(
218 3
            $property,
219 4
            $this->RetrievePropertyValueFromData($property),
220 4
            static::class
221
        );
222
    }
223
224 4
    protected function RetrievePropertyValueFromDataExpectArrayOrNull(string $property) : ? array
225
    {
226 4
        $value = $this->RetrievePropertyValueFromData($property);
227
228 4
        if (is_null($value)) {
229 4
            return null;
230
        }
231
232 4
        return TypeUtilities::ExpectRetrievedValueIsArray($property, $value, static::class);
233
    }
234
235 8
    protected function RetrievePropertyValueFromDataExpectIntish(string $property) : int
236
    {
237 8
        return TypeUtilities::ExpectRetrievedValueIsIntish(
238 6
            $property,
239 8
            $this->RetrievePropertyValueFromData($property),
240 8
            static::class
241
        );
242
    }
243
244 12
    protected function RetrievePropertyValueFromDataExpectIntishOrNull(string $property) : ? int
245
    {
246 12
        $value = $this->RetrievePropertyValueFromData($property);
247
248 12
        if (is_null($value)) {
249 12
            return null;
250
        }
251
252 12
        return TypeUtilities::ExpectRetrievedValueIsIntish($property, $value, static::class);
253
    }
254
255 4
    protected function RetrievePropertyValueFromDataExpectFloatish(string $property) : float
256
    {
257 4
        return TypeUtilities::ExpectRetrievedValueIsFloatish(
258 3
            $property,
259 4
            $this->RetrievePropertyValueFromData($property),
260 4
            static::class
261
        );
262
    }
263
264 12
    protected function RetrievePropertyValueFromDataExpectFloatishOrNull(string $property) : ? float
265
    {
266 12
        $value = $this->RetrievePropertyValueFromData($property);
267
268 12
        if (is_null($value)) {
269 12
            return null;
270
        }
271
272 12
        return TypeUtilities::ExpectRetrievedValueIsFloatish($property, $value, static::class);
273
    }
274
275 8
    protected function RetrievePropertyValueFromDataExpectBoolish(string $property) : bool
276
    {
277 8
        return TypeUtilities::ExpectRetrievedValueIsBoolish(
278 6
            $property,
279 8
            $this->RetrievePropertyValueFromData($property),
280 8
            static::class
281
        );
282
    }
283
284 28
    protected function RetrievePropertyValueFromDataExpectBoolishOrNull(string $property) : ? bool
285
    {
286 28
        $value = $this->RetrievePropertyValueFromData($property);
287
288 28
        if (is_null($value)) {
289 28
            return null;
290
        }
291
292 28
        return TypeUtilities::ExpectRetrievedValueIsBoolish($property, $value, static::class);
293
    }
294
295
    /**
296
    * @param scalar|array|object|null $value
297
    */
298 540
    protected function NudgePropertyValue(
299
        string $property,
300
        $value,
301
        bool $autoTrimStrings = self::BOOL_DEFAULT_AUTOTRIMSTRINGS,
302
        bool $throwIfNotUnique = self::BOOL_DEFAULT_THROWIFNOTUNIQUE
303
    ) : void {
304 540
        TypeUtilities::MaybeThrowOnNudge(static::class, $property, $value);
305
306 324
        if ($this->DaftObjectWormPropertyWritten($property)) {
307 192
            throw Exceptions\Factory::PropertyNotRewriteableException(static::class, $property);
308
        }
309
310 324
        $value = $this->MaybeModifyValueBeforeNudge(
311 243
            $property,
312 162
            $value,
313 162
            $autoTrimStrings,
314 162
            $throwIfNotUnique
315
        );
316
317
        $isChanged = (
318 308
            ! array_key_exists($property, $this->data) ||
319 308
            $this->data[$property] !== $value
320
        );
321
322 308
        $this->data[$property] = $value;
323
324 308
        if ($isChanged && true !== isset($this->changedProperties[$property])) {
325 308
            $this->changedProperties[$property] = $this->wormProperties[$property] = true;
326
        }
327 308
    }
328
329
    /**
330
    * @param array<int|string, scalar|array|object|null> $array
331
    */
332 52
    private static function DaftJsonClosure(array $array, bool $writeAll) : Closure
333
    {
334 52
        $jsonDef = static::DaftObjectJsonProperties();
335
336
        return
337
            /**
338
            * @return scalar|array|object|null
339
            */
340
            function (string $prop) use ($array, $jsonDef, $writeAll) {
341
                /**
342
                * @var string|null
343
                */
344 52
                $jsonType = $jsonDef[$prop] ?? null;
345
346 52
                if ( ! is_string($jsonType)) {
347 36
                    return $array[$prop];
348
                }
349
350
                /**
351
                * @var array<int|string, scalar|(scalar|(scalar|array|object|null)[]|object|null)[]|object|null>
352
                */
353 44
                $propVal = (is_array($array[$prop]) ? $array[$prop] : [$array[$prop]]);
354
355 44
                if ('[]' === mb_substr($jsonType, -2)) {
356
                    /**
357
                    * @psalm-var class-string<DaftObject>
358
                    */
359 44
                    $jsonType = mb_substr($jsonType, 0, -2);
360
361 44
                    $jsonType = JsonTypeUtilities::ThrowIfNotJsonType($jsonType);
362
363 44
                    return JsonTypeUtilities::DaftObjectFromJsonTypeArray(
364 33
                        $jsonType,
365 22
                        $prop,
366 22
                        $propVal,
367 22
                        $writeAll
368
                    );
369
                }
370
371
                /**
372
                * @psalm-var class-string<DaftObject>
373
                */
374 28
                $jsonType = $jsonType;
375
376 28
                $jsonType = JsonTypeUtilities::ThrowIfNotJsonType($jsonType);
377
378 28
                return JsonTypeUtilities::DaftJsonFromJsonType($jsonType, $propVal, $writeAll);
379 52
            };
380
    }
381
382
    /**
383
    * @param scalar|array|object|null $value
384
    *
385
    * @return scalar|array|object|null
386
    */
387 324
    private function MaybeModifyValueBeforeNudge(
388
        string $property,
389
        $value,
390
        bool $autoTrimStrings = self::BOOL_DEFAULT_AUTOTRIMSTRINGS,
391
        bool $throwIfNotUnique = self::BOOL_DEFAULT_THROWIFNOTUNIQUE
392
    ) {
393 324
        $spec = null;
394
395
        if (
396 324
            is_a(
397 324
                static::class,
398 324
                DaftObjectHasPropertiesWithMultiTypedArraysOfUniqueValues::class,
399 324
                true
400
            )
401
        ) {
402
            $spec = (
403 24
                static::DaftObjectPropertiesWithMultiTypedArraysOfUniqueValues()[$property] ?? null
404
            );
405
        }
406
407 324
        if (is_array($spec)) {
408 20
            $value = DefinitionAssistant::MaybeThrowIfValueDoesNotMatchMultiTypedArray(
409 15
                $autoTrimStrings,
410 10
                $throwIfNotUnique,
411 10
                $value,
412 8
                ...$spec
413
            );
414
        }
415
416 308
        if (is_string($value) && $autoTrimStrings) {
417 4
            $value = trim($value);
418
        }
419
420 308
        return $value;
421
    }
422
}
423