Passed
Push — master ( d84220...b277f2 )
by Arthur
01:56 queued 10s
created

Property::setDefault()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Larapie\DataTransferObject\Property;
6
7
use ReflectionProperty;
8
use Symfony\Component\Validator\ValidatorBuilder;
9
use Larapie\DataTransferObject\Casters\TypeCaster;
10
use Larapie\DataTransferObject\DataTransferObject;
11
use Symfony\Component\Validator\ConstraintViolationList;
12
use Symfony\Component\Validator\ConstraintViolationListInterface;
13
use Larapie\DataTransferObject\Violations\PropertyRequiredViolation;
14
use Larapie\DataTransferObject\Violations\InvalidPropertyTypeViolation;
15
16
class Property
17
{
18
    /** @var PropertyData */
19
    protected $data;
20
21
    /** @var mixed */
22
    public $value;
23
24
    /** @var mixed */
25
    protected $default;
26
27
    /** @var bool */
28
    protected $initialized = false;
29
30
    /** @var bool */
31
    protected $visible = true;
32
33
    /** @var ConstraintViolationListInterface|null */
34
    protected $violations;
35
36
    /**
37
     * PropertyValue constructor.
38
     * @param ReflectionProperty $reflection
39
     */
40 36
    public function __construct(ReflectionProperty $reflection)
41
    {
42 36
        $this->boot($reflection);
43 35
    }
44
45 36
    public function boot(ReflectionProperty $property)
46
    {
47 36
        $this->data = new PropertyData($property);
48 35
        $this->initViolations();
49 35
    }
50
51 44
    protected function initViolations()
52
    {
53 44
        $this->setViolations(new ConstraintViolationList());
54 44
        if (!$this->data->isOptional()) {
55 42
            $this->violations->add(new PropertyRequiredViolation());
0 ignored issues
show
Bug introduced by
The method add() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

55
            $this->violations->/** @scrutinizer ignore-call */ 
56
                               add(new PropertyRequiredViolation());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
56
        }
57 44
    }
58
59 41
    public function set($value): void
60
    {
61 41
        $value = (new TypeCaster($this->data->getType()))->cast($value);
62 41
        $this->value = $this->disableAutoValidation($value);
63 41
        $this->initialized = true;
64 41
        $this->setViolations($this->validate($value));
65 41
    }
66
67 41
    protected function disableAutoValidation($value)
68
    {
69 41
        if (is_iterable($value)) {
70 7
            $values = [];
71 7
            foreach ($value as $potentialDto) {
72 6
                if ($potentialDto instanceof DataTransferObject) {
73 4
                    $potentialDto->disableValidation();
74 6
                    $values[] = $potentialDto;
75
                }
76
            }
77
78 7
            return $values;
79 38
        } elseif ($value instanceof DataTransferObject) {
80 6
            $value->disableValidation();
81
        }
82
83 38
        return $value;
84
    }
85
86 15
    public function reset()
87
    {
88 15
        $this->value = null;
89 15
        $this->initialized = false;
90 15
        $this->initViolations();
91
92 15
        if ($this->default !== null)
93 1
            $this->set($this->default);
94 15
    }
95
96 43
    public function isInitialized()
97
    {
98 43
        return $this->initialized;
99
    }
100
101 41
    public function validate($value): ?ConstraintViolationListInterface
102
    {
103 41
        $constraints = $this->data->getConstraints();
104
105 41
        $violations = (new ValidatorBuilder())->getValidator()->validate($value, $constraints);
106
107 41
        if (!$this->isInitialized() && !$this->data->isOptional()) {
108
            $violations->add(new PropertyRequiredViolation());
109
        }
110
111 41
        if (!$this->data->getType()->isValid($value)) {
112 8
            $violations->add(new InvalidPropertyTypeViolation($this->data->getType()->getTypes()));
113
        }
114
115 41
        return $violations;
116
    }
117
118
    public function isValid()
119
    {
120
        return $this->violations === null || $this->violations->count() <= 0;
121
    }
122
123
    /**
124
     * @return ConstraintViolationListInterface|null
125
     */
126 37
    public function getViolations(): ?ConstraintViolationListInterface
127
    {
128 37
        return $this->violations;
129
    }
130
131 44
    public function setViolations(?ConstraintViolationListInterface $violationList): ?ConstraintViolationListInterface
132
    {
133 44
        return $this->violations = $violationList;
134
    }
135
136 36
    public function isImmutable()
137
    {
138 36
        return $this->data->isImmutable();
139
    }
140
141 32
    public function getValue()
142
    {
143 32
        return $this->value;
144
    }
145
146 44
    public function getName()
147
    {
148 44
        return $this->data->getName();
149
    }
150
151
    /**
152
     * @return bool
153
     */
154 14
    public function isVisible(): bool
155
    {
156 14
        return $this->visible;
157
    }
158
159
    /**
160
     * @param bool $visible
161
     */
162 1
    public function setVisible(bool $visible): void
163
    {
164 1
        $this->visible = $visible;
165 1
    }
166
167
    /**
168
     * @return mixed
169
     */
170
    public function getDefault()
171
    {
172
        return $this->default;
173
    }
174
175
    /**
176
     * @param mixed $default
177
     */
178 35
    public function setDefault($default): void
179
    {
180 35
        $this->default = $default;
181 35
    }
182
183 8
    public function chainImmutable($immutable)
184
    {
185 8
        $dto = $this->getValue();
186 8
        if ($dto instanceof DataTransferObject) {
187
            $dto->setImmutable($immutable);
188 8
        } elseif (is_iterable($dto)) {
189 1
            foreach ($dto as $aPotentialDto) {
190 1
                if ($aPotentialDto instanceof DataTransferObject) {
191 1
                    $aPotentialDto->setImmutable($immutable);
192
                }
193
            }
194
        }
195 8
    }
196
}
197