Completed
Push — master ( 11225d...73b999 )
by Alexpts
01:48
created

Validator::__construct()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 24
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 22
CRAP Score 1

Importance

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