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.
Completed
Push — master ( 14690e...e9eac8 )
by Brent
02:11 queued 01:06
created

FieldValidator   A

Complexity

Total Complexity 33

Size/Duplication

Total Lines 181
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 1

Importance

Changes 0
Metric Value
wmc 33
lcom 2
cbo 1
dl 0
loc 181
rs 9.76
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Spatie\DataTransferObject;
6
7
use ReflectionProperty;
8
9
class FieldValidator
10
{
11
    private static array $typeMapping = [
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_ARRAY, expecting T_FUNCTION or T_CONST
Loading history...
12
        'int' => 'integer',
13
        'bool' => 'boolean',
14
        'float' => 'double',
15
    ];
16
17
    private bool $hasTypeDeclaration = false;
18
19
    public bool $isNullable = false;
20
21
    public bool $isMixed = false;
22
23
    public bool $isMixedArray = false;
24
25
    public bool $hasDefaultValue = false;
26
27
    public array $allowedTypes = [];
28
29
    public array $allowedArrayTypes = [];
30
31
    public static function fromReflection(ReflectionProperty $property): FieldValidator
32
    {
33
        return new self(
34
            $property->getDocComment() ?: null,
35
            $property->isDefault()
36
        );
37
    }
38
39
    public function __construct(?string $docComment = null, bool $hasDefaultValue = false)
40
    {
41
        preg_match(
42
            '/@var ((?:(?:[\w?|\\\\<>])+(?:\[])?)+)/',
43
            $docComment ?? '',
44
            $matches
45
        );
46
47
        $definition = $matches[1] ?? '';
48
49
        $this->hasTypeDeclaration = $definition !== '';
50
        $this->hasDefaultValue = $hasDefaultValue;
51
        $this->isNullable = $this->resolveNullable($definition);
52
        $this->isMixed = $this->resolveIsMixed($definition);
53
        $this->isMixedArray = $this->resolveIsMixedArray($definition);
54
        $this->allowedTypes = $this->resolveAllowedTypes($definition);
55
        $this->allowedArrayTypes = $this->resolveAllowedArrayTypes($definition);
56
    }
57
58
    public function isValidType($value): bool
59
    {
60
        if (! $this->hasTypeDeclaration) {
61
            return true;
62
        }
63
64
        if ($this->isMixed) {
65
            return true;
66
        }
67
68
        if (is_iterable($value) && $this->isMixedArray) {
69
            return true;
70
        }
71
72
        if ($this->isNullable && $value === null) {
73
            return true;
74
        }
75
76
        if (is_iterable($value)) {
77
            foreach ($this->allowedArrayTypes as $type) {
78
                $isValid = $this->assertValidArrayTypes($type, $value);
79
80
                if ($isValid) {
81
                    return true;
82
                }
83
            }
84
        }
85
86
        foreach ($this->allowedTypes as $type) {
87
            $isValidType = $this->assertValidType($type, $value);
88
89
            if ($isValidType) {
90
                return true;
91
            }
92
        }
93
94
        return false;
95
    }
96
97
    private function assertValidType(string $type, $value): bool
98
    {
99
        return $value instanceof $type || gettype($value) === $type;
100
    }
101
102
    private function assertValidArrayTypes(string $type, $collection): bool
103
    {
104
        foreach ($collection as $value) {
105
            if (! $this->assertValidType($type, $value)) {
106
                return false;
107
            }
108
        }
109
110
        return true;
111
    }
112
113
    private function resolveNullable(string $definition): bool
114
    {
115
        if (! $definition) {
116
            return true;
117
        }
118
119
        if (Str::contains($definition, ['mixed', 'null', '?'])) {
120
            return true;
121
        }
122
123
        return false;
124
    }
125
126
    private function resolveIsMixed(string $definition): bool
127
    {
128
        return Str::contains($definition, ['mixed']);
129
    }
130
131
    private function resolveIsMixedArray(string $definition): bool
132
    {
133
        $types = $this->normaliseTypes(...explode('|', $definition));
134
135
        foreach ($types as $type) {
136
            if (in_array($type, ['iterable', 'array'])) {
137
                return true;
138
            }
139
        }
140
141
        return false;
142
    }
143
144
    private function resolveAllowedTypes(string $definition): array
145
    {
146
        return $this->normaliseTypes(...explode('|', $definition));
147
    }
148
149
    private function resolveAllowedArrayTypes(string $definition): array
150
    {
151
        return $this->normaliseTypes(...array_map(
152
            function (string $type) {
153
                if (! $type) {
154
                    return;
155
                }
156
157
                if (strpos($type, '[]') !== false) {
158
                    return str_replace('[]', '', $type);
159
                }
160
161
                if (strpos($type, 'iterable<') !== false) {
162
                    return str_replace(['iterable<', '>'], ['', ''], $type);
163
                }
164
165
                return null;
166
            },
167
            explode('|', $definition)
168
        ));
169
    }
170
171
    private function normaliseTypes(?string ...$types): array
172
    {
173
        return array_filter(array_map(
174
            fn (?string $type) => self::$typeMapping[$type] ?? $type,
175
            $types
176
        ));
177
    }
178
}
179