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 ( 26dda9...47155b )
by SignpostMarv
03:11
created

GenerateDaftObjectFromJsonArrayClosure()   B

Complexity

Conditions 3
Paths 1

Size

Total Lines 26
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 13
nc 1
nop 2
dl 0
loc 26
ccs 12
cts 12
cp 1
crap 3
rs 8.8571
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
    /**
19
    * data for this instance.
20
    *
21
    * @var array<string, mixed>
22
    */
23
    private $data = [];
24
25
    /**
26
    * List of changed properties.
27
    *
28
    * @var array<string, bool>
29
    */
30
    private $changedProperties = [];
31
32
    /**
33
    * List of changed properties, for write-once read-many.
34
    *
35
    * @var array<string, bool>
36
    */
37
    private $wormProperties = [];
38
39 376
    public function __construct(array $data = [], bool $writeAll = false)
40
    {
41 376
        parent::__construct();
42
43 372
        if (true === $writeAll) {
44 122
            foreach ($data as $k => $v) {
45 122
                $this->__set($k, $v);
46
            }
47
        } else {
48 254
            foreach ($data as $k => $v) {
49 132
                $this->data[$k] = $v;
50
            }
51
        }
52 368
    }
53
54 62
    public function __isset(string $property) : bool
55
    {
56
        return
57 62
            in_array($property, static::PROPERTIES, true) &&
58 62
            isset($this->data, $this->data[$property]);
59
    }
60
61 58
    public function ChangedProperties() : array
62
    {
63 58
        return array_keys($this->changedProperties);
64
    }
65
66 66
    public function MakePropertiesUnchanged(string ...$properties) : void
67
    {
68 66
        foreach ($properties as $property) {
69 66
            unset($this->changedProperties[$property]);
70
        }
71 66
    }
72
73 164
    public function HasPropertyChanged(string $property) : bool
74
    {
75
        return
76 164
            isset($this->changedProperties[$property]) &&
77 164
            true === $this->changedProperties[$property];
78
    }
79
80 44
    public function jsonSerialize() : array
81
    {
82 44
        static::ThrowIfNotDaftJson();
83
84 12
        $out = [];
85
86 12
        foreach (static::DaftObjectJsonPropertyNames() as $property) {
87 12
            $val = $this->DoGetSet($property, false);
88
89 12
            if (false === is_null($val)) {
90 12
                $out[$property] = $val;
91
            }
92
        }
93
94 12
        return $out;
95
    }
96
97 56
    final public static function DaftObjectFromJsonArray(
98
        array $array,
99
        bool $writeAll = false
100
    ) : DaftJson {
101 56
        static::ThrowIfNotDaftJson();
102 24
        $array = static::ThrowIfJsonDefNotValid($array);
103 18
        $props = array_keys($array);
104 18
        $mapper = static::GenerateDaftObjectFromJsonArrayClosure($array, $writeAll);
105
106
        /**
107
        * @var DaftJson $out
108
        */
109 18
        $out = new static(array_combine($props, array_map($mapper, $props)), $writeAll);
110
111 14
        return $out;
112
    }
113
114 44
    public static function DaftObjectFromJsonString(string $string) : DaftJson
115
    {
116 44
        static::ThrowIfNotDaftJson();
117
118 12
        return static::DaftObjectFromJsonArray(json_decode($string, true));
119
    }
120
121 150
    public function DaftObjectWormPropertyWritten(string $property) : bool
122
    {
123 150
        $wormProperties = $this->wormProperties;
124
125
        return
126 150
            ($this instanceof DaftObjectWorm) &&
127
            (
128 100
                $this->HasPropertyChanged($property) ||
129 150
                false === empty($wormProperties[$property])
130
            );
131
    }
132
133 18
    final protected static function GenerateDaftObjectFromJsonArrayClosure(
134
        array $array,
135
        bool $writeAll
136
    ) : Closure {
137 18
        $jsonDef = static::DaftObjectJsonProperties();
138
139
        return
140
            /**
141
            * @return mixed
142
            */
143
            function (string $prop) use ($array, $jsonDef, $writeAll) {
144 16
                $jsonType = $jsonDef[$prop] ?? null;
145 16
                if (is_string($jsonType)) {
146 10
                    if ('[]' === mb_substr($jsonType, -2)) {
147 6
                        return static::DaftObjectFromJsonTypeArray(
148 6
                            mb_substr($jsonType, 0, -2),
149 6
                            $prop,
150 6
                            $array[$prop],
151 6
                            $writeAll
152
                        );
153
                    }
154
155 4
                    return static::DaftObjectFromJsonType($jsonType, $array[$prop], $writeAll);
156
                }
157
158 12
                return $array[$prop];
159 18
            };
160
    }
161
162
    /**
163
    * @param array<string, mixed> $propVal
164
    *
165
    * @return DaftJson
166
    */
167 4
    protected static function DaftObjectFromJsonType(string $type, array $propVal, bool $writeAll)
168
    {
169 4
        static::ThrowIfNotJsonType($type);
170
171 4
        return static::ArrayToJsonType($type, $propVal, $writeAll);
172
    }
173
174
    /**
175
    * @return array<int, DaftJson>
176
    */
177 6
    protected static function DaftObjectFromJsonTypeArray(
178
        string $jsonType,
179
        string $prop,
180
        array $propVal,
181
        bool $writeAll
182
    ) : array {
183 6
        static::ThrowIfNotJsonType($jsonType);
184
185 4
        $out = [];
186
187 4
        foreach ($propVal as $val) {
188 4
            if (false === is_array($val)) {
189 2
                throw new PropertyNotJsonDecodableShouldBeArrayException($jsonType, $prop);
190
            }
191 2
            $out[] = static::ArrayToJsonType($jsonType, $val, $writeAll);
192
        }
193
194 2
        return $out;
195
    }
196
197
    /**
198
    * Retrieve a property from data.
199
    *
200
    * @param string $property the property being retrieved
201
    *
202
    * @throws PropertyNotNullableException if value is not set and $property is not listed as nullabe
203
    *
204
    * @return mixed the property value
205
    */
206 90
    protected function RetrievePropertyValueFromData(string $property)
207
    {
208
        if (
209 90
            false === array_key_exists($property, $this->data) &&
210 90
            false === in_array($property, static::NULLABLE_PROPERTIES, true)
211
        ) {
212 4
            throw new PropertyNotNullableException(static::class, $property);
213
        } elseif (
214 86
            in_array($property, static::NULLABLE_PROPERTIES, true)
215
        ) {
216 66
            return $this->data[$property] ?? null;
217
        }
218
219 86
        return $this->data[$property];
220
    }
221
222 268
    protected function NudgePropertyValue(string $property, $value) : void
223
    {
224 268
        $this->MaybeThrowOnNudge($property, $value);
225
226
        $isChanged = (
227 150
            false === array_key_exists($property, $this->data) ||
228 150
            $this->data[$property] !== $value
229
        );
230
231 150
        $this->data[$property] = $value;
232
233 150
        if ($isChanged && true !== isset($this->changedProperties[$property])) {
234 150
            $this->changedProperties[$property] = true;
235 150
            $this->wormProperties[$property] = true;
236
        }
237 150
    }
238
239
    /**
240
    * @param mixed $value
241
    *
242
    * @see AbstractArrayBackedDaftObject::NudgePropertyValue()
243
    */
244 268
    private function MaybeThrowOnNudge(string $property, $value) : void
245
    {
246 268
        if (true !== in_array($property, static::PROPERTIES, true)) {
247 2
            throw new UndefinedPropertyException(static::class, $property);
248
        } elseif (
249 266
            true === is_null($value) &&
250 266
            true !== in_array($property, static::NULLABLE_PROPERTIES, true)
251
        ) {
252 116
            throw new PropertyNotNullableException(static::class, $property);
253 150
        } elseif ($this->DaftObjectWormPropertyWritten($property)) {
254 100
            throw new PropertyNotRewriteableException(static::class, $property);
255
        }
256 150
    }
257
258 24
    private static function ThrowIfJsonDefNotValid(array $array) : array
259
    {
260 24
        $jsonProps = static::DaftObjectJsonPropertyNames();
261
262 24
        $jsonDef = static::DaftObjectJsonProperties();
263
264 24
        $out = [];
265
266 24
        foreach ($array as $prop => $propVal) {
267 24
            if (false === in_array($prop, $jsonProps, true)) {
268 2
                throw new PropertyNotJsonDecodableException(static::class, $prop);
269 24
            } elseif (false === is_null($propVal)) {
270 22
                if (isset($jsonDef[$prop])) {
271 16
                    $jsonType = $jsonDef[$prop];
272
273 16
                    if (false === is_array($propVal)) {
274 4
                        static::ThrowBecauseArrayJsonTypeNotValid($jsonType, $prop);
275
                    }
276
                }
277 20
                $out[$prop] = $propVal;
278
            }
279
        }
280
281 18
        return $out;
282
    }
283
284 4
    private static function ThrowBecauseArrayJsonTypeNotValid(string $type, string $prop) : void
285
    {
286 4
        if ('[]' === mb_substr($type, -2)) {
287 2
            throw new PropertyNotJsonDecodableShouldBeArrayException(static::class, $prop);
288
        }
289 2
        throw new PropertyNotJsonDecodableShouldBeArrayException($type, $prop);
290
    }
291
292 10
    private static function ThrowIfNotJsonType(string $jsonType) : void
293
    {
294 10
        if (false === is_a($jsonType, DaftJson::class, true)) {
295 2
            throw new ClassDoesNotImplementClassException($jsonType, DaftJson::class);
296
        }
297 8
    }
298
299 6
    private static function ArrayToJsonType(string $type, array $value, bool $writeAll) : DaftJson
300
    {
301
        /**
302
        * @var DaftJson $type
303
        */
304 6
        $type = $type;
305
306 6
        return $type::DaftObjectFromJsonArray($value, $writeAll);
307
    }
308
}
309