Passed
Branch feature/first-implementation (30573d)
by Andrea Marco
02:38
created

DtoProperty   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 217
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 45
c 1
b 0
f 0
dl 0
loc 217
ccs 50
cts 50
cp 1
rs 10
wmc 23

12 Methods

Rating   Name   Duplication   Size   Complexity  
A create() 0 5 1
A __construct() 0 6 1
A getRawValue() 0 3 1
A value() 0 10 3
A validate() 0 15 4
A getTypes() 0 3 1
A isNullable() 0 7 3
A getName() 0 3 1
A setValue() 0 7 1
A __clone() 0 3 1
A castRawValueIntoDto() 0 15 5
A getFlags() 0 3 1
1
<?php
2
3
namespace Cerbero\Dto;
4
5
use Cerbero\Dto\Exceptions\UnexpectedValueException;
6
7
/**
8
 * The DTO property.
9
 *
10
 */
11
class DtoProperty
12
{
13
    /**
14
     * The property name.
15
     *
16
     * @var string
17
     */
18
    protected $name;
19
20
    /**
21
     * The property raw value.
22
     *
23
     * @var mixed
24
     */
25
    protected $rawValue;
26
27
    /**
28
     * The property types.
29
     *
30
     * @var DtoPropertyTypes
31
     */
32
    protected $types;
33
34
    /**
35
     * The DTO flags.
36
     *
37
     * @var int
38
     */
39
    protected $flags;
40
41
    /**
42
     * The processed value.
43
     *
44
     * @var mixed
45
     */
46
    protected $processedValue;
47
48
    /**
49
     * Whether the value has been processed.
50
     *
51
     * @var bool
52
     */
53
    protected $valueIsProcessed = false;
54
55
    /**
56
     * Instantiate the class.
57
     *
58
     * @param string $name
59
     * @param mixed $rawValue
60
     * @param DtoPropertyTypes $types
61
     * @param int $flags
62
     */
63 177
    protected function __construct(string $name, $rawValue, DtoPropertyTypes $types, int $flags)
64
    {
65 177
        $this->name = $name;
66 177
        $this->rawValue = $rawValue;
67 177
        $this->types = $types;
68 177
        $this->flags = $flags;
69 177
    }
70
71
    /**
72
     * Retrieve a DTO property instance after validating it
73
     *
74
     * @param string $name
75
     * @param mixed $rawValue
76
     * @param DtoPropertyTypes $types
77
     * @param int $flags
78
     * @return self
79
     * @throws UnexpectedValueException
80
     */
81 177
    public static function create(string $name, $rawValue, DtoPropertyTypes $types, int $flags): self
82
    {
83 177
        $instance = new static($name, $rawValue, $types, $flags);
84
85 177
        return $instance->validate();
86
    }
87
88
    /**
89
     * Validate the current property value depending on types and flags
90
     *
91
     * @return self
92
     * @throws UnexpectedValueException
93
     */
94 177
    public function validate(): self
95
    {
96 177
        if ($this->rawValue === null) {
97 36
            if ($this->isNullable()) {
98 30
                return $this;
99
            }
100
101 6
            throw new UnexpectedValueException($this);
102
        }
103
104 150
        if ($this->types->match($this->value())) {
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->value() targeting Cerbero\Dto\DtoProperty::value() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

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.

Loading history...
105 147
            return $this;
106
        }
107
108 3
        throw new UnexpectedValueException($this);
109
    }
110
111
    /**
112
     * Determine whether this property is nullable
113
     *
114
     * @return bool
115
     */
116 42
    public function isNullable(): bool
117
    {
118 42
        if ($this->flags & NOT_NULLABLE) {
119 6
            return false;
120
        }
121
122 36
        return ($this->flags & NULLABLE) || $this->types->includeNull;
123
    }
124
125
    /**
126
     * Retrieve the processed value
127
     *
128
     * @return void
129
     */
130 162
    public function value()
131
    {
132 162
        if ($this->valueIsProcessed) {
133 84
            return $this->processedValue;
134
        }
135
136 162
        $this->processedValue = $this->types->expectedDto ? $this->castRawValueIntoDto() : $this->rawValue;
137 162
        $this->valueIsProcessed = true;
138
139 162
        return $this->processedValue;
140
    }
141
142
    /**
143
     * Retrieve the raw value casted into a DTO or a collection of DTOs
144
     *
145
     * @return Dto|Dto[]|null
146
     */
147 51
    protected function castRawValueIntoDto()
148
    {
149 51
        if ($this->rawValue === null) {
150 6
            return null;
151
        }
152
153 48
        $dto = $this->types->expectedDto;
154
155 48
        if (!$this->types->expectCollection) {
156 36
            return is_a($this->rawValue, $dto) ? $this->rawValue : $dto::make($this->rawValue, $this->flags);
157
        }
158
159
        return array_map(function ($data) use ($dto) {
160 9
            return is_a($data, $dto) ? $data : $dto::make($data, $this->flags);
161 15
        }, $this->rawValue);
162
    }
163
164
    /**
165
     * Retrieve the property name
166
     *
167
     * @return string
168
     */
169 24
    public function getName(): string
170
    {
171 24
        return $this->name;
172
    }
173
174
    /**
175
     * Retrieve the property raw value
176
     *
177
     * @return mixed
178
     */
179 36
    public function getRawValue()
180
    {
181 36
        return $this->rawValue;
182
    }
183
184
    /**
185
     * Retrieve the property types
186
     *
187
     * @return DtoPropertyTypes
188
     */
189 144
    public function getTypes(): DtoPropertyTypes
190
    {
191 144
        return $this->types;
192
    }
193
194
    /**
195
     * Retrieve the DTO flags
196
     *
197
     * @return int
198
     */
199 15
    public function getFlags(): int
200
    {
201 15
        return $this->flags;
202
    }
203
204
    /**
205
     * Set a new value to this property and validate it
206
     *
207
     * @param mixed $rawValue
208
     * @param int $flags
209
     * @return self
210
     */
211 15
    public function setValue($rawValue, int $flags): self
212
    {
213 15
        $this->rawValue = $rawValue;
214 15
        $this->flags = $flags;
215 15
        $this->valueIsProcessed = false;
216
217 15
        return $this->validate();
218
    }
219
220
    /**
221
     * Determine how to clone the DTO property
222
     *
223
     * @return void
224
     */
225 15
    public function __clone()
226
    {
227 15
        $this->types = clone $this->types;
228 15
    }
229
}
230