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 (#56)
by Arthur
01:27
created

Property::isInitialized()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Spatie\DataTransferObject;
6
7
use ReflectionProperty;
8
9
class Property
10
{
11
    /** @var array */
12
    protected static $typeMapping = [
13
        'int' => 'integer',
14
        'bool' => 'boolean',
15
        'float' => 'double',
16
    ];
17
18
    /** @var bool */
19
    protected $hasTypeDeclaration = false;
20
21
    /** @var bool */
22
    protected $isNullable = false;
23
24
    /** @var bool */
25
    protected $isInitialised = false;
26
27
    /** @var array */
28
    protected $types = [];
29
30
    /** @var array */
31
    protected $arrayTypes = [];
32
33
    /** @var mixed */
34
    protected $default;
35
36
    /** @var mixed */
37
    protected $value;
38
39
    /** @var ReflectionProperty */
40
    protected $reflection;
41
42
    public static function fromReflection(ReflectionProperty $reflectionProperty): self
43
    {
44
        return new static($reflectionProperty);
45
    }
46
47
    public function __construct(ReflectionProperty $reflectionProperty)
48
    {
49
        $this->reflection = $reflectionProperty;
50
51
        $this->resolveTypeDefinition();
52
    }
53
54
    public function set($value)
55
    {
56
        if (is_array($value)) {
57
            $value = $this->shouldBeCastToCollection($value) ? $this->castCollection($value) : $this->cast($value);
58
        }
59
60
        if (! $this->isValidType($value)) {
61
            throw DataTransferObjectError::invalidType($this, $value);
62
        }
63
64
        $this->isInitialised = true;
65
66
        $this->value = $value;
67
    }
68
69
    public function setUninitialized()
70
    {
71
        $this->isInitialised = false;
72
    }
73
74
    public function isInitialized()
75
    {
76
        return $this->isInitialised;
77
    }
78
79
    public function getTypes(): array
80
    {
81
        return $this->types;
82
    }
83
84
    public function getFqn(): string
85
    {
86
        return "{$this->reflection->getDeclaringClass()->getName()}::{$this->reflection->getName()}";
87
    }
88
89
    public function isNullable(): bool
90
    {
91
        return $this->isNullable;
92
    }
93
94
    public function setNullable(bool $bool): void
95
    {
96
        $this->isNullable = $bool;
97
    }
98
99
    protected function resolveTypeDefinition()
100
    {
101
        $docComment = $this->reflection->getDocComment();
102
103
        if (! $docComment) {
104
            $this->setNullable(true);
105
106
            return;
107
        }
108
109
        preg_match('/\@var ((?:(?:[\w|\\\\])+(?:\[\])?)+)/', $docComment, $matches);
110
111
        if (! count($matches)) {
112
            $this->setNullable(true);
113
114
            return;
115
        }
116
117
        $this->hasTypeDeclaration = true;
118
119
        $varDocComment = end($matches);
120
121
        $this->types = explode('|', $varDocComment);
122
        $this->arrayTypes = str_replace('[]', '', $this->types);
123
124
        $this->setNullable(strpos($varDocComment, 'null') !== false);
125
    }
126
127
    protected function isValidType($value): bool
128
    {
129
        if (! $this->hasTypeDeclaration) {
130
            return true;
131
        }
132
133
        if ($this->isNullable() && $value === null) {
134
            return true;
135
        }
136
137
        foreach ($this->types as $currentType) {
138
            $isValidType = $this->assertTypeEquals($currentType, $value);
139
140
            if ($isValidType) {
141
                return true;
142
            }
143
        }
144
145
        return false;
146
    }
147
148
    protected function cast($value)
149
    {
150
        $castTo = null;
151
152
        foreach ($this->types as $type) {
153
            if (! is_subclass_of($type, DataTransferObject::class)) {
154
                continue;
155
            }
156
157
            $castTo = $type;
158
159
            break;
160
        }
161
162
        if (! $castTo) {
163
            return $value;
164
        }
165
166
        return new $castTo($value);
167
    }
168
169
    protected function castCollection(array $values)
170
    {
171
        $castTo = null;
172
173
        foreach ($this->arrayTypes as $type) {
174
            if (! is_subclass_of($type, DataTransferObject::class)) {
175
                continue;
176
            }
177
178
            $castTo = $type;
179
180
            break;
181
        }
182
183
        if (! $castTo) {
184
            return $values;
185
        }
186
187
        $casts = [];
188
189
        foreach ($values as $value) {
190
            $casts[] = new $castTo($value);
191
        }
192
193
        return $casts;
194
    }
195
196
    protected function shouldBeCastToCollection(array $values): bool
197
    {
198
        if (empty($values)) {
199
            return false;
200
        }
201
202
        foreach ($values as $key => $value) {
203
            if (is_string($key)) {
204
                return false;
205
            }
206
207
            if (! is_array($value)) {
208
                return false;
209
            }
210
        }
211
212
        return true;
213
    }
214
215
    protected function assertTypeEquals(string $type, $value): bool
216
    {
217
        if (strpos($type, '[]') !== false) {
218
            return $this->isValidGenericCollection($type, $value);
219
        }
220
221
        if ($type === 'mixed' && $value !== null) {
222
            return true;
223
        }
224
225
        return $value instanceof $type
226
            || gettype($value) === (self::$typeMapping[$type] ?? $type);
227
    }
228
229
    protected function isValidGenericCollection(string $type, $collection): bool
230
    {
231
        if (! is_array($collection)) {
232
            return false;
233
        }
234
235
        $valueType = str_replace('[]', '', $type);
236
237
        foreach ($collection as $value) {
238
            if (! $this->assertTypeEquals($valueType, $value)) {
239
                return false;
240
            }
241
        }
242
243
        return true;
244
    }
245
246
    public function getDefault()
247
    {
248
        return $this->default;
249
    }
250
251
    public function setDefault($default): void
252
    {
253
        $this->default = $default;
254
    }
255
256
    public function getValue()
257
    {
258
        if (! $this->isNullable() && $this->value == null) {
259
            return $this->getDefault();
260
        }
261
262
        return $this->value;
263
    }
264
265
    public function getValueFromReflection($object)
266
    {
267
        return $this->reflection->getValue($object);
268
    }
269
270
    public function getName()
271
    {
272
        return $this->reflection->getName();
273
    }
274
}
275