Passed
Push — master ( 77331f...637ad2 )
by SignpostMarv
03:51
created

Thing::NudgePropertyWithUniqueValuesOfThings()   B

Complexity

Conditions 6
Paths 4

Size

Total Lines 55
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 8.4648

Importance

Changes 0
Metric Value
cc 6
eloc 28
nc 4
nop 4
dl 0
loc 55
ccs 13
cts 22
cp 0.5909
crap 8.4648
rs 8.8497
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
* @author SignpostMarv
4
*/
5
declare(strict_types=1);
6
7
namespace SignpostMarv\DaftObject\SchemaOrg;
8
9
use BadMethodCallException;
10
use InvalidArgumentException;
11
use SignpostMarv\DaftObject\AbstractArrayBackedDaftObject;
12
use SignpostMarv\DaftObject\DaftJson;
13
use SignpostMarv\DaftObject\DaftObjectHasPropertiesWithMultiTypedArraysOfUniqueValues;
14
use SignpostMarv\DaftObject\JsonTypeUtilities;
15
use SignpostMarv\DaftObject\SchemaOrg\CreativeWork\MediaObject\ImageObject;
16
use SignpostMarv\DaftObject\SchemaOrg\DataTypes\Date;
17
use SignpostMarv\DaftObject\SchemaOrg\DataTypes\DateTime;
18
use SignpostMarv\DaftObject\SchemaOrg\Intangible\StructuredValue\ContactPoint;
19
use SignpostMarv\DaftObject\SchemaOrg\Intangible\StructuredValue\PropertyValue;
20
use SignpostMarv\DaftObject\TypeUtilities;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, SignpostMarv\DaftObject\SchemaOrg\TypeUtilities. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

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

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

757
        /** @scrutinizer ignore-unused */ string ...$implementation

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
758
    ) : void {
759
        $this->NudgePropertyWithUniqueValues($property, $method, $value);
760
    }
761
762
    /**
763
    * @param array<int, string|Thing|DataTypes\DataType> $value
764
    *
765
    * @psalm-param class-string<Thing>|class-string<DataTypes\DataType> ...$implementation
766
    */
767 1
    protected function NudgePropertyWithUniqueTrimmedStringsOrThings(
768
        string $property,
769
        string $method,
770
        array $value,
771
        string ...$implementation
0 ignored issues
show
Unused Code introduced by
The parameter $implementation is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

771
        /** @scrutinizer ignore-unused */ string ...$implementation

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
772
    ) : void {
773 1
        $initialCount = count($value);
774
775
        /**
776
        * @var array<int, string|Thing|DataTypes\DataType>
777
        */
778 1
        $value = array_values(array_filter(
779 1
            array_map(
780
                /**
781
                * @param string|Thing|DataTypes\DataType $val
782
                *
783
                * @return string|Thing|DataTypes\DataType
784
                */
785
                function ($val) {
786
                    return is_string($val) ? trim($val) : $val;
787 1
                },
788 1
                $value
789
            ),
790
            /**
791
            * @param string|Thing|DataTypes\DataType $maybe
792
            */
793
            function ($maybe) : bool {
794
                return '' !== $maybe;
795 1
            }
796
        ));
797
798 1
        if (count($value) !== $initialCount) {
799
            throw new InvalidArgumentException(
800
                'Arguments passed to ' .
801
                __METHOD__ .
802
                ' must be strings with no trailing whitespace or instances of ' .
803
                Thing::class
804
            );
805
        }
806
807 1
        $this->NudgePropertyWithUniqueValues($property, $method, $value);
808 1
    }
809
810
    /**
811
    * @param array<int, int|float|string|Thing|DataTypes\DataType> $value
812
    *
813
    * @psalm-param class-string<Thing>|class-string<DataTypes\DataType> ...$implementation
814
    */
815
    protected function NudgePropertyWithUniqueNumericsOrThings(
816
        string $property,
817
        string $method,
818
        array $value,
819
        string ...$implementation
0 ignored issues
show
Unused Code introduced by
The parameter $implementation is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

819
        /** @scrutinizer ignore-unused */ string ...$implementation

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
820
    ) : void {
821
        $initialCount = count($value);
822
823
        /**
824
        * @var array<int, string|Thing|DataTypes\DataType>
825
        */
826
        $value = array_values(
827
            array_map(
828
                /**
829
                * @param string|int|float|Thing|DataTypes\DataType $val
830
                *
831
                * @return int|float|Thing|DataTypes\DataType
832
                */
833
                function ($val) {
834
                    return
835
                        is_string($val)
836
                            ? (
837
                                ctype_digit($val)
838
                                    ? (int) $val
839
                                    : (float) $val
840
                            )
841
                            : $val;
842
                },
843
                $value
844
            )
845
        );
846
847
        if (count($value) !== $initialCount) {
848
            throw new InvalidArgumentException(
849
                'Arguments passed to ' .
850
                __METHOD__ .
851
                ' must be numerics or instances of ' .
852
                Thing::class
853
            );
854
        }
855
856
        $this->NudgePropertyWithUniqueValues($property, $method, $value, SORT_NUMERIC);
857
    }
858
859
    /**
860
    * @param array<int, string> $value
861
    */
862 1
    protected function NudgePropertyWithUniqueTrimmedStringsMightNotBeString(
863
        string $property,
864
        string $method,
865
        array $value
866
    ) : void {
867 1
        $initialCount = count($value);
868
869
        /**
870
        * @var array<int, string>
871
        */
872 1
        $value = array_filter($value, 'is_string');
873
874 1
        if (count($value) !== $initialCount) {
875
            throw new InvalidArgumentException(
876
                'Argument 1 passed to ' .
877
                $method .
878
                ' must be an array of strings!'
879
            );
880
        }
881
882 1
        $this->NudgePropertyWithUniqueTrimmedStrings($property, $method, ...$value);
883 1
    }
884
885
    /**
886
    * @param array<int, int|float|string> $value
887
    */
888
    protected function NudgePropertyWithUniqueTrimmedStringsNumericsMightNotBeStringsOrNumerics(
889
        string $property,
890
        string $method,
891
        array $value
892
    ) : void {
893
        $initialCount = count($value);
894
895
        /**
896
        * @var array<int, string|float|int>
897
        */
898
        $value = array_filter(
899
            $value,
900
            /**
901
            * @param mixed $maybe
902
            */
903
            function ($maybe) : bool {
904
                return is_string($maybe) || is_numeric($maybe);
905
            }
906
        );
907
908
        if (count($value) !== $initialCount) {
909
            throw new InvalidArgumentException(
910
                'Argument 1 passed to ' .
911
                $method .
912
                ' must be an array of numerics!'
913
            );
914
        }
915
916
        /**
917
        * @var array<int, string|int|float>
918
        */
919
        $value = array_unique(
920
            array_map(
921
                /**
922
                * @param string|float|int $val
923
                *
924
                * @return string|float|int
925
                */
926
                function ($val) {
927
                    return
928
                        is_string($val)
929
                            ? (
930
                                ctype_digit($val)
931
                                    ? (int) $val
932
                                    : (
933
                                        is_numeric($val)
934
                                            ? (float) $val
935
                                            : trim($val)
936
                                    )
937
                            )
938
                            : $val;
939
                },
940
                $value
941
            ),
942
            SORT_NUMERIC
943
        );
944
945
        $this->NudgePropertyWithUniqueValues($property, $method, $value);
946
    }
947
948 1
    protected function NudgePropertyWithUniqueTrimmedStrings(
949
        string $property,
950
        string $method,
951
        string ...$value
952
    ) : void {
953 1
        $initialCount = count($value);
954
        $value = array_filter(array_map('trim', $value), function (string $maybe) : bool {
955
            return '' !== $maybe;
956 1
        });
957
958 1
        if ($initialCount !== count($value)) {
959
            throw new InvalidArgumentException(
960
                'Arguments passed to ' .
961
                $method .
962
                ' must not have trailing whitespace!'
963
            );
964
        }
965
966 1
        $this->NudgePropertyWithUniqueValues($property, $method, $value);
967 1
    }
968
969
    /**
970
    * @param array<int, int> $value
971
    */
972
    protected function NudgePropertyWithUniqueIntegers(
973
        string $property,
974
        string $method,
975
        array $value
976
    ) : void {
977
        $this->NudgePropertyWithUniqueValues($property, $method, $value);
978
    }
979
980
    /**
981
    * @param array<int, int|float|string> $value
982
    */
983 3
    protected function NudgePropertyWithUniqueIntegersOrFloats(
984
        string $property,
985
        string $method,
986
        array $value
987
    ) : void {
988 3
        $initialCount = count($value);
989
990
        /**
991
        * @var array<int, int|float>
992
        */
993 3
        $value = array_map(
994
            /**
995
            * @param int|float|string $val
996
            *
997
            * @return int|float
998
            */
999
            function ($val) {
1000
                return
1001 3
                    (is_int($val) || is_float($val))
1002 3
                        ? $val
1003
                        : (
1004
                            ctype_digit($val)
1005
                                ? (int) $val
1006 3
                                : (float) $val
1007
                        );
1008 3
            },
1009 3
            array_filter($value, 'is_numeric')
1010
        );
1011
1012 3
        if (count($value) !== $initialCount) {
1013
            throw new InvalidArgumentException(
1014
                'Argument 1 passed to ' .
1015
                $method .
1016
                ' must be a numeric list!'
1017
            );
1018
        }
1019
1020 3
        $this->NudgePropertyWithUniqueValues($property, $method, $value);
1021 3
    }
1022
1023
    /**
1024
    * @param string|int|bool $maybe
1025
    *
1026
    * @psalm-param 'true'|'false'|'0'|'1'|0|1|bool $maybe
1027
    *
1028
    * @return string|int|bool
1029
    *
1030
    * @psalm-return 'true'|'false'|'0'|'1'|0|1|bool
1031
    */
1032
    protected function MapMaybeBoolean($maybe)
1033
    {
1034
        if (is_string($maybe)) {
1035
            $str = trim(mb_strtolower($maybe));
1036
1037
            if ('true' === $str || 'false' === $str) {
1038
                return 'true' === $str;
1039
            } elseif ('0' === $str || '1' === $str) {
1040
                return '1' === $str;
1041
            }
1042
        } elseif (is_int($maybe)) {
1043
            if (0 === $maybe || 1 === $maybe) {
1044
                return 1 === $maybe;
1045
            }
1046
        }
1047
1048
        return $maybe;
1049
    }
1050
1051
    /**
1052
    * @param array<int, bool> $value
1053
    */
1054
    protected function NudgePropertyWithUniqueBooleans(
1055
        string $property,
1056
        string $method,
1057
        array $value
1058
    ) : void {
1059
        $this->NudgePropertyWithUniqueValues($property, $method, $value);
1060
    }
1061
1062
    /**
1063
    * @param array<int, int|string> $value
1064
    */
1065
    protected function NudgePropertWithUniqueIntegersOrTrimmedStrings(
1066
        string $property,
1067
        string $method,
1068
        array $value
1069
    ) : void {
1070
        $initialCount = count($value);
1071
1072
        $value = array_map(
1073
            /**
1074
            * @param int|string $val
1075
            *
1076
            * @return int|string
1077
            */
1078
            function ($val) {
1079
                return is_string($val) ? trim($val) : $val;
1080
            },
1081
            array_filter(
1082
                $value,
1083
                /**
1084
                * @param mixed $maybe
1085
                */
1086
                function ($maybe) : bool {
1087
                    return is_string($maybe) || is_int($maybe);
1088
                }
1089
            )
1090
        );
1091
1092
        if (count($value) !== $initialCount) {
1093
            throw new InvalidArgumentException(
1094
                'Argument 1 passed to ' .
1095
                $method .
1096
                ' must be a list of integers & strings!'
1097
            );
1098
        }
1099
1100
        $this->NudgePropertyWithUniqueValues($property, $method, $value);
1101
    }
1102
1103
    /**
1104
    * @param array<int, scalar|array|object|null> $value
1105
    */
1106 3
    protected function NudgePropertyWithUniqueValues(
1107
        string $property,
1108
        string $method,
1109
        array $value,
1110
        int $sort_flags = SORT_REGULAR
1111
    ) : void {
1112 3
        $initialCount = count($value);
1113
1114 3
        $value = array_values(array_unique($value, $sort_flags));
1115
1116 3
        if ($initialCount !== count($value)) {
1117
            throw new InvalidArgumentException(
1118
                'Arguments passed to ' .
1119
                $method .
1120
                ' must be unique!'
1121
            );
1122
        }
1123
1124 3
        $this->NudgePropertyValue($property, $value);
1125 3
    }
1126
1127
    /**
1128
    * @param array<int, Date> $value
1129
    */
1130
    protected function NudgePropertyWithUniqueDates(
1131
        string $property,
1132
        string $method,
1133
        array $value
1134
    ) : void {
1135
        $this->NudgePropertyWithUniqueValuesOfThings($property, $method, $value, Date::class);
1136
    }
1137
1138
    /**
1139
    * @param array<int, DateTime> $value
1140
    */
1141
    protected function NudgePropertyWithUniqueDateTimes(
1142
        string $property,
1143
        string $method,
1144
        array $value
1145
    ) : void {
1146
        $this->NudgePropertyWithUniqueValuesOfThings($property, $method, $value, DateTime::class);
1147
    }
1148
1149
    /**
1150
    * @param array<int, Date|DateTime> $value
1151
    */
1152
    protected function NudgePropertyWithUniqueDatesOrDateTimes(
1153
        string $property,
1154
        string $method,
1155
        array $value
1156
    ) : void {
1157
        $this->NudgePropertyWithUniqueValuesOfThings(
1158
            $property,
1159
            $method,
1160
            $value,
1161
            Date::class,
1162
            DateTime::class
1163
        );
1164
    }
1165
1166
    /**
1167
    * @param array<int, Person> $value
1168
    */
1169
    protected function NudgePropertyWithUniquePersons(
1170
        string $property,
1171
        string $method,
1172
        array $value
1173
    ) : void {
1174
        $this->NudgePropertyWithUniqueValuesOfThings(
1175
            $property,
1176
            $method,
1177
            $value,
1178
            Person::class
1179
        );
1180
    }
1181
1182
    /**
1183
    * @param array<int, Organization|Person> $value
1184
    */
1185
    protected function NudgePropertyWithUniqueOrganizationsOrPersons(
1186
        string $property,
1187
        string $method,
1188
        array $value
1189
    ) : void {
1190
        $this->NudgePropertyWithUniqueValuesOfThings(
1191
            $property,
1192
            $method,
1193
            $value,
1194
            Organization::class,
1195
            Person::class
1196
        );
1197
    }
1198
1199
    /**
1200
    * @param array<int, Organization> $value
1201
    */
1202
    protected function NudgePropertyWithUniqueOrganizations(
1203
        string $property,
1204
        string $method,
1205
        array $value
1206
    ) : void {
1207
        $this->NudgePropertyWithUniqueValuesOfThings(
1208
            $property,
1209
            $method,
1210
            $value,
1211
            Organization::class
1212
        );
1213
    }
1214
1215
    /**
1216
    * @param array<int, Offer> $value
1217
    */
1218
    protected function NudgePropertyWithUniqueOffers(
1219
        string $property,
1220
        string $method,
1221
        array $value
1222
    ) : void {
1223
        $this->NudgePropertyWithUniqueValuesOfThings(
1224
            $property,
1225
            $method,
1226
            $value,
1227
            Offer::class
1228
        );
1229
    }
1230
1231
    /**
1232
    * @param array<int, Event> $value
1233
    */
1234
    protected function NudgePropertyWithUniqueEvents(
1235
        string $property,
1236
        string $method,
1237
        array $value
1238
    ) : void {
1239
        $this->NudgePropertyWithUniqueValuesOfThings(
1240
            $property,
1241
            $method,
1242
            $value,
1243
            Event::class
1244
        );
1245
    }
1246
1247
    /**
1248
    * @param array<int, Place> $value
1249
    */
1250
    protected function NudgePropertyValueWithUniquePlaces(
1251
        string $property,
1252
        string $method,
0 ignored issues
show
Unused Code introduced by
The parameter $method is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1252
        /** @scrutinizer ignore-unused */ string $method,

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1253
        array $value
1254
    ) : void {
1255
        $this->NudgePropertyWithUniqueValuesOfThings(
1256
            $property,
1257
            __METHOD__,
1258
            $value,
1259
            Place::class
1260
        );
1261
    }
1262
1263
    /**
1264
    * @param array<int, ContactPoint|Place> $value
1265
    */
1266
    protected function NudgePropertyValueWithUniqueContactPointsOrPlaces(
1267
        string $property,
1268
        string $method,
0 ignored issues
show
Unused Code introduced by
The parameter $method is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

1268
        /** @scrutinizer ignore-unused */ string $method,

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1269
        array $value
1270
    ) : void {
1271
        $this->NudgePropertyWithUniqueValuesOfThings(
1272
            $property,
1273
            __METHOD__,
1274
            $value,
1275
            ContactPoint::class,
1276
            Place::class
1277
        );
1278
    }
1279
1280
    /**
1281
    * @param array<int, Thing|DataTypes\DataType> $value
1282
    *
1283
    * @psalm-param class-string<Thing>|class-string<DataTypes\DataType> ...$validThings
1284
    */
1285 3
    protected function NudgePropertyWithUniqueValuesOfThings(
1286
        string $property,
1287
        string $method,
1288
        array $value,
1289
        string ...$validThings
1290
    ) : void {
1291 3
        $initialCount = count($validThings);
1292
1293 3
        if (0 === $initialCount) {
1294
            throw new BadMethodCallException(
1295
                'Argument 4 of ' .
1296
                __METHOD__ .
1297
                ' is required!'
1298
            );
1299 3
        } elseif (count($validThings) !== $initialCount) {
1300
            throw new InvalidArgumentException(
1301
                'Arguments 4+ passed to ' .
1302
                __METHOD__ .
1303
                ' must be implementations of ' .
1304
                Thing::class .
1305
                '!'
1306
            );
1307
        }
1308
1309 3
        $initialCount = count($value);
1310
1311
        /**
1312
        * @var array<int, Thing|DataTypes\DataType>
1313
        */
1314 3
        $value = array_filter(
1315 3
            $value,
1316
            /**
1317
            * @param Thing|DataTypes\DataType $maybe
1318
            */
1319
            function ($maybe) use ($validThings) : bool {
1320 2
                foreach ($validThings as $thing) {
1321 2
                    if (is_a($maybe, $thing, true)) {
1322 2
                        return true;
1323
                    }
1324
                }
1325
1326
                return false;
1327 3
            }
1328
        );
1329
1330 3
        if (count($value) !== $initialCount) {
1331
            throw new InvalidArgumentException(
1332
                'Argument 1 passed to ' .
1333
                $method .
1334
                ' must be an array containing any combination of ' .
1335
                implode(', ', $validThings)
1336
            );
1337
        }
1338
1339 3
        $this->NudgePropertyWithUniqueValues($property, $method, $value);
1340 3
    }
1341
}
1342