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 ( 807941...300eda )
by Brent
20s queued 12s
created

FieldValidator::resolveNullable()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.8666
c 0
b 0
f 0
cc 3
nc 3
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(
43
            $property->getDocComment() ?: null,
44
            $property->isDefault()
45
        );
46
    }
47
48
    public function __construct(?string $docComment = null, bool $hasDefaultValue = false)
49
    {
50
        preg_match(
51
            '/@var ((?:(?:[\w?|\\\\<>])+(?:\[])?)+)/',
52
            $docComment ?? '',
53
            $matches
54
        );
55
56
        $definition = $matches[1] ?? '';
57
58
        $this->hasTypeDeclaration = $definition !== '';
59
        $this->hasDefaultValue = $hasDefaultValue;
60
        $this->isNullable = $this->resolveNullable($definition);
61
        $this->isMixed = $this->resolveIsMixed($definition);
62
        $this->isMixedArray = $this->resolveIsMixedArray($definition);
63
        $this->allowedTypes = $this->resolveAllowedTypes($definition);
64
        $this->allowedArrayTypes = $this->resolveAllowedArrayTypes($definition);
65
    }
66
67
    public function isValidType($value): bool
68
    {
69
        if (! $this->hasTypeDeclaration) {
70
            return true;
71
        }
72
73
        if ($this->isMixed) {
74
            return true;
75
        }
76
77
        if (is_iterable($value) && $this->isMixedArray) {
78
            return true;
79
        }
80
81
        if ($this->isNullable && $value === null) {
82
            return true;
83
        }
84
85
        if (is_iterable($value)) {
86
            foreach ($this->allowedArrayTypes as $type) {
87
                $isValid = $this->assertValidArrayTypes($type, $value);
88
89
                if ($isValid) {
90
                    return true;
91
                }
92
            }
93
        }
94
95
        foreach ($this->allowedTypes as $type) {
96
            $isValidType = $this->assertValidType($type, $value);
97
98
            if ($isValidType) {
99
                return true;
100
            }
101
        }
102
103
        return false;
104
    }
105
106
    private function assertValidType(string $type, $value): bool
107
    {
108
        return $value instanceof $type || gettype($value) === $type;
109
    }
110
111
    private function assertValidArrayTypes(string $type, $collection): bool
112
    {
113
        foreach ($collection as $value) {
114
            if (! $this->assertValidType($type, $value)) {
115
                return false;
116
            }
117
        }
118
119
        return true;
120
    }
121
122
    private function resolveNullable(string $definition): bool
123
    {
124
        if (! $definition) {
125
            return true;
126
        }
127
128
        if (Str::contains($definition, ['mixed', 'null', '?'])) {
129
            return true;
130
        }
131
132
        return false;
133
    }
134
135
    private function resolveIsMixed(string $definition): bool
136
    {
137
        return Str::contains($definition, ['mixed']);
138
    }
139
140
    private function resolveIsMixedArray(string $definition): bool
141
    {
142
        $types = $this->normaliseTypes(...explode('|', $definition));
143
144
        foreach ($types as $type) {
145
            if (in_array($type, ['iterable', 'array'])) {
146
                return true;
147
            }
148
        }
149
150
        return false;
151
    }
152
153
    private function resolveAllowedTypes(string $definition): array
154
    {
155
        return $this->normaliseTypes(...explode('|', $definition));
156
    }
157
158
    private function resolveAllowedArrayTypes(string $definition): array
159
    {
160
        return $this->normaliseTypes(...array_map(
161
            function (string $type) {
162
                if (! $type) {
163
                    return;
164
                }
165
166
                if (strpos($type, '[]') !== false) {
167
                    return str_replace('[]', '', $type);
168
                }
169
170
                if (strpos($type, 'iterable<') !== false) {
171
                    return str_replace(['iterable<', '>'], ['', ''], $type);
172
                }
173
174
                return null;
175
            },
176
            explode('|', $definition)
177
        ));
178
    }
179
180
    private function normaliseTypes(?string ...$types): array
181
    {
182
        return array_filter(array_map(
183
            function (?string $type) {
184
                return self::$typeMapping[$type] ?? $type;
185
            },
186
            $types
187
        ));
188
    }
189
}
190