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 ( a700a2...5ecdcc )
by SignpostMarv
04:49
created

TypeUtilities   A

Complexity

Total Complexity 27

Size/Duplication

Total Lines 180
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 27
eloc 69
dl 0
loc 180
ccs 68
cts 68
cp 1
rs 10
c 0
b 0
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A HasMethod() 0 14 4
A CountMaybeArray() 0 6 1
A DaftObjectPublicSetters() 0 5 1
A DaftObjectPublicOrProtectedGetters() 0 5 1
A MethodNameFromProperty() 0 9 4
A CachePublicGettersAndSetters() 0 11 3
A FilterMaybeArray() 0 5 1
A CheckTypeDefinesOwnIdProperties() 0 10 3
A DaftObjectPublicGetters() 0 5 1
A CachePublicGettersAndSettersProperties() 0 18 5
A CheckTypeDefinesOwnIdPropertiesIsImplementation() 0 20 3
1
<?php
2
/**
3
* @author SignpostMarv
4
*/
5
declare(strict_types=1);
6
7
namespace SignpostMarv\DaftObject;
8
9
use ReflectionException;
10
use ReflectionMethod;
11
12
class TypeUtilities
13
{
14
    const BOOL_EXPECTING_NON_PUBLIC_METHOD = false;
15
16
    const BOOL_EXPECTING_GETTER = false;
17
18
    const BOOL_DEFAULT_THROWIFNOTIMPLEMENTATION = false;
19
20
    const BOOL_DEFAULT_EXPECTING_NON_PUBLIC_METHOD = true;
21
22
    const BOOL_METHOD_IS_PUBLIC = true;
23
24
    const BOOL_METHOD_IS_NON_PUBLIC = false;
25
26
    const BOOL_DEFAULT_SET_NOT_GET = false;
27
28
    const SUPPORTED_INVALID_LEADING_CHARACTERS = [
29
        '@',
30
    ];
31
32
    /**
33
    * @var array<string, array<string, bool>>
34
    */
35
    private static $Getters = [];
36
37
    /**
38
    * @var array<string, array<int, string>>
39
    */
40
    private static $publicSetters = [];
41
42 126
    public static function DaftObjectPublicGetters(string $class) : array
43
    {
44 126
        static::CachePublicGettersAndSetters($class);
45
46 126
        return array_keys(array_filter(self::$Getters[$class]));
47
    }
48
49 2
    public static function DaftObjectPublicOrProtectedGetters(string $class) : array
50
    {
51 2
        static::CachePublicGettersAndSetters($class);
52
53 2
        return array_keys(self::$Getters[$class]);
54
    }
55
56 188
    public static function DaftObjectPublicSetters(string $class) : array
57
    {
58 188
        static::CachePublicGettersAndSetters($class);
59
60 188
        return self::$publicSetters[$class];
61
    }
62
63 266
    public static function MethodNameFromProperty(
64
        string $prop,
65
        bool $SetNotGet = self::BOOL_DEFAULT_SET_NOT_GET
66
    ) : string {
67 266
        if (TypeParanoia::MaybeInArray(mb_substr($prop, 0, 1), self::SUPPORTED_INVALID_LEADING_CHARACTERS)) {
68 4
            return ($SetNotGet ? 'Alter' : 'Obtain') . ucfirst(mb_substr($prop, 1));
69
        }
70
71 262
        return ($SetNotGet ? 'Set' : 'Get') . ucfirst($prop);
72
    }
73
74
    /**
75
    * Checks if a type correctly defines it's own id.
76
    *
77
    * @throws ClassDoesNotImplementClassException if $class is not an implementation of DefinesOwnIdPropertiesInterface
78
    * @throws ClassMethodReturnHasZeroArrayCountException if $class::DaftObjectIdProperties() does not contain at least one property
79
    * @throws ClassMethodReturnIsNotArrayOfStringsException if $class::DaftObjectIdProperties() is not string[]
80
    * @throws UndefinedPropertyException if an id property is not in $class::DaftObjectIdProperties()
81
    */
82 536
    public static function CheckTypeDefinesOwnIdProperties(
83
        string $class,
84
        bool $throwIfNotImplementation = self::BOOL_DEFAULT_THROWIFNOTIMPLEMENTATION
85
    ) : void {
86 536
        if (TypeParanoia::IsThingStrings($class, DefinesOwnIdPropertiesInterface::class)) {
87 314
            self::CheckTypeDefinesOwnIdPropertiesIsImplementation($class);
88 228
        } elseif ($throwIfNotImplementation) {
89 2
            throw new ClassDoesNotImplementClassException(
90 2
                $class,
91 2
                DefinesOwnIdPropertiesInterface::class
92
            );
93
        }
94 530
    }
95
96 36
    private static function HasMethod(
97
        string $class,
98
        string $property,
99
        bool $SetNotGet,
100
        bool $pub = self::BOOL_DEFAULT_EXPECTING_NON_PUBLIC_METHOD
101
    ) : bool {
102 36
        $method = static::MethodNameFromProperty($property, $SetNotGet);
103
104
        try {
105 36
            $ref = new ReflectionMethod($class, $method);
106
107 36
            return ($pub ? $ref->isPublic() : $ref->isProtected()) && false === $ref->isStatic();
108 20
        } catch (ReflectionException $e) {
109 20
            return false;
110
        }
111
    }
112
113
    /**
114
    * @param mixed $maybe
115
    */
116 312
    private static function FilterMaybeArray($maybe, callable $filter) : array
117
    {
118 312
        return array_filter(
119 312
            TypeParanoia::EnsureArgumentIsArray($maybe, TypeParanoia::INDEX_FIRST_ARG, __METHOD__),
120 312
            $filter
121
        );
122
    }
123
124
    /**
125
    * @param mixed $maybe
126
    */
127 314
    private static function CountMaybeArray($maybe) : int
128
    {
129 314
        return count(TypeParanoia::EnsureArgumentIsArray(
130 314
            $maybe,
131 314
            TypeParanoia::INDEX_FIRST_ARG,
132 314
            __METHOD__
133
        ));
134
    }
135
136 244
    private static function CachePublicGettersAndSetters(string $class) : void
137
    {
138 244
        if (false === isset(self::$Getters[$class])) {
139 36
            self::$Getters[$class] = [];
140 36
            self::$publicSetters[$class] = [];
141
142 36
            if (TypeParanoia::IsThingStrings($class, DefinesOwnIdPropertiesInterface::class)) {
143 16
                self::$Getters[$class]['id'] = self::BOOL_METHOD_IS_PUBLIC;
144
            }
145
146 36
            self::CachePublicGettersAndSettersProperties($class);
147
        }
148 244
    }
149
150 36
    private static function CachePublicGettersAndSettersProperties(string $class) : void
151
    {
152
        foreach (
153 36
            DefinitionAssistant::ObtainExpectedOrDefaultPropertiesWithAutoRegister($class) as $prop
154
        ) {
155 36
            if (static::HasMethod($class, $prop, self::BOOL_EXPECTING_GETTER)) {
156 32
                self::$Getters[$class][$prop] = self::BOOL_METHOD_IS_PUBLIC;
157 6
            } elseif (static::HasMethod(
158 6
                $class,
159 6
                $prop,
160 6
                self::BOOL_EXPECTING_GETTER,
161 6
                self::BOOL_EXPECTING_NON_PUBLIC_METHOD
162
            )) {
163 2
                self::$Getters[$class][$prop] = self::BOOL_METHOD_IS_NON_PUBLIC;
164
            }
165
166 36
            if (static::HasMethod($class, $prop, true)) {
167 36
                self::$publicSetters[$class][] = $prop;
168
            }
169
        }
170 36
    }
171
172 314
    private static function CheckTypeDefinesOwnIdPropertiesIsImplementation(
173
        string $class
174
    ) : void {
175
        /**
176
        * @var scalar|array|object|null
177
        */
178 314
        $properties = $class::DaftObjectIdProperties();
179
180 314
        if (self::CountMaybeArray($properties) < 1) {
181 2
            throw new ClassMethodReturnHasZeroArrayCountException(
182 2
                $class,
183 2
                'DaftObjectIdProperties'
184
            );
185
        } elseif (
186 312
            self::CountMaybeArray($properties) !==
187 312
            count(self::FilterMaybeArray($properties, 'is_string'))
188
        ) {
189 2
            throw new ClassMethodReturnIsNotArrayOfStringsException(
190 2
                $class,
191 2
                'DaftObjectIdProperties'
192
            );
193
        }
194 310
    }
195
}
196