GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Test Failed
Push — master ( 3bc013...b16dc9 )
by SignpostMarv
02:15
created

MaybeThrowIfValueDoesNotMatchMultiTypedArrayValueArray()   C

Complexity

Conditions 12
Paths 6

Size

Total Lines 74
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 12

Importance

Changes 0
Metric Value
cc 12
eloc 35
nc 6
nop 4
dl 0
loc 74
ccs 15
cts 15
cp 1
crap 12
rs 6.9666
c 0
b 0
f 0

How to fix   Long Method    Complexity   

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;
8
9
use InvalidArgumentException;
10
use ReflectionException;
11
use ReflectionMethod;
12
13
class TypeUtilities
14
{
15
    const SUPPORTED_INVALID_LEADING_CHARACTERS = [
16
        '@',
17
    ];
18
19
    /**
20
    * @var array<string, array<string, bool>>
21
    */
22
    private static $Getters = [];
23
24
    /**
25
    * @var array<string, array<int, string>>
26
    */
27
    private static $publicSetters = [];
28 118
29
    public static function DaftObjectPublicGetters(string $class) : array
30 118
    {
31
        static::CachePublicGettersAndSetters($class);
32 118
33
        return array_keys(array_filter(self::$Getters[$class]));
34
    }
35 2
36
    public static function DaftObjectPublicOrProtectedGetters(string $class) : array
37 2
    {
38
        static::CachePublicGettersAndSetters($class);
39 2
40
        return array_keys(self::$Getters[$class]);
41
    }
42 186
43
    public static function DaftObjectPublicSetters(string $class) : array
44 186
    {
45
        static::CachePublicGettersAndSetters($class);
46 186
47
        return self::$publicSetters[$class];
48
    }
49 32
50
    public static function HasMethod(
51
        string $class,
52
        string $property,
53
        bool $SetNotGet,
54
        bool $pub = true
55 32
    ) : bool {
56
        $method = static::MethodNameFromProperty($property, $SetNotGet);
57
58 32
        try {
59
            $ref = new ReflectionMethod($class, $method);
60 32
61 8
            return ($pub ? $ref->isPublic() : $ref->isProtected()) && false === $ref->isStatic();
62 8
        } catch (ReflectionException $e) {
63
            return false;
64
        }
65
    }
66 262
67
    public static function MethodNameFromProperty(string $prop, bool $SetNotGet = false) : string
68 262
    {
69 2
        if (in_array(mb_substr($prop, 0, 1), self::SUPPORTED_INVALID_LEADING_CHARACTERS, true)) {
70
            return ($SetNotGet ? 'Alter' : 'Obtain') . ucfirst(mb_substr($prop, 1));
71
        }
72 260
73
        return ($SetNotGet ? 'Set' : 'Get') . ucfirst($prop);
74
    }
75
76
    /**
77
    * Checks if a type correctly defines it's own id.
78
    *
79
    * @throws ClassDoesNotImplementClassException if $class is not an implementation of DefinesOwnIdPropertiesInterface
80
    * @throws ClassMethodReturnHasZeroArrayCountException if $class::DaftObjectIdProperties() does not contain at least one property
81
    * @throws ClassMethodReturnIsNotArrayOfStringsException if $class::DaftObjectIdProperties() is not string[]
82
    * @throws UndefinedPropertyException if an id property is not in $class::DaftObjectIdProperties()
83 528
    */
84
    public static function CheckTypeDefinesOwnIdProperties(
85
        string $class,
86
        bool $throwIfNotImplementation = false
87 528
    ) : void {
88 314
        if (is_a($class, DefinesOwnIdPropertiesInterface::class, true)) {
89 220
            self::CheckTypeDefinesOwnIdPropertiesIsImplementation($class);
90 2
        } elseif ($throwIfNotImplementation) {
91 2
            throw new ClassDoesNotImplementClassException(
92 2
                $class,
93
                DefinesOwnIdPropertiesInterface::class
94
            );
95 524
        }
96
    }
97 236
98
    /**
99 236
    * @param mixed $value
100 32
    *
101 32
    * @return array<int, mixed> filtered $value
102
    */
103 32
    public static function MaybeThrowIfValueDoesNotMatchMultiTypedArray(
104 16
        bool $autoTrimStrings,
0 ignored issues
show
Unused Code introduced by
The parameter $autoTrimStrings 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

104
        /** @scrutinizer ignore-unused */ bool $autoTrimStrings,

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...
105
        bool $throwIfNotUnique,
0 ignored issues
show
Unused Code introduced by
The parameter $throwIfNotUnique 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

105
        /** @scrutinizer ignore-unused */ bool $throwIfNotUnique,

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...
106
        $value,
107 32
        string ...$types
0 ignored issues
show
Unused Code introduced by
The parameter $types 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

107
        /** @scrutinizer ignore-unused */ string ...$types

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...
108
    ) : array {
109 236
        if ( ! is_array($value)) {
110
            throw new InvalidArgumentException(
111
                'Argument 3 passed to ' .
112
                __METHOD__ .
113
                ' must be an array, ' .
114 32
                (is_object($value) ? get_class($value) : gettype($value)) .
115
                ' given!'
116
            );
117
        }
0 ignored issues
show
Bug Best Practice introduced by
The function implicitly returns null when the if condition on line 109 is false. This is incompatible with the type-hinted return array. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
118
    }
119 32
120
    /**
121 32
    * @param mixed $value
122 32
    *
123 28
    * @return array<int, mixed> filtered $value
124 6
    */
125 2
    protected static function MaybeThrowIfValueDoesNotMatchMultiTypedArrayValueArray(
126
        bool $autoTrimStrings,
127
        bool $throwIfNotUnique,
128 32
        array $value,
129 32
        string ...$types
130
    ) : array {
131
        $initialCount = count($value);
132 32
        $value = array_filter($value, 'is_int', ARRAY_FILTER_USE_KEY);
133
134
        if (count($value) !== $initialCount) {
135
            throw new InvalidArgumentException(
136
                'Argument 3 passed to ' .
137 314
                __METHOD__ .
138
                ' must be array<int, mixed>'
139
            );
140 314
        }
141
142 314
        $initialCount = count($value);
143 2
144 2
        $value = array_filter(
145 2
            $value,
146
            /**
147 312
            * @param mixed $maybe
148 2
            */
149 2
            function ($maybe) use ($types) : bool {
150 2
                if (is_object($maybe)) {
151
                    foreach ($types as $maybeType) {
152
                        if (is_a($maybe, $maybeType)) {
153 310
                            return true;
154
                        }
155
                    }
156
157
                    return false;
158
                }
159
160
                return in_array(gettype($maybe), $types, true);
161
            }
162
        );
163
164
        if (count($value) !== $initialCount) {
165
            throw new InvalidArgumentException(
166
                'Argument 3 passed to ' .
167
                __METHOD__ .
168
                ' contained values that did not match the provided types!'
169
            );
170
        }
171
172
        $initialCount = count($value);
173
174
        if (in_array('string', $types, true) && $autoTrimStrings && $initialCount > 0) {
175
            $value = array_map(
176
                /**
177
                * @param mixed $maybe
178
                *
179
                * @return mixed
180
                */
181
                function ($maybe) {
182
                    return is_string($maybe) ? trim($maybe) : $maybe;
183
                },
184
                $value
185
            );
186
        }
187
188
        $value = array_unique($value, SORT_REGULAR);
189
190
        if ($throwIfNotUnique && count($value) !== $initialCount) {
191
            throw new InvalidArgumentException(
192
                'Argument 3 passed to ' .
193
                __METHOD__ .
194
                ' contained non-unique values!'
195
            );
196
        }
197
198
        return array_values($value);
199
    }
200
201
    final protected static function CachePublicGettersAndSetters(string $class) : void
202
    {
203
        if (false === isset(self::$Getters[$class])) {
204
            self::$Getters[$class] = [];
205
            self::$publicSetters[$class] = [];
206
207
            if (is_a($class, DefinesOwnIdPropertiesInterface::class, true)) {
208
                self::$Getters[$class]['id'] = true;
209
            }
210
211
            self::CachePublicGettersAndSettersProperties($class);
212
        }
213
    }
214
215
    /**
216
    * @psalm-suppress InvalidStringClass
217
    */
218
    final protected static function CachePublicGettersAndSettersProperties(string $class) : void
219
    {
220
        /**
221
        * @var string[]
222
        */
223
        $props = $class::DaftObjectProperties();
224
225
        foreach ($props as $prop) {
226
            if (static::HasMethod($class, $prop, false)) {
227
                self::$Getters[$class][$prop] = true;
228
            } elseif (static::HasMethod($class, $prop, false, false)) {
229
                self::$Getters[$class][$prop] = false;
230
            }
231
232
            if (static::HasMethod($class, $prop, true)) {
233
                self::$publicSetters[$class][] = $prop;
234
            }
235
        }
236
    }
237
238
    /**
239
    * @psalm-suppress InvalidStringClass
240
    */
241
    final protected static function CheckTypeDefinesOwnIdPropertiesIsImplementation(
242
        string $class
243
    ) : void {
244
        $properties = (array) $class::DaftObjectIdProperties();
245
246
        if (count($properties) < 1) {
247
            throw new ClassMethodReturnHasZeroArrayCountException(
248
                $class,
249
                'DaftObjectIdProperties'
250
            );
251
        } elseif (count($properties) !== count(array_filter($properties, 'is_string'))) {
252
            throw new ClassMethodReturnIsNotArrayOfStringsException(
253
                $class,
254
                'DaftObjectIdProperties'
255
            );
256
        }
257
    }
258
}
259