Property   A
last analyzed

Complexity

Total Complexity 33

Size/Duplication

Total Lines 177
Duplicated Lines 0 %

Test Coverage

Coverage 92.11%

Importance

Changes 0
Metric Value
wmc 33
eloc 57
dl 0
loc 177
ccs 70
cts 76
cp 0.9211
rs 9.76
c 0
b 0
f 0

19 Methods

Rating   Name   Duplication   Size   Complexity  
A reset() 0 8 2
A __construct() 0 3 1
A disableAutoValidation() 0 17 5
A initViolations() 0 5 2
A set() 0 6 1
A boot() 0 4 1
A setDefault() 0 3 1
A getDefault() 0 3 1
A isValid() 0 3 2
A setViolations() 0 3 1
A isImmutable() 0 3 1
A isInitialized() 0 3 1
A chainImmutable() 0 9 5
A isVisible() 0 3 1
A setVisible() 0 3 1
A getValue() 0 3 1
A getName() 0 3 1
A getViolations() 0 3 1
A validate() 0 15 4
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
        }
95 15
    }
96
97 43
    public function isInitialized()
98
    {
99 43
        return $this->initialized;
100
    }
101
102 41
    public function validate($value): ?ConstraintViolationListInterface
103
    {
104 41
        $constraints = $this->data->getConstraints();
105
106 41
        $violations = (new ValidatorBuilder())->getValidator()->validate($value, $constraints);
107
108 41
        if (! $this->isInitialized() && ! $this->data->isOptional()) {
109
            $violations->add(new PropertyRequiredViolation());
110
        }
111
112 41
        if (! $this->data->getType()->isValid($value)) {
113 8
            $violations->add(new InvalidPropertyTypeViolation($this->data->getType()->getTypes()));
114
        }
115
116 41
        return $violations;
117
    }
118
119
    public function isValid()
120
    {
121
        return $this->violations === null || $this->violations->count() <= 0;
122
    }
123
124
    /**
125
     * @return ConstraintViolationListInterface|null
126
     */
127 37
    public function getViolations(): ?ConstraintViolationListInterface
128
    {
129 37
        return $this->violations;
130
    }
131
132 44
    public function setViolations(?ConstraintViolationListInterface $violationList): ?ConstraintViolationListInterface
133
    {
134 44
        return $this->violations = $violationList;
135
    }
136
137 36
    public function isImmutable()
138
    {
139 36
        return $this->data->isImmutable();
140
    }
141
142 32
    public function getValue()
143
    {
144 32
        return $this->value;
145
    }
146
147 44
    public function getName()
148
    {
149 44
        return $this->data->getName();
150
    }
151
152
    /**
153
     * @return bool
154
     */
155 14
    public function isVisible(): bool
156
    {
157 14
        return $this->visible;
158
    }
159
160
    /**
161
     * @param bool $visible
162
     */
163 1
    public function setVisible(bool $visible): void
164
    {
165 1
        $this->visible = $visible;
166 1
    }
167
168
    /**
169
     * @return mixed
170
     */
171
    public function getDefault()
172
    {
173
        return $this->default;
174
    }
175
176
    /**
177
     * @param mixed $default
178
     */
179 35
    public function setDefault($default): void
180
    {
181 35
        $this->default = $default;
182 35
    }
183
184 8
    public function chainImmutable($immutable)
185
    {
186 8
        $dto = $this->getValue();
187 8
        if ($dto instanceof DataTransferObject) {
188
            $dto->setImmutable($immutable);
189 8
        } elseif (is_iterable($dto)) {
190 1
            foreach ($dto as $aPotentialDto) {
191 1
                if ($aPotentialDto instanceof DataTransferObject) {
192 1
                    $aPotentialDto->setImmutable($immutable);
193
                }
194
            }
195
        }
196 8
    }
197
}
198