Completed
Push — master ( dd9385...7bb1ab )
by Alexpts
04:21
created

Validator::getValue()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 3
cts 3
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 3
crap 1
1
<?php
2
3
namespace PTS\Validator;
4
5
use PTS\Tools\DeepArray;
6
use PTS\Validator\Validators\AlphaDashValidator;
7
use PTS\Validator\Validators\AlphaNumValidator;
8
use PTS\Validator\Validators\AlphaValidator;
9
use PTS\Validator\Validators\BetweenIntValidator;
10
use PTS\Validator\Validators\BoolValidator;
11
use PTS\Validator\Validators\DateTimeValidator;
12
use PTS\Validator\Validators\DateValidator;
13
use PTS\Validator\Validators\InArrayValidator;
14
use PTS\Validator\Validators\MaxValidator;
15
use PTS\Validator\Validators\MinValidator;
16
use PTS\Validator\Validators\RequiredValidator;
17
18
class Validator
19
{
20
    /** @var bool */
21
    protected $paramDelimiter = ':';
22
    protected $keysDelimiter = '.';
23
24
    /** @var DeepArray */
25
    protected $deepArrayService;
26
27
    /** @var ValidatorRuleException */
28
    protected $notExistValue;
29
30
    /** @var callable[] */
31
    protected $rulesHandlers = [];
32
33 46
    public function __construct(DeepArray $deepArrayService)
34
    {
35 46
        $this->notExistValue = new ValidatorRuleException('Value is not exists');
36 46
        $this->deepArrayService = $deepArrayService;
37
38 46
        $this->registerRule('string', 'is_string')
39 46
            ->registerRule('int', 'is_int')
40 46
            ->registerRule('array', 'is_array')
41 46
            ->registerRule('required', new RequiredValidator)
42 46
            ->registerRule('betweenInt', new BetweenIntValidator)
43 46
            ->registerRule('strictBool', 'is_bool')
44 46
            ->registerRule('bool', new BoolValidator)
45 46
            ->registerRule('alpha', new AlphaValidator)
46 46
            ->registerRule('alphaDash', new AlphaDashValidator)
47 46
            ->registerRule('alphaNum', new AlphaNumValidator)
48 46
            ->registerRule('date', new DateValidator)
49 46
            ->registerRule('dateTime', new DateTimeValidator)
50 46
            ->registerRule('inArray', new InArrayValidator)
51 46
            ->registerRule('min', new MinValidator)
52 46
            ->registerRule('max', new MaxValidator);
53 46
    }
54
55
    /**
56
     * @param string $name
57
     * @param callable $handler
58
     * @return $this
59
     */
60 46
    public function registerRule(string $name, callable $handler): self
61
    {
62 46
        $this->rulesHandlers[$name] = $handler;
63 46
        return $this;
64
    }
65
66 2
    public function getRules(): array
67
    {
68 2
        return $this->rulesHandlers;
69
    }
70
71 38
    public function validate(array $data, array $rules, bool $validateIfExist = false): array
72
    {
73 38
        $errors = [];
74
75 38
        foreach ($rules as $name => $attrRules) {
76 38
            $value = $this->getValue($name, $data, $this->notExistValue);
77
78 38
            if (!($value instanceof $this->notExistValue)) {
79 38
                $errors[$name] = $this->validateValue($value, $attrRules);
80 37
                continue;
81
            }
82
83 2
            if (!$validateIfExist) {
84 2
                $errors[$name] = 'Value is not exists or bad: ' . $name;
85
            }
86
        }
87
88 37
        return array_filter($errors);
89
    }
90
91 30
    public function validateIfExists(array $data, array $rules): array
92
    {
93 30
       return $this->validate($data, $rules, true);
94
    }
95
96
    /**
97
     * @param string $name
98
     * @param array $data
99
     * @param mixed $default
100
     * @return mixed
101
     */
102 38
    protected function getValue(string $name, array $data, $default)
103
    {
104 38
        $names = explode($this->keysDelimiter, $name);
105 38
        return $this->deepArrayService->getAttr($names, $data, $default);
106
    }
107
108 38
    protected function validateValue($value, array $rules): array
109
    {
110 38
        $errors = [];
111
112 38
        foreach ($rules as $rule) {
113 38
            list($handlerAlias, $params) = is_string($rule)
114 35
                ? $this->extractStringRule($rule)
115 38
                : $this->extractArrayRule($rule);
116
117 38
            $handler = $this->rulesHandlers[$handlerAlias] ?? null;
118
119 38
            if (!$handler) {
120 1
                throw new ValidatorRuleException("Handler not found for alias: {$handlerAlias}");
121
            }
122
123 38
            if (!$handler($value, ...$params)) {
124 38
                $errors[] = $handlerAlias;
125
            }
126
        }
127
128 37
        return $errors;
129
    }
130
131 6
    public function extractArrayRule(array $rule): array
132
    {
133 6
        return [key($rule), current($rule)];
134
    }
135
136 38
    public function extractStringRule(string $rule): array
137
    {
138 38
        $params = explode($this->paramDelimiter, $rule);
139 38
        $handlerAlias = array_shift($params);
140
141 38
        return [$handlerAlias, (array)$params];
142
    }
143
}
144