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
Pull Request — master (#100)
by Cristian
01:07
created

FieldValidator   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 189
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 1

Importance

Changes 0
Metric Value
wmc 35
lcom 2
cbo 1
dl 0
loc 189
rs 9.6
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A fromReflection() 0 4 1
A __construct() 0 12 1
C isValidType() 0 38 12
A getDefinition() 0 16 3
A assertValidType() 0 4 2
A assertValidArrayTypes() 0 10 3
A resolveNullable() 0 12 3
A resolveIsMixed() 0 4 1
A resolveIsMixedArray() 0 12 3
A resolveAllowedTypes() 0 4 1
A resolveAllowedArrayTypes() 0 21 4
A normaliseTypes() 0 9 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Spatie\DataTransferObject;
6
7
use ReflectionProperty;
8
9
class FieldValidator
10
{
11
    /** @var array */
12
    private static $typeMapping = [
13
        'int' => 'integer',
14
        'bool' => 'boolean',
15
        'float' => 'double',
16
    ];
17
18
    /** @var bool */
19
    private $hasTypeDeclaration = false;
20
21
    /** @var bool */
22
    public $isNullable = false;
23
24
    /** @var bool */
25
    public $isMixed = false;
26
27
    /** @var bool */
28
    public $isMixedArray = false;
29
30
    /** @var bool */
31
    public $hasDefaultValue = false;
32
33
    /** @var array */
34
    public $allowedTypes = [];
35
36
    /** @var array */
37
    public $allowedArrayTypes = [];
38
39
40
    public static function fromReflection(ReflectionProperty $property): FieldValidator
41
    {
42
        return new self($property);
43
    }
44
45
    public function __construct(ReflectionProperty $property)
46
    {
47
        $definition = $this->getDefinition($property);
48
49
        $this->hasTypeDeclaration = $definition !== '';
50
        $this->hasDefaultValue = $property->isDefault();
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 getDefinition(ReflectionProperty $property): string
98
    {
99
        if ($type = $property->getType()) {
100
            return $type->getName();
101
        }
102
103
        $docComment = $property->getDocComment() ?: null;
104
105
        preg_match(
106
            '/@var ((?:(?:[\w?|\\\\<>])+(?:\[])?)+)/',
107
            $docComment ?? '',
108
            $matches
109
        );
110
111
        return $matches[1] ?? '';
112
    }
113
114
    private function assertValidType(string $type, $value): bool
115
    {
116
        return $value instanceof $type || gettype($value) === $type;
117
    }
118
119
    private function assertValidArrayTypes(string $type, $collection): bool
120
    {
121
        foreach ($collection as $value) {
122
            if (! $this->assertValidType($type, $value)) {
123
                return false;
124
            }
125
        }
126
127
        return true;
128
    }
129
130
    private function resolveNullable(string $definition): bool
131
    {
132
        if (! $definition) {
133
            return true;
134
        }
135
136
        if (Str::contains($definition, ['mixed', 'null', '?'])) {
137
            return true;
138
        }
139
140
        return false;
141
    }
142
143
    private function resolveIsMixed(string $definition): bool
144
    {
145
        return Str::contains($definition, ['mixed']);
146
    }
147
148
    private function resolveIsMixedArray(string $definition): bool
149
    {
150
        $types = $this->normaliseTypes(...explode('|', $definition));
151
152
        foreach ($types as $type) {
153
            if (in_array($type, ['iterable', 'array'])) {
154
                return true;
155
            }
156
        }
157
158
        return false;
159
    }
160
161
    private function resolveAllowedTypes(string $definition): array
162
    {
163
        return $this->normaliseTypes(...explode('|', $definition));
164
    }
165
166
    private function resolveAllowedArrayTypes(string $definition): array
167
    {
168
        return $this->normaliseTypes(...array_map(
169
            function (string $type) {
170
                if (! $type) {
171
                    return;
172
                }
173
174
                if (strpos($type, '[]') !== false) {
175
                    return str_replace('[]', '', $type);
176
                }
177
178
                if (strpos($type, 'iterable<') !== false) {
179
                    return str_replace(['iterable<', '>'], ['', ''], $type);
180
                }
181
182
                return null;
183
            },
184
            explode('|', $definition)
185
        ));
186
    }
187
188
    private function normaliseTypes(?string ...$types): array
189
    {
190
        return array_filter(array_map(
191
            function (?string $type) {
192
                return self::$typeMapping[$type] ?? $type;
193
            },
194
            $types
195
        ));
196
    }
197
}
198