Passed
Push — master ( 1ce067...27c9ca )
by Alexander
02:32
created

RuleSet::asArray()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 3
nop 0
dl 0
loc 11
ccs 7
cts 7
cp 1
crap 3
rs 10
c 0
b 0
f 0
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 39
    public function __construct(iterable $rules = [])
26
    {
27 39
        foreach ($rules as $rule) {
28 38
            $this->add($rule);
29
        }
30
    }
31
32
    /**
33
     * @param callable|RuleInterface $rule
34
     */
35 39
    public function add($rule): void
36
    {
37 39
        $this->rules[] = $this->normalizeRule($rule);
38
    }
39
40 32
    public function validate($value, ValidationContext $context = null): Result
41
    {
42 32
        $context = $context ?? new ValidationContext();
43
44 32
        $compoundResult = new Result();
45 32
        foreach ($this->rules as $rule) {
46 32
            $ruleResult = $rule->validate($value, $context);
47 32
            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 32
        return $compoundResult;
58
    }
59
60 39
    private function normalizeRule($rule): RuleInterface
61
    {
62 39
        if (is_callable($rule)) {
63 6
            return new Callback($rule);
64
        }
65
66 36
        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 36
        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