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 ( 93d877...41bc2a )
by Brent
05:38
created

Property::cast()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

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