Passed
Push — master ( 76a992...e07d3c )
by SignpostMarv
03:53
created

Thing::NudgePropertyWithUniqueValuesOfThings()   A

Complexity

Conditions 5
Paths 3

Size

Total Lines 52
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 6.0718

Importance

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

742
        /** @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...
743
    ) : void {
744
        $this->NudgePropertyWithUniqueValues($property, $method, $value);
745
    }
746
747
    /**
748
    * @param array<int, string|Thing|DataTypes\DataType> $value
749
    *
750
    * @psalm-param class-string<Thing>|class-string<DataTypes\DataType> ...$implementation
751
    */
752 1
    protected function NudgePropertyWithUniqueTrimmedStringsOrThings(
753
        string $property,
754
        string $method,
755
        array $value,
756
        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

756
        /** @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...
757
    ) : void {
758 1
        $initialCount = count($value);
759
760
        /**
761
        * @var array<int, string|Thing|DataTypes\DataType>
762
        */
763 1
        $value = array_values(array_filter(
764 1
            array_map(
765
                /**
766
                * @param string|Thing|DataTypes\DataType $val
767
                *
768
                * @return string|Thing|DataTypes\DataType
769
                */
770
                function ($val) {
771
                    return is_string($val) ? trim($val) : $val;
772 1
                },
773 1
                $value
774
            ),
775
            /**
776
            * @param string|Thing|DataTypes\DataType $maybe
777
            */
778
            function ($maybe) : bool {
779
                return '' !== $maybe;
780 1
            }
781
        ));
782
783 1
        if (count($value) !== $initialCount) {
784
            throw new InvalidArgumentException(
785
                'Arguments passed to ' .
786
                __METHOD__ .
787
                ' must be strings with no trailing whitespace or instances of ' .
788
                Thing::class
789
            );
790
        }
791
792 1
        $this->NudgePropertyWithUniqueValues($property, $method, $value);
793 1
    }
794
795
    /**
796
    * @param array<int, int|float|string|Thing|DataTypes\DataType> $value
797
    *
798
    * @psalm-param class-string<Thing>|class-string<DataTypes\DataType> ...$implementation
799
    */
800
    protected function NudgePropertyWithUniqueNumericsOrThings(
801
        string $property,
802
        string $method,
803
        array $value,
804
        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

804
        /** @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...
805
    ) : void {
806
        $initialCount = count($value);
807
808
        /**
809
        * @var array<int, string|Thing|DataTypes\DataType>
810
        */
811
        $value = array_values(
812
            array_map(
813
                /**
814
                * @param string|int|float|Thing|DataTypes\DataType $val
815
                *
816
                * @return int|float|Thing|DataTypes\DataType
817
                */
818
                function ($val) {
819
                    return
820
                        is_string($val)
821
                            ? (
822
                                ctype_digit($val)
823
                                    ? (int) $val
824
                                    : (float) $val
825
                            )
826
                            : $val;
827
                },
828
                $value
829
            )
830
        );
831
832
        if (count($value) !== $initialCount) {
833
            throw new InvalidArgumentException(
834
                'Arguments passed to ' .
835
                __METHOD__ .
836
                ' must be numerics or instances of ' .
837
                Thing::class
838
            );
839
        }
840
841
        $this->NudgePropertyWithUniqueValues($property, $method, $value, SORT_NUMERIC);
842
    }
843
844
    /**
845
    * @param array<int, string> $value
846
    */
847 1
    protected function NudgePropertyWithUniqueTrimmedStringsMightNotBeString(
848
        string $property,
849
        string $method,
850
        array $value
851
    ) : void {
852 1
        $initialCount = count($value);
853
854
        $value = array_filter(array_map('trim', $value), function (string $maybe) : bool {
855
            return '' !== $maybe;
856 1
        });
857
858 1
        if ($initialCount !== count($value)) {
859
            throw new InvalidArgumentException(
860
                'Arguments passed to ' .
861
                $method .
862
                ' must not have trailing whitespace!'
863
            );
864
        }
865
866 1
        $this->NudgePropertyWithUniqueValues($property, $method, $value);
867 1
    }
868
869
    /**
870
    * @param array<int, int|float|string> $value
871
    */
872
    protected function NudgePropertyWithUniqueTrimmedStringsNumericsMightNotBeStringsOrNumerics(
873
        string $property,
874
        string $method,
875
        array $value
876
    ) : void {
877
        $initialCount = count($value);
878
879
        /**
880
        * @var array<int, string|float|int>
881
        */
882
        $value = array_filter(
883
            $value,
884
            /**
885
            * @param mixed $maybe
886
            */
887
            function ($maybe) : bool {
888
                return is_string($maybe) || is_numeric($maybe);
889
            }
890
        );
891
892
        if (count($value) !== $initialCount) {
893
            throw new InvalidArgumentException(
894
                'Argument 1 passed to ' .
895
                $method .
896
                ' must be an array of numerics!'
897
            );
898
        }
899
900
        /**
901
        * @var array<int, string|int|float>
902
        */
903
        $value = array_unique(
904
            array_map(
905
                /**
906
                * @param string|float|int $val
907
                *
908
                * @return string|float|int
909
                */
910
                function ($val) {
911
                    return
912
                        is_string($val)
913
                            ? (
914
                                ctype_digit($val)
915
                                    ? (int) $val
916
                                    : (
917
                                        is_numeric($val)
918
                                            ? (float) $val
919
                                            : trim($val)
920
                                    )
921
                            )
922
                            : $val;
923
                },
924
                $value
925
            ),
926
            SORT_NUMERIC
927
        );
928
929
        $this->NudgePropertyWithUniqueValues($property, $method, $value);
930
    }
931
932
    /**
933
    * @param array<int, int> $value
934
    */
935
    protected function NudgePropertyWithUniqueIntegers(
936
        string $property,
937
        string $method,
938
        array $value
939
    ) : void {
940
        $this->NudgePropertyWithUniqueValues($property, $method, $value);
941
    }
942
943
    /**
944
    * @param array<int, int|float|string> $value
945
    */
946 3
    protected function NudgePropertyWithUniqueIntegersOrFloats(
947
        string $property,
948
        string $method,
949
        array $value
950
    ) : void {
951 3
        $initialCount = count($value);
952
953
        /**
954
        * @var array<int, int|float>
955
        */
956 3
        $value = array_map(
957
            /**
958
            * @param int|float|string $val
959
            *
960
            * @return int|float
961
            */
962
            function ($val) {
963
                return
964 3
                    (is_int($val) || is_float($val))
965 3
                        ? $val
966
                        : (
967
                            ctype_digit($val)
968
                                ? (int) $val
969 3
                                : (float) $val
970
                        );
971 3
            },
972 3
            array_filter($value, 'is_numeric')
973
        );
974
975 3
        if (count($value) !== $initialCount) {
976
            throw new InvalidArgumentException(
977
                'Argument 1 passed to ' .
978
                $method .
979
                ' must be a numeric list!'
980
            );
981
        }
982
983 3
        $this->NudgePropertyWithUniqueValues($property, $method, $value);
984 3
    }
985
986
    /**
987
    * @param array<int, bool> $value
988
    */
989
    protected function NudgePropertyWithUniqueBooleans(
990
        string $property,
991
        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

991
        /** @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...
992
        array $value
993
    ) : void {
994
        $replace = [];
995
        if (in_array(true, $value, true)) {
996
            $replace[] = true;
997
        }
998
        if (in_array(false, $value, true)) {
999
            $replace[] = false;
1000
        }
1001
1002
        $this->NudgePropertyValue($property, $replace);
1003
    }
1004
1005
    /**
1006
    * @param array<int, int|string> $value
1007
    */
1008
    protected function NudgePropertWithUniqueIntegersOrTrimmedStrings(
1009
        string $property,
1010
        string $method,
1011
        array $value
1012
    ) : void {
1013
        $initialCount = count($value);
1014
1015
        $value = array_map(
1016
            /**
1017
            * @param int|string $val
1018
            *
1019
            * @return int|string
1020
            */
1021
            function ($val) {
1022
                return is_string($val) ? trim($val) : $val;
1023
            },
1024
            array_filter(
1025
                $value,
1026
                /**
1027
                * @param mixed $maybe
1028
                */
1029
                function ($maybe) : bool {
1030
                    return is_string($maybe) || is_int($maybe);
1031
                }
1032
            )
1033
        );
1034
1035
        if (count($value) !== $initialCount) {
1036
            throw new InvalidArgumentException(
1037
                'Argument 1 passed to ' .
1038
                $method .
1039
                ' must be a list of integers & strings!'
1040
            );
1041
        }
1042
1043
        $this->NudgePropertyWithUniqueValues($property, $method, $value);
1044
    }
1045
1046
    /**
1047
    * @param array<int, scalar|array|object|null> $value
1048
    */
1049 3
    protected function NudgePropertyWithUniqueValues(
1050
        string $property,
1051
        string $method,
1052
        array $value,
1053
        int $sort_flags = SORT_REGULAR
1054
    ) : void {
1055 3
        $initialCount = count($value);
1056
1057 3
        $value = array_values(array_unique($value, $sort_flags));
1058
1059 3
        if ($initialCount !== count($value)) {
1060
            throw new InvalidArgumentException(
1061
                'Arguments passed to ' .
1062
                $method .
1063
                ' must be unique!'
1064
            );
1065
        }
1066
1067 3
        $this->NudgePropertyValue($property, $value);
1068 3
    }
1069
1070
    /**
1071
    * @param array<int, Date> $value
1072
    */
1073
    protected function NudgePropertyWithUniqueDates(
1074
        string $property,
1075
        string $method,
1076
        array $value
1077
    ) : void {
1078
        $this->NudgePropertyWithUniqueValuesOfThings($property, $method, $value, Date::class);
1079
    }
1080
1081
    /**
1082
    * @param array<int, DateTime> $value
1083
    */
1084
    protected function NudgePropertyWithUniqueDateTimes(
1085
        string $property,
1086
        string $method,
1087
        array $value
1088
    ) : void {
1089
        $this->NudgePropertyWithUniqueValuesOfThings($property, $method, $value, DateTime::class);
1090
    }
1091
1092
    /**
1093
    * @param array<int, Date|DateTime> $value
1094
    */
1095
    protected function NudgePropertyWithUniqueDatesOrDateTimes(
1096
        string $property,
1097
        string $method,
1098
        array $value
1099
    ) : void {
1100
        $this->NudgePropertyWithUniqueValuesOfThings(
1101
            $property,
1102
            $method,
1103
            $value,
1104
            Date::class,
1105
            DateTime::class
1106
        );
1107
    }
1108
1109
    /**
1110
    * @param array<int, Person> $value
1111
    */
1112
    protected function NudgePropertyWithUniquePersons(
1113
        string $property,
1114
        string $method,
1115
        array $value
1116
    ) : void {
1117
        $this->NudgePropertyWithUniqueValuesOfThings(
1118
            $property,
1119
            $method,
1120
            $value,
1121
            Person::class
1122
        );
1123
    }
1124
1125
    /**
1126
    * @param array<int, Organization|Person> $value
1127
    */
1128
    protected function NudgePropertyWithUniqueOrganizationsOrPersons(
1129
        string $property,
1130
        string $method,
1131
        array $value
1132
    ) : void {
1133
        $this->NudgePropertyWithUniqueValuesOfThings(
1134
            $property,
1135
            $method,
1136
            $value,
1137
            Organization::class,
1138
            Person::class
1139
        );
1140
    }
1141
1142
    /**
1143
    * @param array<int, Organization> $value
1144
    */
1145
    protected function NudgePropertyWithUniqueOrganizations(
1146
        string $property,
1147
        string $method,
1148
        array $value
1149
    ) : void {
1150
        $this->NudgePropertyWithUniqueValuesOfThings(
1151
            $property,
1152
            $method,
1153
            $value,
1154
            Organization::class
1155
        );
1156
    }
1157
1158
    /**
1159
    * @param array<int, Event> $value
1160
    */
1161
    protected function NudgePropertyWithUniqueEvents(
1162
        string $property,
1163
        string $method,
1164
        array $value
1165
    ) : void {
1166
        $this->NudgePropertyWithUniqueValuesOfThings(
1167
            $property,
1168
            $method,
1169
            $value,
1170
            Event::class
1171
        );
1172
    }
1173
1174
    /**
1175
    * @param array<int, Place> $value
1176
    */
1177
    protected function NudgePropertyValueWithUniquePlaces(
1178
        string $property,
1179
        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

1179
        /** @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...
1180
        array $value
1181
    ) : void {
1182
        $this->NudgePropertyWithUniqueValuesOfThings(
1183
            $property,
1184
            __METHOD__,
1185
            $value,
1186
            Place::class
1187
        );
1188
    }
1189
1190
    /**
1191
    * @param array<int, ContactPoint|Place> $value
1192
    */
1193
    protected function NudgePropertyValueWithUniqueContactPointsOrPlaces(
1194
        string $property,
1195
        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

1195
        /** @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...
1196
        array $value
1197
    ) : void {
1198
        $this->NudgePropertyWithUniqueValuesOfThings(
1199
            $property,
1200
            __METHOD__,
1201
            $value,
1202
            ContactPoint::class,
1203
            Place::class
1204
        );
1205
    }
1206
1207
    /**
1208
    * @param array<int, Thing|DataTypes\DataType> $value
1209
    *
1210
    * @psalm-param class-string<Thing>|class-string<DataTypes\DataType> $validThing
1211
    * @psalm-param class-string<Thing>|class-string<DataTypes\DataType> ...$validThings
1212
    */
1213 3
    protected function NudgePropertyWithUniqueValuesOfThings(
1214
        string $property,
1215
        string $method,
1216
        array $value,
1217
        string $validThing,
1218
        string ...$validThings
1219
    ) : void {
1220 3
        array_unshift($validThings, $validThing);
1221
1222 3
        $initialCount = count($validThings);
1223
1224 3
        if (count($validThings) !== $initialCount) {
1225
            throw new InvalidArgumentException(
1226
                'Arguments 4+ passed to ' .
1227
                __METHOD__ .
1228
                ' must be implementations of ' .
1229
                Thing::class .
1230
                '!'
1231
            );
1232
        }
1233
1234 3
        $initialCount = count($value);
1235
1236
        /**
1237
        * @var array<int, Thing|DataTypes\DataType>
1238
        */
1239 3
        $value = array_filter(
1240 3
            $value,
1241
            /**
1242
            * @param Thing|DataTypes\DataType $maybe
1243
            */
1244
            function ($maybe) use ($validThings) : bool {
1245 2
                foreach ($validThings as $thing) {
1246 2
                    if (is_a($maybe, $thing, true)) {
1247 2
                        return true;
1248
                    }
1249
                }
1250
1251
                return false;
1252 3
            }
1253
        );
1254
1255 3
        if (count($value) !== $initialCount) {
1256
            throw new InvalidArgumentException(
1257
                'Argument 1 passed to ' .
1258
                $method .
1259
                ' must be an array containing any combination of ' .
1260
                implode(', ', $validThings)
1261
            );
1262
        }
1263
1264 3
        $this->NudgePropertyWithUniqueValues($property, $method, $value);
1265 3
    }
1266
}
1267