Completed
Pull Request — master (#7)
by Albert
02:45
created

Validator::validate()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 5.0909

Importance

Changes 0
Metric Value
dl 0
loc 24
c 0
b 0
f 0
ccs 11
cts 13
cp 0.8462
rs 8.5125
cc 5
eloc 14
nc 5
nop 1
crap 5.0909
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Albert221\Validation;
6
7
use Albert221\Validation\Rule\Validator\RuleValidator;
8
use InvalidArgumentException;
9
use RuntimeException;
10
use Symfony\Component\PropertyAccess\PropertyAccess;
11
12
class Validator
13
{
14
    /**
15
     * @var RuleValidatorFactory
16
     */
17
    private $ruleValidatorFactory;
18
19
    /**
20
     * @var Field[]
21
     */
22
    private $fields = [];
23
24
    /**
25
     * @return Validator
26
     */
27 2
    public static function build()
28
    {
29 2
        return new self();
30
    }
31
32
    /**
33
     * Validator constructor.
34
     */
35 2
    public function __construct()
36
    {
37 2
        $this->ruleValidatorFactory = new RuleValidatorFactory();
38 2
    }
39
40
    /**
41
     * @return Field[]
42
     */
43
    public function getFields(): array
44
    {
45
        return $this->fields;
46
    }
47
48
    /**
49
     * @param Validator $validatorBuilder
50
     *
51
     * @return Validator
52
     */
53
    public function merge(Validator $validatorBuilder): self
54
    {
55
        foreach ($validatorBuilder->getFields() as $field) {
56
            $this->addRawField($field);
57
        }
58
59
        return $this;
60
    }
61
62
    /**
63
     * @param Field $field
64
     *
65
     * @return Field
66
     */
67 2
    public function addRawField(Field $field)
68
    {
69 2
        if (array_key_exists($field->getName(), $this->fields)) {
70
            throw new InvalidArgumentException(sprintf(
71
                'Field with name "%s" already exists.',
72
                $field->getName()
73
            ));
74
        }
75
76 2
        return $this->fields[$field->getName()] = $field;
77
    }
78
79
    /**
80
     * @param string $name
81
     *
82
     * @return Field
83
     */
84 2
    public function addField(string $name): Field
85
    {
86 2
        return $this->addRawField(new Field($name, $this));
87
    }
88
89
    /**
90
     * @param $data
91
     *
92
     * @return VerdictList
93
     */
94 2
    public function validate($data): VerdictList
95
    {
96 2
        $propertyAccessor = PropertyAccess::createPropertyAccessor();
97
98 2
        $verdicts = [];
99 2
        foreach ($this->fields as $field) {
100
            try {
101 2
                $value = $propertyAccessor->getValue(
102 2
                    $data,
103 2
                    is_array($data) ? "[" . $field->getName() . "]" : $field->getName()
104
                );
105
            } catch (RuntimeException $e) {
106
                $value = null;
107
            }
108
109 2
            foreach ($field->getRules() as $rule) {
110 2
                $ruleValidator = $this->ruleValidatorFactory->getInstance($rule);
111
112 2
                $verdicts[] = $ruleValidator->verdict($value, $rule);
113
            }
114
        }
115
116 2
        return new VerdictList($verdicts);
117
    }
118
}
119