Passed
Push — master ( 0c064e...87b116 )
by Arthur
08:29 queued 10s
created

Property::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Larapie\DataTransferObject\Property;
6
7
use Larapie\DataTransferObject\DataTransferObject;
8
use ReflectionProperty;
9
use Symfony\Component\Validator\ValidatorBuilder;
10
use Larapie\DataTransferObject\Casters\TypeCaster;
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 bool */
25
    protected $initialized = false;
26
27
    /** @var bool */
28
    protected $visible = true;
29
30
    /** @var ConstraintViolationListInterface|null */
31
    protected $violations;
32
33
    /**
34
     * PropertyValue constructor.
35
     * @param ReflectionProperty $reflection
36
     */
37
    public function __construct(ReflectionProperty $reflection)
38
    {
39
        $this->boot($reflection);
40
    }
41
42
    public function boot(ReflectionProperty $property)
43
    {
44
        $this->data = new PropertyData($property);
45
        $this->initViolations();
46
    }
47
48
    protected function initViolations()
49
    {
50
        $this->setViolations(new ConstraintViolationList());
51
        if (!$this->data->isOptional()) {
52
            $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

52
            $this->violations->/** @scrutinizer ignore-call */ 
53
                               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...
53
        }
54
    }
55
56
    public function set($value): void
57
    {
58
        $value = (new TypeCaster($this->data->getType()))->cast($value);
59
        $this->value = $this->disableAutoValidation($value);
60
        $this->initialized = true;
61
        $this->setViolations($this->validate($value));
62
    }
63
64
    protected function disableAutoValidation($value){
65
        if(is_iterable($value)){
66
            $values = [];
67
            foreach($value as $potentialDto){
68
                if($potentialDto instanceof DataTransferObject){
69
                    $potentialDto->setValidation(false);
70
                    $values[] = $potentialDto;
71
                }
72
            }
73
            return $values;
74
        }
75
        elseif ($value instanceof DataTransferObject){
76
            $value->setValidation(false);
77
        }
78
        return $value;
79
    }
80
81
    public function reset()
82
    {
83
        $this->value = null;
84
        $this->initialized = false;
85
        $this->initViolations();
86
    }
87
88
    public function isInitialized()
89
    {
90
        return $this->initialized;
91
    }
92
93
    public function validate($value): ?ConstraintViolationListInterface
94
    {
95
        $constraints = $this->data->getConstraints();
96
97
        $violations = (new ValidatorBuilder())->getValidator()->validate($value, $constraints);
98
99
        if (!$this->isInitialized() && !$this->data->isOptional()) {
100
            $violations->add(new PropertyRequiredViolation());
101
        }
102
        if (!$this->data->getType()->isValid($value)) {
103
            $violations->add(new InvalidPropertyTypeViolation($this->data->getType()->getTypes()));
104
        }
105
106
        return $violations;
107
    }
108
109
    public function isValid()
110
    {
111
        return $this->violations === null || $this->violations->count() <= 0;
112
    }
113
114
    /**
115
     * @return ConstraintViolationListInterface|null
116
     */
117
    public function getViolations(): ?ConstraintViolationListInterface
118
    {
119
        return $this->violations;
120
    }
121
122
    public function setViolations(?ConstraintViolationListInterface $violationList): ?ConstraintViolationListInterface
123
    {
124
        return $this->violations = $violationList;
125
    }
126
127
    public function isImmutable()
128
    {
129
        return $this->data->isImmutable();
130
    }
131
132
    public function getValue()
133
    {
134
        return $this->value;
135
    }
136
137
    public function getName()
138
    {
139
        return $this->data->getName();
140
    }
141
142
    /**
143
     * @return bool
144
     */
145
    public function isVisible(): bool
146
    {
147
        return $this->visible;
148
    }
149
150
    /**
151
     * @param bool $visible
152
     */
153
    public function setVisible(bool $visible): void
154
    {
155
        $this->visible = $visible;
156
    }
157
}
158