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 (#14)
by Brent
01:57
created

DataTransferObjectProperty::set()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 9.7998
c 0
b 0
f 0
cc 3
nc 4
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Spatie\DataTransferObject;
6
7
use ReflectionProperty;
8
use Spatie\DataTransferObject\DataTransferObjectDefinition;
9
10
class DataTransferObjectProperty extends ReflectionProperty
11
{
12
    /** @var array */
13
    protected static $typeMapping = [
14
        'int' => 'integer',
15
        'bool' => 'boolean',
16
    ];
17
18
    /** @var \Spatie\DataTransferObject\DataTransferObject */
19
    protected $dataTransferObject;
20
21
    /** @var bool */
22
    protected $hasTypeDeclaration = false;
23
24
    /** @var bool */
25
    protected $isNullable = false;
26
27
    /** @var bool */
28
    protected $isInitialised = false;
29
30
    /** @var array */
31
    protected $types = [];
32
33
    /** @var \Spatie\DataTransferObject\DataTransferObjectDefinition */
34
    protected $dataTransferObjectDefinition;
35
36
    public static function fromReflection(
37
        DataTransferObject $dataTransferObject,
38
        DataTransferObjectDefinition $dataTransferObjectDefinition,
39
        ReflectionProperty $reflectionProperty
40
    ) {
41
        return new self($dataTransferObject, $dataTransferObjectDefinition, $reflectionProperty);
42
    }
43
44
    public function __construct(
45
        DataTransferObject $dataTransferObject,
46
        DataTransferObjectDefinition $dataTransferObjectDefinition,
47
        ReflectionProperty $reflectionProperty
48
    ) {
49
        parent::__construct($reflectionProperty->class, $reflectionProperty->getName());
50
51
        $this->dataTransferObject = $dataTransferObject;
52
53
        $this->dataTransferObjectDefinition = $dataTransferObjectDefinition;
54
55
        $this->resolveTypeDefinition();
56
    }
57
58
    public function set($value)
59
    {
60
        if (is_array($value)) {
61
            $value = $this->cast($value);
62
        }
63
64
        if (! $this->isValidType($value)) {
65
            throw DataTransferObjectError::invalidType($this, $value);
66
        }
67
68
        $this->isInitialised = true;
69
70
        $this->dataTransferObject->{$this->getName()} = $value;
71
    }
72
73
    public function getTypes(): array
74
    {
75
        return $this->types;
76
    }
77
78
    public function getFqn(): string
79
    {
80
        return "{$this->getDeclaringClass()->getName()}::{$this->getName()}";
81
    }
82
83
    public function isNullable(): bool
84
    {
85
        return $this->isNullable;
86
    }
87
88
    protected function resolveTypeDefinition()
89
    {
90
        $docComment = $this->getDocComment();
91
92
        if (! $docComment) {
93
            $this->isNullable = true;
94
95
            return;
96
        }
97
98
        preg_match('/\@var ((?:(?:[\w|\\\\])+(?:\[\])?)+)/', $docComment, $matches);
99
100
        if (! count($matches)) {
101
            $this->isNullable = true;
102
103
            return;
104
        }
105
106
        $varDocComment = end($matches);
107
108
        $this->types = explode('|', $varDocComment);
109
110
        $this->isNullable = strpos($varDocComment, 'null') !== false;
111
112
        $this->hasTypeDeclaration = true;
113
    }
114
115
    protected function isValidType($value): bool
116
    {
117
        if (! $this->hasTypeDeclaration) {
118
            return true;
119
        }
120
121
        if ($this->isNullable && $value === null) {
122
            return true;
123
        }
124
125
        foreach ($this->types as $currentType) {
126
            $isValidType = $this->assertTypeEquals($currentType, $value);
127
128
            if ($isValidType) {
129
                return true;
130
            }
131
        }
132
133
        return false;
134
    }
135
136
    protected function cast($value)
137
    {
138
        $castTo = null;
139
140
        foreach ($this->types as $type) {
141
            if (! is_subclass_of($type, DataTransferObject::class)) {
142
                continue;
143
            }
144
145
            $castTo = $type;
146
147
            break;
148
        }
149
150
        if (! $castTo) {
151
            return $value;
152
        }
153
154
        return new $castTo($value);
155
    }
156
157
    protected function assertTypeEquals(string $type, $value): bool
158
    {
159
        if (strpos($type, '[]') !== false) {
160
            return $this->isValidGenericCollection($type, $value);
161
        }
162
163
        if ($type === 'mixed' && $value !== null) {
164
            return true;
165
        }
166
167
        if ($this->dataTransferObjectDefinition->hasAlias($type)) {
168
            $type = $this->dataTransferObjectDefinition->resolveAlias($type);
169
170
            return $value instanceof $type;
171
        }
172
173
        return $value instanceof $type
174
            || gettype($value) === (self::$typeMapping[$type] ?? $type);
175
    }
176
177
    protected function isValidGenericCollection(string $type, $collection): bool
178
    {
179
        if (! is_array($collection)) {
180
            return false;
181
        }
182
183
        $valueType = str_replace('[]', '', $type);
184
185
        foreach ($collection as $value) {
186
            if (! $this->assertTypeEquals($valueType, $value)) {
187
                return false;
188
            }
189
        }
190
191
        return true;
192
    }
193
}
194