Passed
Pull Request — master (#99)
by Def
02:07
created

Rule::translator()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 5
ccs 4
cts 4
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Validator;
6
7
/**
8
 * Rule represents a single value validation rule.
9
 */
10
abstract class Rule
11
{
12
    private bool $skipOnEmpty = false;
13
    private bool $skipOnError = true;
14
15
    /**
16
     * @var callable|null
17
     */
18
    private $when = null;
19
20
    /**
21
     * Validates the value
22
     *
23
     * @param mixed $value value to be validated
24
     * @param DataSetInterface|null $dataSet optional data set that could be used for contextual validation
25
     * @param bool $previousRulesErrored set to true if rule is part of a group of rules and one of the previous validations failed
26
     *
27
     * @return Result
28
     */
29 137
    final public function validate($value, DataSetInterface $dataSet = null, bool $previousRulesErrored = false): Result
30
    {
31 137
        if ($this->skipOnEmpty && $this->isEmpty($value)) {
32
            return new Result();
33
        }
34
35
        if (
36 137
          ($this->skipOnError && $previousRulesErrored) ||
37 137
          (is_callable($this->when) && !($this->when)($value, $dataSet))
38
        ) {
39 6
            return new Result();
40
        }
41
42 137
        return $this->validateValue($value, $dataSet);
43
    }
44
45
    /**
46
     * Validates the value. The method should be implemented by concrete validation rules.
47
     *
48
     * @param mixed $value value to be validated
49
     * @param DataSetInterface|null $dataSet optional data set that could be used for contextual validation
50
     *
51
     * @return Result
52
     */
53
    abstract protected function validateValue($value, DataSetInterface $dataSet = null): Result;
54
55
    /**
56
     * Add a PHP callable whose return value determines whether this rule should be applied.
57
     * By default rule will be always applied.
58
     *
59
     * The signature of the callable should be `function ($value, DataSetInterface $dataSet): bool`, where $value and $dataSet
60
     * refer to the value validated and the data set in which context it is validated. The callable should return
61
     * a boolean value.
62
     *
63
     * The following example will enable the validator only when the country currently selected is USA:
64
     *
65
     * ```php
66
     * function ($value, DataSetInterface $dataSet) {
67
         return $dataSet->getAttributeValue('country') === Country::USA;
68
     }
69
     * ```
70
     *
71
     * @param callable $callback
72
     *
73
     * @return $this
74
     */
75 1
    public function when(callable $callback): self
76
    {
77 1
        $new = clone $this;
78 1
        $new->when = $callback;
79 1
        return $new;
80
    }
81
82 3
    public function skipOnError(bool $value): self
83
    {
84 3
        $new = clone $this;
85 3
        $new->skipOnError = $value;
86 3
        return $new;
87
    }
88
89
    /**
90
     * @param bool $value if validation should be skipped if value validated is empty
91
     *
92
     * @return self
93
     */
94 1
    public function skipOnEmpty(bool $value): self
95
    {
96 1
        $new = clone $this;
97 1
        $new->skipOnEmpty = $value;
98 1
        return $new;
99
    }
100
101
    /**
102
     * Checks if the given value is empty.
103
     * A value is considered empty if it is null, an empty array, or an empty string.
104
     * Note that this method is different from PHP empty(). It will return false when the value is 0.
105
     *
106
     * @param mixed $value the value to be checked
107
     *
108
     * @return bool whether the value is empty
109
     */
110 10
    protected function isEmpty($value): bool
111
    {
112 10
        return $value === null || $value === [] || $value === '';
113
    }
114
115
    /**
116
     * Get name of the rule to be used when rule is converted to array.
117
     * By default it returns base name of the class, first letter in lowercase.
118
     *
119
     * @return string
120
     */
121 20
    public function getName(): string
122
    {
123 20
        $className = static::class;
124 20
        return lcfirst(substr($className, strrpos($className, '\\') + 1));
125
    }
126
127
    /**
128
     * Returns rule options as array.
129
     *
130
     * @return array
131
     */
132 57
    public function getOptions(): array
133
    {
134
        return [
135 57
            'skipOnEmpty' => $this->skipOnEmpty,
136 57
            'skipOnError' => $this->skipOnError,
137
        ];
138
    }
139
}
140