GitHub Access Token became invalid

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

TypeUtilities::MaybeRemapStringsToTrimmedStrings()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 20
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 6
nc 2
nop 3
dl 0
loc 20
ccs 7
cts 7
cp 1
crap 4
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
* @author SignpostMarv
4
*/
5
declare(strict_types=1);
6
7
namespace SignpostMarv\DaftObject;
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
29 118
    public static function DaftObjectPublicGetters(string $class) : array
30
    {
31 118
        static::CachePublicGettersAndSetters($class);
32
33 118
        return array_keys(array_filter(self::$Getters[$class]));
34
    }
35
36 2
    public static function DaftObjectPublicOrProtectedGetters(string $class) : array
37
    {
38 2
        static::CachePublicGettersAndSetters($class);
39
40 2
        return array_keys(self::$Getters[$class]);
41
    }
42
43 186
    public static function DaftObjectPublicSetters(string $class) : array
44
    {
45 186
        static::CachePublicGettersAndSetters($class);
46
47 186
        return self::$publicSetters[$class];
48
    }
49
50 32
    public static function HasMethod(
51
        string $class,
52
        string $property,
53
        bool $SetNotGet,
54
        bool $pub = true
55
    ) : bool {
56 32
        $method = static::MethodNameFromProperty($property, $SetNotGet);
57
58
        try {
59 32
            $ref = new ReflectionMethod($class, $method);
60
61 32
            return ($pub ? $ref->isPublic() : $ref->isProtected()) && false === $ref->isStatic();
62 8
        } catch (ReflectionException $e) {
63 8
            return false;
64
        }
65
    }
66
67 262
    public static function MethodNameFromProperty(string $prop, bool $SetNotGet = false) : string
68
    {
69 262
        if (in_array(mb_substr($prop, 0, 1), self::SUPPORTED_INVALID_LEADING_CHARACTERS, true)) {
70 2
            return ($SetNotGet ? 'Alter' : 'Obtain') . ucfirst(mb_substr($prop, 1));
71
        }
72
73 260
        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
    */
84 528
    public static function CheckTypeDefinesOwnIdProperties(
85
        string $class,
86
        bool $throwIfNotImplementation = false
87
    ) : void {
88 528
        if (is_a($class, DefinesOwnIdPropertiesInterface::class, true)) {
89 314
            self::CheckTypeDefinesOwnIdPropertiesIsImplementation($class);
90 220
        } elseif ($throwIfNotImplementation) {
91 2
            throw new ClassDoesNotImplementClassException(
92 2
                $class,
93 2
                DefinesOwnIdPropertiesInterface::class
94
            );
95
        }
96 524
    }
97
98
    /**
99
    * @param mixed $value
100
    *
101
    * @return array<int, mixed> filtered $value
102
    */
103 14
    public static function MaybeThrowIfValueDoesNotMatchMultiTypedArray(
104
        bool $autoTrimStrings,
105
        bool $throwIfNotUnique,
106
        $value,
107
        string ...$types
108
    ) : array {
109 14
        if ( ! is_array($value)) {
110 2
            throw new InvalidArgumentException(
111
                'Argument 3 passed to ' .
112
                __METHOD__ .
113
                ' must be an array, ' .
114 2
                (is_object($value) ? get_class($value) : gettype($value)) .
115 2
                ' given!'
116
            );
117
        }
118
119 12
        return static::MaybeThrowIfValueDoesNotMatchMultiTypedArrayValueArray(
120 12
            $autoTrimStrings,
121 12
            $throwIfNotUnique,
122 12
            $value,
123 9
            ...$types
124
        );
125
    }
126
127
    /**
128
    * @return array<int, mixed> filtered $value
129
    */
130 12
    protected static function MaybeThrowIfNotArrayIntKeys(array $value) : array
131
    {
132 12
        $initialCount = count($value);
133
134
        /**
135
        * @var array<int, mixed>
136
        */
137 12
        $value = array_filter($value, 'is_int', ARRAY_FILTER_USE_KEY);
138
139 12
        if (count($value) !== $initialCount) {
140 2
            throw new InvalidArgumentException(
141
                'Argument 3 passed to ' .
142
                __METHOD__ .
143 2
                ' must be array<int, mixed>'
144
            );
145
        }
146
147 10
        return $value;
148
    }
149
150
    /**
151
    * @param array<int, mixed> $value
152
    *
153
    * @return array<int, mixed> filtered $value
154
    */
155 10
    protected static function MaybeThrowIfValueArrayDoesNotMatchTypes(
156
        array $value,
157
        string ...$types
158
    ) : array {
159 10
        $initialCount = count($value);
160
161 10
        $value = array_filter(
162 10
            $value,
163
            /**
164
            * @param mixed $maybe
165
            */
166
            function ($maybe) use ($types) : bool {
167 10
                if (is_object($maybe)) {
168 8
                    foreach ($types as $maybeType) {
169 8
                        if (is_a($maybe, $maybeType)) {
170 8
                            return true;
171
                        }
172
                    }
173
174 2
                    return false;
175
                }
176
177 4
                return in_array(gettype($maybe), $types, true);
178 10
            }
179
        );
180
181 10
        if (count($value) !== $initialCount) {
182 2
            throw new InvalidArgumentException(
183
                'Argument 3 passed to ' .
184
                __METHOD__ .
185 2
                ' contained values that did not match the provided types!'
186
            );
187
        }
188
189 8
        return $value;
190
    }
191
192
    /**
193
    * @param array<int, mixed> $value
194
    *
195
    * @return array<int, mixed>
196
    */
197 8
    protected static function MaybeRemapStringsToTrimmedStrings(
198
        array $value,
199
        bool $autoTrimStrings,
200
        string ...$types
201
    ) : array {
202 8
        if (in_array('string', $types, true) && $autoTrimStrings) {
203 2
            $value = array_map(
204
                /**
205
                * @param mixed $maybe
206
                *
207
                * @return mixed
208
                */
209
                function ($maybe) {
210 2
                    return is_string($maybe) ? trim($maybe) : $maybe;
211 2
                },
212 2
                $value
213
            );
214
        }
215
216 8
        return $value;
217
    }
218
219
    /**
220
    * @return array<int, mixed> filtered $value
221
    */
222 12
    protected static function MaybeThrowIfValueDoesNotMatchMultiTypedArrayValueArray(
223
        bool $autoTrimStrings,
224
        bool $throwIfNotUnique,
225
        array $value,
226
        string ...$types
227
    ) : array {
228 12
        $value = static::MaybeThrowIfNotArrayIntKeys($value);
229 10
        $value = static::MaybeThrowIfValueArrayDoesNotMatchTypes($value, ...$types);
230 8
        $value = static::MaybeRemapStringsToTrimmedStrings($value, $autoTrimStrings, ...$types);
231
232 8
        $initialCount = count($value);
233
234 8
        $value = array_unique($value, SORT_REGULAR);
235
236 8
        if ($throwIfNotUnique && count($value) !== $initialCount) {
237 2
            throw new InvalidArgumentException(
238
                'Argument 3 passed to ' .
239
                __METHOD__ .
240 2
                ' contained non-unique values!'
241
            );
242
        }
243
244 6
        return array_values($value);
245
    }
246
247 236
    final protected static function CachePublicGettersAndSetters(string $class) : void
248
    {
249 236
        if (false === isset(self::$Getters[$class])) {
250 32
            self::$Getters[$class] = [];
251 32
            self::$publicSetters[$class] = [];
252
253 32
            if (is_a($class, DefinesOwnIdPropertiesInterface::class, true)) {
254 16
                self::$Getters[$class]['id'] = true;
255
            }
256
257 32
            self::CachePublicGettersAndSettersProperties($class);
258
        }
259 236
    }
260
261
    /**
262
    * @psalm-suppress InvalidStringClass
263
    */
264 32
    final protected static function CachePublicGettersAndSettersProperties(string $class) : void
265
    {
266
        /**
267
        * @var string[]
268
        */
269 32
        $props = $class::DaftObjectProperties();
270
271 32
        foreach ($props as $prop) {
272 32
            if (static::HasMethod($class, $prop, false)) {
273 28
                self::$Getters[$class][$prop] = true;
274 6
            } elseif (static::HasMethod($class, $prop, false, false)) {
275 2
                self::$Getters[$class][$prop] = false;
276
            }
277
278 32
            if (static::HasMethod($class, $prop, true)) {
279 32
                self::$publicSetters[$class][] = $prop;
280
            }
281
        }
282 32
    }
283
284
    /**
285
    * @psalm-suppress InvalidStringClass
286
    */
287 314
    final protected static function CheckTypeDefinesOwnIdPropertiesIsImplementation(
288
        string $class
289
    ) : void {
290 314
        $properties = (array) $class::DaftObjectIdProperties();
291
292 314
        if (count($properties) < 1) {
293 2
            throw new ClassMethodReturnHasZeroArrayCountException(
294 2
                $class,
295 2
                'DaftObjectIdProperties'
296
            );
297 312
        } elseif (count($properties) !== count(array_filter($properties, 'is_string'))) {
298 2
            throw new ClassMethodReturnIsNotArrayOfStringsException(
299 2
                $class,
300 2
                'DaftObjectIdProperties'
301
            );
302
        }
303 310
    }
304
}
305