1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Cerbero\Dto; |
4
|
|
|
|
5
|
|
|
use Cerbero\Dto\Manipulators\ArrayConverter; |
6
|
|
|
use Cerbero\Dto\Exceptions\UnexpectedValueException; |
7
|
|
|
|
8
|
|
|
/** |
9
|
|
|
* The DTO property. |
10
|
|
|
* |
11
|
|
|
*/ |
12
|
|
|
class DtoProperty |
13
|
|
|
{ |
14
|
|
|
/** |
15
|
|
|
* The property name. |
16
|
|
|
* |
17
|
|
|
* @var string |
18
|
|
|
*/ |
19
|
|
|
protected $name; |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* The property raw value. |
23
|
|
|
* |
24
|
|
|
* @var mixed |
25
|
|
|
*/ |
26
|
|
|
protected $rawValue; |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* The property types. |
30
|
|
|
* |
31
|
|
|
* @var DtoPropertyTypes |
32
|
|
|
*/ |
33
|
|
|
protected $types; |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* The DTO flags. |
37
|
|
|
* |
38
|
|
|
* @var int |
39
|
|
|
*/ |
40
|
|
|
protected $flags; |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* The processed value. |
44
|
|
|
* |
45
|
|
|
* @var mixed |
46
|
|
|
*/ |
47
|
|
|
protected $processedValue; |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* Whether the value has been processed. |
51
|
|
|
* |
52
|
|
|
* @var bool |
53
|
|
|
*/ |
54
|
|
|
protected $valueIsProcessed = false; |
55
|
|
|
|
56
|
|
|
/** |
57
|
|
|
* Instantiate the class. |
58
|
|
|
* |
59
|
|
|
* @param string $name |
60
|
|
|
* @param mixed $rawValue |
61
|
|
|
* @param DtoPropertyTypes $types |
62
|
|
|
* @param int $flags |
63
|
|
|
*/ |
64
|
219 |
|
protected function __construct(string $name, $rawValue, DtoPropertyTypes $types, int $flags) |
65
|
|
|
{ |
66
|
219 |
|
$this->name = $name; |
67
|
219 |
|
$this->rawValue = $rawValue; |
68
|
219 |
|
$this->types = $types; |
69
|
219 |
|
$this->flags = $flags; |
70
|
219 |
|
} |
71
|
|
|
|
72
|
|
|
/** |
73
|
|
|
* Retrieve a DTO property instance after validating it |
74
|
|
|
* |
75
|
|
|
* @param string $name |
76
|
|
|
* @param mixed $rawValue |
77
|
|
|
* @param DtoPropertyTypes $types |
78
|
|
|
* @param int $flags |
79
|
|
|
* @return self |
80
|
|
|
* @throws UnexpectedValueException |
81
|
|
|
*/ |
82
|
219 |
|
public static function create(string $name, $rawValue, DtoPropertyTypes $types, int $flags): self |
83
|
|
|
{ |
84
|
219 |
|
$instance = new static($name, $rawValue, $types, $flags); |
85
|
|
|
|
86
|
219 |
|
return $instance->validate(); |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
/** |
90
|
|
|
* Validate the current property value depending on types and flags |
91
|
|
|
* |
92
|
|
|
* @return self |
93
|
|
|
* @throws UnexpectedValueException |
94
|
|
|
*/ |
95
|
219 |
|
public function validate(): self |
96
|
|
|
{ |
97
|
219 |
|
if ($this->rawValue === null) { |
98
|
39 |
|
if ($this->isNullable()) { |
99
|
33 |
|
return $this; |
100
|
|
|
} |
101
|
|
|
|
102
|
6 |
|
throw new UnexpectedValueException($this); |
103
|
|
|
} |
104
|
|
|
|
105
|
192 |
|
if ($this->types->match($this->value())) { |
|
|
|
|
106
|
183 |
|
return $this; |
107
|
|
|
} |
108
|
|
|
|
109
|
9 |
|
throw new UnexpectedValueException($this); |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
/** |
113
|
|
|
* Determine whether this property is nullable |
114
|
|
|
* |
115
|
|
|
* @return bool |
116
|
|
|
*/ |
117
|
45 |
|
public function isNullable(): bool |
118
|
|
|
{ |
119
|
45 |
|
if ($this->flags & NOT_NULLABLE) { |
120
|
6 |
|
return false; |
121
|
|
|
} |
122
|
|
|
|
123
|
39 |
|
return ($this->flags & NULLABLE) || $this->types->includeNull; |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* Retrieve the processed value |
128
|
|
|
* |
129
|
|
|
* @return void |
130
|
|
|
*/ |
131
|
204 |
|
public function value() |
132
|
|
|
{ |
133
|
204 |
|
if ($this->valueIsProcessed) { |
134
|
108 |
|
return $this->processedValue; |
135
|
|
|
} |
136
|
|
|
|
137
|
204 |
|
$this->processedValue = $this->processRawValue(); |
138
|
204 |
|
$this->valueIsProcessed = true; |
139
|
|
|
|
140
|
204 |
|
return $this->processedValue; |
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
/** |
144
|
|
|
* Retrieve the processed raw value |
145
|
|
|
* |
146
|
|
|
* @return mixed |
147
|
|
|
*/ |
148
|
204 |
|
protected function processRawValue() |
149
|
|
|
{ |
150
|
204 |
|
if ($this->rawValue === null) { |
151
|
15 |
|
return null; |
152
|
|
|
} |
153
|
|
|
|
154
|
192 |
|
foreach ($this->types->all as $type) { |
155
|
192 |
|
if (!class_exists($class = $type->name())) { |
156
|
177 |
|
continue; |
157
|
66 |
|
} elseif ($converter = ArrayConverter::instance()->getConverterByClass($class)) { |
158
|
44 |
|
return $converter->toDto($this->rawValue); |
159
|
|
|
} |
160
|
|
|
} |
161
|
|
|
|
162
|
192 |
|
return $this->types->expectedDto ? $this->castRawValueIntoDto() : $this->rawValue; |
163
|
|
|
} |
164
|
|
|
|
165
|
|
|
/** |
166
|
|
|
* Retrieve the raw value casted into a DTO or a collection of DTOs |
167
|
|
|
* |
168
|
|
|
* @return Dto|Dto[]|null |
169
|
|
|
*/ |
170
|
66 |
|
protected function castRawValueIntoDto() |
171
|
|
|
{ |
172
|
66 |
|
$dto = $this->types->expectedDto; |
173
|
|
|
|
174
|
66 |
|
if (!$this->types->expectCollection) { |
175
|
54 |
|
return is_a($this->rawValue, $dto) ? $this->rawValue : $dto::make($this->rawValue, $this->flags); |
176
|
|
|
} |
177
|
|
|
|
178
|
|
|
return array_map(function ($data) use ($dto) { |
179
|
9 |
|
return is_a($data, $dto) ? $data : $dto::make($data, $this->flags); |
180
|
15 |
|
}, $this->rawValue); |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
/** |
184
|
|
|
* Retrieve the property name |
185
|
|
|
* |
186
|
|
|
* @return string |
187
|
|
|
*/ |
188
|
30 |
|
public function getName(): string |
189
|
|
|
{ |
190
|
30 |
|
return $this->name; |
191
|
|
|
} |
192
|
|
|
|
193
|
|
|
/** |
194
|
|
|
* Retrieve the property raw value |
195
|
|
|
* |
196
|
|
|
* @return mixed |
197
|
|
|
*/ |
198
|
42 |
|
public function getRawValue() |
199
|
|
|
{ |
200
|
42 |
|
return $this->rawValue; |
201
|
|
|
} |
202
|
|
|
|
203
|
|
|
/** |
204
|
|
|
* Retrieve the property types |
205
|
|
|
* |
206
|
|
|
* @return DtoPropertyTypes |
207
|
|
|
*/ |
208
|
186 |
|
public function getTypes(): DtoPropertyTypes |
209
|
|
|
{ |
210
|
186 |
|
return $this->types; |
211
|
|
|
} |
212
|
|
|
|
213
|
|
|
/** |
214
|
|
|
* Retrieve the DTO flags |
215
|
|
|
* |
216
|
|
|
* @return int |
217
|
|
|
*/ |
218
|
15 |
|
public function getFlags(): int |
219
|
|
|
{ |
220
|
15 |
|
return $this->flags; |
221
|
|
|
} |
222
|
|
|
|
223
|
|
|
/** |
224
|
|
|
* Set a new value to this property and validate it |
225
|
|
|
* |
226
|
|
|
* @param mixed $rawValue |
227
|
|
|
* @param int $flags |
228
|
|
|
* @return self |
229
|
|
|
*/ |
230
|
24 |
|
public function setValue($rawValue, int $flags): self |
231
|
|
|
{ |
232
|
24 |
|
$this->rawValue = $rawValue; |
233
|
24 |
|
$this->flags = $flags; |
234
|
24 |
|
$this->valueIsProcessed = false; |
235
|
|
|
|
236
|
24 |
|
return $this->validate(); |
237
|
|
|
} |
238
|
|
|
|
239
|
|
|
/** |
240
|
|
|
* Determine how to clone the DTO property |
241
|
|
|
* |
242
|
|
|
* @return void |
243
|
|
|
*/ |
244
|
21 |
|
public function __clone() |
245
|
|
|
{ |
246
|
21 |
|
$this->types = clone $this->types; |
247
|
21 |
|
} |
248
|
|
|
} |
249
|
|
|
|
This check looks for function or method calls that always return null and whose return value is used.
The method
getObject()
can return nothing but null, so it makes no sense to use the return value.The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.