Passed
Push — master ( a5c78b...c47e5f )
by Alexander
02:21
created

Rules   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 89
Duplicated Lines 0 %

Test Coverage

Coverage 88.37%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 36
c 2
b 0
f 0
dl 0
loc 89
ccs 38
cts 43
cp 0.8837
rs 10
wmc 19

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 2
A asArray() 0 9 3
A withFormatter() 0 6 1
A add() 0 7 3
A normalizeRule() 0 15 3
A validate() 0 13 4
A addFormatterToRules() 0 5 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Validator;
6
7
use InvalidArgumentException;
8
use Yiisoft\Validator\Rule\Callback;
9
use function is_callable;
10
11
/**
12
 * Rules represents multiple rules for a single value
13
 */
14
final class Rules
15
{
16
    private ?FormatterInterface $formatter = null;
17
18
    /**
19
     * @var RuleInterface[]
20
     */
21
    private array $rules = [];
22
23 16
    public function __construct(iterable $rules = [])
24
    {
25 16
        foreach ($rules as $rule) {
26 15
            $this->add($rule);
27
        }
28 16
    }
29
30
    /**
31
     * @param callable|RuleInterface $rule
32
     */
33 16
    public function add($rule): void
34
    {
35 16
        $rule = $this->normalizeRule($rule);
36 16
        if ($this->formatter !== null && $rule instanceof FormattableRuleInterface) {
37
            $rule = $rule->withFormatter($this->formatter);
38
        }
39 16
        $this->rules[] = $rule;
40 16
    }
41
42 10
    public function validate($value, DataSetInterface $dataSet = null, bool $previousRulesErrored = false): Result
43
    {
44 10
        $compoundResult = new Result();
45 10
        foreach ($this->rules as $rule) {
46 10
            $ruleResult = $rule->validate($value, $dataSet, $previousRulesErrored);
47 10
            if ($ruleResult->isValid() === false) {
48 10
                $previousRulesErrored = true;
49 10
                foreach ($ruleResult->getErrors() as $message) {
50 10
                    $compoundResult->addError($message);
51
                }
52
            }
53
        }
54 10
        return $compoundResult;
55
    }
56
57 16
    private function normalizeRule($rule): RuleInterface
58
    {
59 16
        if (is_callable($rule)) {
60 2
            $rule = new Callback($rule);
61
        }
62
63 16
        if (!$rule instanceof RuleInterface) {
64
            throw new InvalidArgumentException(sprintf(
65
                'Rule should be either an instance of %s or a callable, %s given.',
66
                RuleInterface::class,
67
                gettype($rule)
68
            ));
69
        }
70
71 16
        return $rule;
72
    }
73
74 1
    public function withFormatter(?FormatterInterface $formatter): self
75
    {
76 1
        $new = clone $this;
77 1
        $new->formatter = $formatter;
78 1
        $new->addFormatterToRules($formatter);
79 1
        return $new;
80
    }
81
82
    /**
83
     * Return rules as array.
84
     *
85
     * @return array
86
     */
87 5
    public function asArray(): array
88
    {
89 5
        $arrayOfRules = [];
90 5
        foreach ($this->rules as $rule) {
91 5
            if ($rule instanceof ParametrizedRuleInterface) {
92 5
                $arrayOfRules[] = array_merge([$rule->getName()], $rule->getOptions());
93
            }
94
        }
95 5
        return $arrayOfRules;
96
    }
97
98 1
    private function addFormatterToRules(?FormatterInterface $formatter): void
99
    {
100 1
        foreach ($this->rules as &$rule) {
101 1
            if ($rule instanceof FormattableRuleInterface) {
102 1
                $rule = $rule->withFormatter($formatter);
103
            }
104
        }
105 1
    }
106
}
107