Test Failed
Push — master ( 416f02...68008b )
by SignpostMarv
02:20
created

Thing::ExpectRetrievedValueIsArrayOfStrings()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 8
ccs 3
cts 3
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
* @author SignpostMarv
4
*/
5
declare(strict_types=1);
6
7
namespace SignpostMarv\DaftObject\SchemaOrg;
8
9
use InvalidArgumentException;
10
use SignpostMarv\DaftObject\AbstractArrayBackedDaftObject;
11
use SignpostMarv\DaftObject\DaftJson;
12
use SignpostMarv\DaftObject\DaftObjectHasPropertiesWithMultiTypedArraysOfUniqueValues;
13
use SignpostMarv\DaftObject\JsonTypeUtilities;
14
use SignpostMarv\DaftObject\SchemaOrg\CreativeWork\MediaObject\ImageObject;
15
use SignpostMarv\DaftObject\SchemaOrg\Intangible\StructuredValue\PropertyValue;
16
use SignpostMarv\DaftObject\SchemaOrgLookup\LookupInterface;
17
18
/**
19
* @property array<int, string> $additionalType
20
* @property array<int, string> $alternateName
21
* @property array<int, string> $description
22
* @property array<int, string> $disambiguatingDescription
23
* @property array<int, string|PropertyValue> $identifier
24
* @property array<int, string|ImageObject> $image
25
* @property array<int, string|CreativeWork> $mainEntityOfPage
26
* @property array<int, string> $name
27
* @property array<int, Action> $potentialAction
28
* @property array<int, string> $sameAs
29
* @property array<int, CreativeWork|Event> $subjectOf
30
* @property array<int, Action> $potentialAction
31
* @property array<int, string> $url
32
*
33
* @template-implements DaftJson<Thing>
34
*/
35
class Thing extends AbstractArrayBackedDaftObject implements
36
    DaftJson,
37
    DaftObjectHasPropertiesWithMultiTypedArraysOfUniqueValues
38
{
39
    const SCHEMA_ORG_CONTEXT = 'http://schema.org';
40
41
    const SCHEMA_ORG_TYPE = 'Thing';
42
43
    const PROPERTIES = [
44
        '@context',
45
        '@type',
46
        'additionalType',
47
        'alternateName',
48
        'description',
49
        'disambiguatingDescription',
50
        'identifier',
51
        'image',
52
        'mainEntityOfPage',
53
        'name',
54
        'potentialAction',
55
        'sameAs',
56
        'subjectOf',
57
        'url',
58
    ];
59
60
    const PROPERTIES_WITH_MULTI_TYPED_ARRAYS = [
61
        'additionalType' => [
62
            'string',
63
        ],
64
        'alternateName' => [
65
            'string',
66
        ],
67
        'description' => [
68
            'string',
69
        ],
70
        'disambiguatingDescription' => [
71
            'string',
72
        ],
73
        'identifier' => [
74
            'string',
75
            PropertyValue::class,
76
        ],
77
        'image' => [
78
            'string',
79
            ImageObject::class,
80
        ],
81
        'mainEntityOfPage' => [
82
            'string',
83
            CreativeWork::class,
84
        ],
85
        'name' => [
86
            'string',
87
        ],
88
        'potentialAction' => [
89
            Action::class,
90
        ],
91
        'sameAs' => [
92
            'string',
93
        ],
94
        'subjectOf' => [
95
            CreativeWork::class,
96
            Event::class,
97
        ],
98
        'url' => [
99
            'string',
100
        ],
101
    ];
102
103 10220
    public function __construct(array $data = [], bool $writeAll = false)
104
    {
105 10220
        $missing = array_diff(static::DaftObjectProperties(), array_keys($data));
106
107
        /**
108
        * @var array<int, string>
109
        */
110 10220
        $missing = array_combine(
111 10220
            $missing,
112 10220
            array_fill(0, count($missing), [])
113
        );
114
115
        /**
116
        * @var array<string, scalar|array|object|null>
117
        */
118 10220
        $data = array_merge(
119 10220
            $data,
120 10220
            $missing
121
        );
122
123 10220
        unset($data['@context'], $data['@type']);
124
125 10220
        parent::__construct($data, $writeAll);
126 10220
    }
127
128 261
    public function ObtainContext() : string
129
    {
130 261
        return (string) static::SCHEMA_ORG_CONTEXT;
131
    }
132
133 261
    public function ObtainType() : string
134
    {
135 261
        return (string) static::SCHEMA_ORG_TYPE;
136
    }
137
138
    /**
139
    * @return array<int, string>
140
    */
141 520
    public function GetAdditionalType() : array
142
    {
143
        return $this->ExpectRetrievedValueIsArrayOfStrings('additionalType');
144
    }
145
146 520
    /**
147
    * @param array<int, string> $value
148 520
    */
149
    public function SetAdditionalType(array $value) : void
150
    {
151
        $this->NudgePropertyValue('additionalType', $value, true);
152
    }
153
154 260
    /**
155
    * @return array<int, string>
156 260
    */
157 260
    public function GetAlternateName() : array
158
    {
159
        return $this->ExpectRetrievedValueIsArrayOfStrings('alternateName');
160
    }
161
162 520
    /**
163
    * @param array<int, string> $value
164
    */
165
    public function SetAlternateName(array $value) : void
166
    {
167 520
        $this->NudgePropertyValue('alternateName', $value, true);
168
    }
169 520
170
    /**
171
    * @return array<int, string>
172
    */
173
    public function GetDescription() : array
174
    {
175 260
        return $this->ExpectRetrievedValueIsArrayOfStrings('description');
176
    }
177 260
178 260
    /**
179
    * @param array<int, string> $value
180
    */
181
    public function SetDescription(array $value) : void
182
    {
183 520
        $this->NudgePropertyValue('description', $value, true);
184
    }
185
186
    /**
187
    * @return array<int, string>
188 520
    */
189
    public function GetDisambiguatingDescription() : array
190 520
    {
191
        return $this->ExpectRetrievedValueIsArrayOfStrings('disambiguatingDescription');
192
    }
193
194
    /**
195
    * @param array<int, string> $value
196 260
    */
197
    public function SetDisambiguatingDescription(array $value) : void
198 260
    {
199 260
        $this->NudgePropertyValue('disambiguatingDescription', $value, true);
200
    }
201
202
    /**
203
    * @return array<int, string|PropertyValue>
204 520
    */
205
    public function GetIdentifier() : array
206
    {
207
        /**
208
        * @var array<int, string|PropertyValue>
209 520
        */
210
        $out = $this->ExpectRetrievedValueIsArray('identifier');
211 520
212
        return $out;
213
    }
214
215
    /**
216
    * @param array<int, string|PropertyValue> $value
217 260
    */
218
    public function SetIdentifier(array $value) : void
219 260
    {
220 260
        $this->NudgePropertyValue('identifier', $value, true);
221
    }
222
223
    /**
224
    * @return array<int, string|ImageObject>
225 521
    */
226
    public function GetImage() : array
227
    {
228
        /**
229
        * @var array<int, string|ImageObject>
230 521
        */
231
        $out = $this->ExpectRetrievedValueIsArray('image');
232 521
233
        return $out;
234
    }
235
236
    /**
237
    * @param array<int, string|ImageObject> $value
238 261
    */
239
    public function SetImage(array $value) : void
240 261
    {
241 261
        $this->NudgePropertyValue('image', $value, true);
242
    }
243
244
    /**
245
    * @return array<int, string|CreativeWork>
246 520
    */
247
    public function GetMainEntityOfPage() : array
248
    {
249
        /**
250
        * @var array<int, string|CreativeWork>
251 520
        */
252
        $out = $this->ExpectRetrievedValueIsArray('mainEntityOfPage');
253 520
254
        return $out;
255
    }
256
257
    /**
258
    * @param array<int, string|CreativeWork> $value
259 260
    */
260
    public function SetMainEntityOfPage(array $value) : void
261 260
    {
262 260
        $this->NudgePropertyValue('mainEntityOfPage', $value, true);
263
    }
264
265
    /**
266
    * @return array<int, string>
267 520
    */
268
    public function GetName() : array
269
    {
270
        return $this->ExpectRetrievedValueIsArrayOfStrings('name');
271
    }
272 520
273
    /**
274 520
    * @param array<int, string> $value
275
    */
276
    public function SetName(array $value) : void
277
    {
278
        $this->NudgePropertyValue('name', $value, true);
279
    }
280 260
281
    /**
282 260
    * @return array<int, Action>
283 260
    */
284
    public function GetPotentialAction() : array
285
    {
286
        /**
287
        * @var array<int, Action>
288 520
        */
289
        $out = $this->ExpectRetrievedValueIsArray('potentialAction');
290
291
        return $out;
292
    }
293 520
294
    /**
295 520
    * @param array<int, Action> $value
296
    */
297
    public function SetPotentialAction(array $value) : void
298
    {
299
        $this->NudgePropertyValue('potentialAction', $value);
300
    }
301 260
302
    /**
303 260
    * @return array<int, string>
304 260
    */
305
    public function GetSameAs() : array
306
    {
307
        return $this->ExpectRetrievedValueIsArrayOfStrings('sameAs');
308
    }
309 520
310
    /**
311
    * @param array<int, string> $value
312
    */
313
    public function SetSameAs(array $value) : void
314 520
    {
315
        $this->NudgePropertyValue('sameAs', $value, true);
316 520
    }
317
318
    /**
319
    * @return array<int, CreativeWork|Event>
320
    */
321
    public function GetSubjectOf() : array
322 260
    {
323
        /**
324 260
        * @var array<int, CreativeWork|Event>
325 260
        */
326
        $out = $this->ExpectRetrievedValueIsArray('subjectOf');
327
328
        return $out;
329
    }
330 520
331
    /**
332
    * @param array<int, CreativeWork|Event> $value
333
    */
334
    public function SetSubjectOf(array $value) : void
335 520
    {
336
        $this->NudgePropertyValue('subjectOf', $value, true);
337 520
    }
338
339
    /**
340
    * @return array<int, string>
341
    */
342
    public function GetUrl() : array
343 260
    {
344
        return $this->ExpectRetrievedValueIsArrayOfStrings('url');
345 260
    }
346 260
347
    /**
348
    * @param array<int, string> $value
349
    */
350
    public function SetUrl(array $value) : void
351 520
    {
352
        $this->NudgePropertyValue('url', $value, true);
353
    }
354
355
    public function jsonSerialize() : array
356 520
    {
357
        return array_filter(
358 520
            parent::jsonSerialize(),
359
            /**
360
            * @param scalar|array|object|null $val
361
            */
362
            function ($val) : bool {
363
                return ! is_array($val) || count($val) > 0;
364 260
            }
365
        );
366 260
    }
367 260
368
    public static function DaftObjectProperties() : array
369
    {
370
        /**
371
        * @var array<int, string>
372 520
        */
373
        $static = static::PROPERTIES;
374
375
        /**
376
        * @var string
377 520
        *
378
        * @psalm-var class-string<Thing>
379 520
        */
380
        $static_parent = get_parent_class(static::class);
381
382
        $parent = $static_parent::DaftObjectProperties();
383
384
        return array_unique(array_merge(
385 260
            $parent,
386
            $static
387 260
        ));
388 260
    }
389
390 261
    /**
391
    * @return array<string, array<int, string>>
392 261
    */
393 261
    public static function DaftObjectPropertiesWithMultiTypedArraysOfUniqueValues() : array
394
    {
395
        /**
396
        * @var array<string, array<int, string>>
397
        */
398 261
        $static = static::PROPERTIES_WITH_MULTI_TYPED_ARRAYS;
399 261
400
        /**
401
        * @var string
402
        *
403 20654
        * @psalm-var class-string<Thing>
404
        */
405
        $static_parent = get_parent_class(static::class);
406
407
        if ($static_parent === get_parent_class(self::class)) {
408 20654
            return $static;
409
        }
410
411
        $parent = $static_parent::DaftObjectPropertiesWithMultiTypedArraysOfUniqueValues();
412
413
        return array_merge(
414
            $parent,
415 20654
            $static
416
        );
417 20654
    }
418
419 20654
    public static function DaftObjectNullableProperties() : array
420 20654
    {
421 20654
        /**
422
        * @var array<int, string>
423
        */
424
        $static = static::NULLABLE_PROPERTIES;
425
426
        /**
427
        * @var string
428 523
        *
429
        * @psalm-var class-string<Thing>
430
        */
431
        $static_parent = get_parent_class(static::class);
432
433 523
        $parent = $static_parent::DaftObjectNullableProperties();
434
435
        return array_unique(array_merge(
436
            $parent,
437
            $static
438
        ));
439
    }
440 523
441
    public static function DaftObjectExportableProperties() : array
442 523
    {
443 523
        return static::DaftObjectProperties();
444
    }
445
446 521
    public static function DaftObjectJsonProperties() : array
447
    {
448 521
        return static::DaftObjectProperties();
449 521
    }
450 521
451
    public static function DaftObjectPublicGetters() : array
452
    {
453
        /**
454 10329
        * @var string
455
        *
456
        * @psalm-var class-string<Thing>
457
        */
458
        $static_parent = get_parent_class(static::class);
459 10329
460
        $static = TypeUtilities::DaftObjectPublicGetters(static::class);
461
462
        if ($static_parent === get_parent_class(self::class)) {
463
            return $static;
464
        }
465
466 10329
        return array_unique(array_merge(
467
            TypeUtilities::DaftObjectPublicGetters($static_parent),
468 10329
            $static
469
        ));
470 10329
    }
471 10329
472 10329
    public static function DaftObjectPublicOrProtectedGetters() : array
473
    {
474
        /**
475
        * @var string
476 478
        *
477
        * @psalm-var class-string<Thing>
478 478
        */
479
        $static_parent = get_parent_class(static::class);
480
481 521
        $static = TypeUtilities::DaftObjectPublicOrProtectedGetters(static::class);
482
483 521
        if ($static_parent === get_parent_class(self::class)) {
484
            return $static;
485
        }
486 521
487
        return array_unique(array_merge(
488
            TypeUtilities::DaftObjectPublicOrProtectedGetters($static_parent),
489
            $static
490
        ));
491
    }
492
493 521
    public static function DaftObjectPublicSetters() : array
494
    {
495 521
        /**
496
        * @var string
497 521
        *
498 91
        * @psalm-var class-string<Thing>
499
        */
500
        $static_parent = get_parent_class(static::class);
501 520
502 520
        $static = TypeUtilities::DaftObjectPublicSetters(static::class);
503 520
504
        if ($static_parent === get_parent_class(self::class)) {
505
            return $static;
506
        }
507 1
508
        return array_unique(array_merge(
509
            TypeUtilities::DaftObjectPublicSetters($static_parent),
510
            $static
511
        ));
512
    }
513
514 1
    /**
515
    * @return static
516 1
    *
517
    * @psalm-return Thing
518 1
    */
519 1
    public static function DaftObjectFromJsonString(
520
        string $string,
521
        bool $writeAll = self::BOOL_DEFAULT_WRITEALL
522 1
    ) : DaftJson {
523 1
        /**
524 1
        * @var array<string, scalar|(scalar|array|object|null)[]|object|null>
525
        */
526
        $decoded = json_decode($string, true);
527
528 261
        /**
529
        * @var static
530
        */
531
        $out = static::DaftObjectFromJsonArray($decoded, $writeAll);
532
533
        return $out;
534
    }
535 261
536
    /**
537 261
    * @return static
538
    *
539 261
    * @psalm-return Thing
540 2
    */
541
    public static function DaftObjectFromJsonArray(
542
        array $array,
543 260
        bool $writeAll = self::BOOL_DEFAULT_WRITEALL
544 260
    ) : DaftJson {
545 260
        $type = JsonTypeUtilities::ThrowIfNotDaftJson(static::class);
546
547
        $multi_type = static::DaftObjectPropertiesWithMultiTypedArraysOfUniqueValues();
548
549
        $array_keys = array_keys($array);
550
551
        foreach ($array_keys as $k) {
552
            if ( ! is_string($k)) {
553
                throw new InvalidArgumentException(
554 261
                    'Argument 1 passed to ' .
555
                    __METHOD__ .
556
                    '() must have all-string indices!'
557
                );
558
            }
559
        }
560
561 261
        /**
562
        * @var array<int, string>
563
        */
564
        $array_keys = $array_keys;
565
566 261
        $data = array_combine($array_keys, array_map(
567
            /**
568 261
            * @param string $k
569
            *
570
            * @return mixed
571
            */
572
            function (string $k) use ($array, $multi_type) {
573
                if (is_array($array[$k])) {
574
                    return static::DaftObjectFromJsonArrayFromArray($k, $multi_type, $array[$k]);
575
                }
576 262
577
                return $array[$k];
578
            },
579
            $array_keys
580 262
        ));
581
582 262
        /**
583
        * @psalm-var Thing
584 262
        *
585
        * @var Thing
586 262
        */
587 262
        $out = new $type($data, $writeAll);
588 1
589
        return $out;
590
    }
591 262
592
    /**
593
    * @param array<string, array<int, string>> $multi_type
594
    */
595
    protected static function DaftObjectFromJsonArrayFromArray(
596
        string $k,
597
        array $multi_type,
598
        array $arr
599 261
    ) : array {
600
        return array_map(
601 261
            /**
602
            * @param mixed $val
603
            *
604
            * @return mixed
605
            */
606
            function ($val) use ($k, $multi_type) {
607
                if (
608 261
                    is_array($val) &&
609 261
                    isset($val['@context'], $val['@type'], $multi_type[$k])
610
                ) {
611
                    /**
612 261
                    * @psalm-var array<string, array<array-key, array<array-key, mixed>|scalar|object|null>|scalar|object|null>
613 261
                    */
614 261
                    $val = $val;
615
616
                    return static::DaftObjectFromJsonArrayFromArrayMapVal($val, $multi_type, $k);
617
                }
618
619
                return $val;
620
            },
621
            $arr
622 261
        );
623
    }
624 261
625
    /**
626
    * @param array<string, array<int, string>> $multi_type
627
    *
628
    * @psalm-param array<string, array<array-key, array<array-key, mixed>|scalar|object|null>|scalar|object|null> $val
629
    */
630 261
    protected static function DaftObjectFromJsonArrayFromArrayMapVal(
631
        array $val,
632
        array $multi_type,
633
        string $k
634
    ) : Thing {
635 261
        foreach ($multi_type[$k] as $maybe) {
636
            $lookup_class =
637
                '\\SignpostMarv\\DaftObject\\SchemaOrgLookup\\Lookup_' .
638
                hash('sha512', $maybe);
639
            if (is_a($lookup_class, LookupInterface::class, true)) {
640
                /**
641
                * @psalm-var array<int, class-string<Thing>>
642
                */
643 261
                $maybe_classes = $lookup_class::ObtainClasses();
644 261
645
                foreach ($maybe_classes as $maybe_class) {
646
                    if (
647
                        $val['@context'] === $maybe_class::SCHEMA_ORG_CONTEXT &&
648
                        $val['@type'] === $maybe_class::SCHEMA_ORG_TYPE
649 261
                    ) {
650
                        return $maybe_class::DaftObjectFromJsonArray($val);
651 261
                    }
652
                }
653
            }
654 261
        }
655 261
656 261
        throw new InvalidArgumentException(
657
            'Argument 3 (' .
658
            $k .
659
            ') passed to ' .
660
            __METHOD__ .
661
            '() did not correspond to an instance of ' .
662
            Thing::class .
663
            ' as defined in Argument 2!'
664
        );
665 261
    }
666
667
    protected function ExpectRetrievedValueIsArray(string $property) : array
668
    {
669
        return TypeUtilities::ExpectRetrievedValueIsArray(
670 261
            $property,
671
            $this->RetrievePropertyValueFromData($property),
672 261
            static::class
673
        );
674
    }
675
676 261
    /**
677
    * @return array<int, string>
678 261
    */
679
    protected function ExpectRetrievedValueIsArrayOfStrings(string $property) : array
680
    {
681
        /**
682 261
        * @var array<int, string>
683
        */
684 261
        $out = $this->ExpectRetrievedValueIsArrayOfStrings($property);
685
686 261
        return $out;
687 261
    }
688
689 261
    /**
690
    * @param array<int, bool> $value
691
    */
692
    protected function NudgePropertyWithUniqueBooleans(
693
        string $property,
694
        array $value
695
    ) : void {
696
        $replace = [];
697
        if (in_array(true, $value, true)) {
698
            $replace[] = true;
699
        }
700
        if (in_array(false, $value, true)) {
701
            $replace[] = false;
702
        }
703
704
        $this->NudgePropertyValue($property, $replace);
705
    }
706
}
707