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 ( 6b2e87...92dcf0 )
by SignpostMarv
02:33
created

TypeUtilities::CachePublicGettersAndSetters()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 6
nc 3
nop 1
dl 0
loc 11
rs 10
c 0
b 0
f 0
ccs 7
cts 7
cp 1
crap 3
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
    * @return array<int, mixed> filtered $value
194
    */
195 12
    protected static function MaybeThrowIfValueDoesNotMatchMultiTypedArrayValueArray(
196
        bool $autoTrimStrings,
197
        bool $throwIfNotUnique,
198
        array $value,
199
        string ...$types
200
    ) : array {
201 12
        $value = static::MaybeThrowIfNotArrayIntKeys($value);
202 10
        $value = static::MaybeThrowIfValueArrayDoesNotMatchTypes($value, ...$types);
203
204 8
        $initialCount = count($value);
205
206 8
        if (in_array('string', $types, true) && $autoTrimStrings && $initialCount > 0) {
207 2
            $value = array_map(
208
                /**
209
                * @param mixed $maybe
210
                *
211
                * @return mixed
212
                */
213
                function ($maybe) {
214 2
                    return is_string($maybe) ? trim($maybe) : $maybe;
215 2
                },
216 2
                $value
217
            );
218
        }
219
220 8
        $value = array_unique($value, SORT_REGULAR);
221
222 8
        if ($throwIfNotUnique && count($value) !== $initialCount) {
223 2
            throw new InvalidArgumentException(
224
                'Argument 3 passed to ' .
225
                __METHOD__ .
226 2
                ' contained non-unique values!'
227
            );
228
        }
229
230 6
        return array_values($value);
231
    }
232
233 236
    final protected static function CachePublicGettersAndSetters(string $class) : void
234
    {
235 236
        if (false === isset(self::$Getters[$class])) {
236 32
            self::$Getters[$class] = [];
237 32
            self::$publicSetters[$class] = [];
238
239 32
            if (is_a($class, DefinesOwnIdPropertiesInterface::class, true)) {
240 16
                self::$Getters[$class]['id'] = true;
241
            }
242
243 32
            self::CachePublicGettersAndSettersProperties($class);
244
        }
245 236
    }
246
247
    /**
248
    * @psalm-suppress InvalidStringClass
249
    */
250 32
    final protected static function CachePublicGettersAndSettersProperties(string $class) : void
251
    {
252
        /**
253
        * @var string[]
254
        */
255 32
        $props = $class::DaftObjectProperties();
256
257 32
        foreach ($props as $prop) {
258 32
            if (static::HasMethod($class, $prop, false)) {
259 28
                self::$Getters[$class][$prop] = true;
260 6
            } elseif (static::HasMethod($class, $prop, false, false)) {
261 2
                self::$Getters[$class][$prop] = false;
262
            }
263
264 32
            if (static::HasMethod($class, $prop, true)) {
265 32
                self::$publicSetters[$class][] = $prop;
266
            }
267
        }
268 32
    }
269
270
    /**
271
    * @psalm-suppress InvalidStringClass
272
    */
273 314
    final protected static function CheckTypeDefinesOwnIdPropertiesIsImplementation(
274
        string $class
275
    ) : void {
276 314
        $properties = (array) $class::DaftObjectIdProperties();
277
278 314
        if (count($properties) < 1) {
279 2
            throw new ClassMethodReturnHasZeroArrayCountException(
280 2
                $class,
281 2
                'DaftObjectIdProperties'
282
            );
283 312
        } elseif (count($properties) !== count(array_filter($properties, 'is_string'))) {
284 2
            throw new ClassMethodReturnIsNotArrayOfStringsException(
285 2
                $class,
286 2
                'DaftObjectIdProperties'
287
            );
288
        }
289 310
    }
290
}
291