Passed
Pull Request — master (#199)
by Alexander
02:44
created

RuleSet   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 77
Duplicated Lines 0 %

Test Coverage

Coverage 93.33%

Importance

Changes 0
Metric Value
eloc 30
dl 0
loc 77
ccs 28
cts 30
cp 0.9333
rs 10
c 0
b 0
f 0
wmc 13

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 2
A asArray() 0 11 3
A normalizeRule() 0 15 3
A validate() 0 18 4
A add() 0 3 1
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 get_class;
10
use function gettype;
11
use function is_callable;
12
13
/**
14
 * Rule set represents multiple rules for a single value.
15
 */
16
final class RuleSet
17
{
18
    public const PARAMETER_PREVIOUS_RULES_ERRORED = 'previousRulesErrored';
19
20
    /**
21
     * @var RuleInterface[]
22
     */
23
    private array $rules = [];
24
25 40
    public function __construct(iterable $rules = [])
26
    {
27 40
        foreach ($rules as $rule) {
28 39
            $this->add($rule);
29
        }
30
    }
31
32
    /**
33
     * @param callable|RuleInterface $rule
34
     */
35 40
    public function add($rule): void
36
    {
37 40
        $this->rules[] = $this->normalizeRule($rule);
38
    }
39
40 33
    public function validate($value, ValidationContext $context = null): Result
41
    {
42 33
        $context = $context ?? new ValidationContext();
43
44 33
        $compoundResult = new Result();
45 33
        foreach ($this->rules as $rule) {
46 33
            $ruleResult = $rule->validate($value, $context);
47 33
            if ($ruleResult->isValid()) {
48 24
                continue;
49
            }
50
51 21
            $context->setParameter(self::PARAMETER_PREVIOUS_RULES_ERRORED, true);
52
53 21
            foreach ($ruleResult->getErrors() as $error) {
54 21
                $compoundResult->addError($error->getMessage(), $error->getValuePath());
55
            }
56
        }
57 33
        return $compoundResult;
58
    }
59
60 40
    private function normalizeRule($rule): RuleInterface
61
    {
62 40
        if (is_callable($rule)) {
63 6
            return new Callback($rule);
64
        }
65
66 37
        if (!$rule instanceof RuleInterface) {
67
            throw new InvalidArgumentException(sprintf(
68
                'Rule should be either an instance of %s or a callable, %s given.',
69
                RuleInterface::class,
70
                gettype($rule)
71
            ));
72
        }
73
74 37
        return $rule;
75
    }
76
77
    /**
78
     * Return rules as array.
79
     *
80
     * @return array
81
     */
82 5
    public function asArray(): array
83
    {
84 5
        $arrayOfRules = [];
85 5
        foreach ($this->rules as $rule) {
86 5
            if ($rule instanceof ParametrizedRuleInterface) {
87 5
                $arrayOfRules[] = array_merge([$rule->getName()], $rule->getOptions());
88
            } else {
89 1
                $arrayOfRules[] = [get_class($rule)];
90
            }
91
        }
92 5
        return $arrayOfRules;
93
    }
94
}
95