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 ( 85fe9f...6b2e87 )
by SignpostMarv
02:29
created

TypeUtilities::DaftObjectPublicSetters()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 5
rs 10
c 0
b 0
f 0
ccs 3
cts 3
cp 1
crap 1
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
    * @return array<int, mixed> filtered $value
152
    */
153 12
    protected static function MaybeThrowIfValueDoesNotMatchMultiTypedArrayValueArray(
154
        bool $autoTrimStrings,
155
        bool $throwIfNotUnique,
156
        array $value,
157
        string ...$types
158
    ) : array {
159 12
        $value = static::MaybeThrowIfNotArrayIntKeys($value);
160
161 10
        $initialCount = count($value);
162
163 10
        $value = array_filter(
164 10
            $value,
165
            /**
166
            * @param mixed $maybe
167
            */
168
            function ($maybe) use ($types) : bool {
169 10
                if (is_object($maybe)) {
170 8
                    foreach ($types as $maybeType) {
171 8
                        if (is_a($maybe, $maybeType)) {
172 8
                            return true;
173
                        }
174
                    }
175
176 2
                    return false;
177
                }
178
179 4
                return in_array(gettype($maybe), $types, true);
180 10
            }
181
        );
182
183 10
        if (count($value) !== $initialCount) {
184 2
            throw new InvalidArgumentException(
185
                'Argument 3 passed to ' .
186
                __METHOD__ .
187 2
                ' contained values that did not match the provided types!'
188
            );
189
        }
190
191 8
        $initialCount = count($value);
192
193 8
        if (in_array('string', $types, true) && $autoTrimStrings && $initialCount > 0) {
194 2
            $value = array_map(
195
                /**
196
                * @param mixed $maybe
197
                *
198
                * @return mixed
199
                */
200
                function ($maybe) {
201 2
                    return is_string($maybe) ? trim($maybe) : $maybe;
202 2
                },
203 2
                $value
204
            );
205
        }
206
207 8
        $value = array_unique($value, SORT_REGULAR);
208
209 8
        if ($throwIfNotUnique && count($value) !== $initialCount) {
210 2
            throw new InvalidArgumentException(
211
                'Argument 3 passed to ' .
212
                __METHOD__ .
213 2
                ' contained non-unique values!'
214
            );
215
        }
216
217 6
        return array_values($value);
218
    }
219
220 236
    final protected static function CachePublicGettersAndSetters(string $class) : void
221
    {
222 236
        if (false === isset(self::$Getters[$class])) {
223 32
            self::$Getters[$class] = [];
224 32
            self::$publicSetters[$class] = [];
225
226 32
            if (is_a($class, DefinesOwnIdPropertiesInterface::class, true)) {
227 16
                self::$Getters[$class]['id'] = true;
228
            }
229
230 32
            self::CachePublicGettersAndSettersProperties($class);
231
        }
232 236
    }
233
234
    /**
235
    * @psalm-suppress InvalidStringClass
236
    */
237 32
    final protected static function CachePublicGettersAndSettersProperties(string $class) : void
238
    {
239
        /**
240
        * @var string[]
241
        */
242 32
        $props = $class::DaftObjectProperties();
243
244 32
        foreach ($props as $prop) {
245 32
            if (static::HasMethod($class, $prop, false)) {
246 28
                self::$Getters[$class][$prop] = true;
247 6
            } elseif (static::HasMethod($class, $prop, false, false)) {
248 2
                self::$Getters[$class][$prop] = false;
249
            }
250
251 32
            if (static::HasMethod($class, $prop, true)) {
252 32
                self::$publicSetters[$class][] = $prop;
253
            }
254
        }
255 32
    }
256
257
    /**
258
    * @psalm-suppress InvalidStringClass
259
    */
260 314
    final protected static function CheckTypeDefinesOwnIdPropertiesIsImplementation(
261
        string $class
262
    ) : void {
263 314
        $properties = (array) $class::DaftObjectIdProperties();
264
265 314
        if (count($properties) < 1) {
266 2
            throw new ClassMethodReturnHasZeroArrayCountException(
267 2
                $class,
268 2
                'DaftObjectIdProperties'
269
            );
270 312
        } elseif (count($properties) !== count(array_filter($properties, 'is_string'))) {
271 2
            throw new ClassMethodReturnIsNotArrayOfStringsException(
272 2
                $class,
273 2
                'DaftObjectIdProperties'
274
            );
275
        }
276 310
    }
277
}
278