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:11
created

FieldValidator::getDefinition()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 19
rs 9.6333
c 0
b 0
f 0
cc 4
nc 5
nop 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 (method_exists($property, 'getType')) {
100
            $type = $property->getType();
101
            if ($type) {
102
                return $type->getName();
103
            }
104
        }
105
106
        $docComment = $property->getDocComment() ?: null;
107
108
        preg_match(
109
            '/@var ((?:(?:[\w?|\\\\<>])+(?:\[])?)+)/',
110
            $docComment ?? '',
111
            $matches
112
        );
113
114
        return $matches[1] ?? '';
115
    }
116
117
    private function assertValidType(string $type, $value): bool
118
    {
119
        return $value instanceof $type || gettype($value) === $type;
120
    }
121
122
    private function assertValidArrayTypes(string $type, $collection): bool
123
    {
124
        foreach ($collection as $value) {
125
            if (! $this->assertValidType($type, $value)) {
126
                return false;
127
            }
128
        }
129
130
        return true;
131
    }
132
133
    private function resolveNullable(string $definition): bool
134
    {
135
        if (! $definition) {
136
            return true;
137
        }
138
139
        if (Str::contains($definition, ['mixed', 'null', '?'])) {
140
            return true;
141
        }
142
143
        return false;
144
    }
145
146
    private function resolveIsMixed(string $definition): bool
147
    {
148
        return Str::contains($definition, ['mixed']);
149
    }
150
151
    private function resolveIsMixedArray(string $definition): bool
152
    {
153
        $types = $this->normaliseTypes(...explode('|', $definition));
154
155
        foreach ($types as $type) {
156
            if (in_array($type, ['iterable', 'array'])) {
157
                return true;
158
            }
159
        }
160
161
        return false;
162
    }
163
164
    private function resolveAllowedTypes(string $definition): array
165
    {
166
        return $this->normaliseTypes(...explode('|', $definition));
167
    }
168
169
    private function resolveAllowedArrayTypes(string $definition): array
170
    {
171
        return $this->normaliseTypes(...array_map(
172
            function (string $type) {
173
                if (! $type) {
174
                    return;
175
                }
176
177
                if (strpos($type, '[]') !== false) {
178
                    return str_replace('[]', '', $type);
179
                }
180
181
                if (strpos($type, 'iterable<') !== false) {
182
                    return str_replace(['iterable<', '>'], ['', ''], $type);
183
                }
184
185
                return null;
186
            },
187
            explode('|', $definition)
188
        ));
189
    }
190
191
    private function normaliseTypes(?string ...$types): array
192
    {
193
        return array_filter(array_map(
194
            function (?string $type) {
195
                return self::$typeMapping[$type] ?? $type;
196
            },
197
            $types
198
        ));
199
    }
200
}
201