Passed
Pull Request — master (#222)
by Alexander
04:33 queued 02:13
created

Nested   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 107
Duplicated Lines 0 %

Test Coverage

Coverage 94%

Importance

Changes 4
Bugs 2 Features 0
Metric Value
eloc 50
c 4
b 2
f 0
dl 0
loc 107
ccs 47
cts 50
cp 0.94
rs 10
wmc 24
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Validator\Rule;
6
7
use Attribute;
8
use Closure;
9
use InvalidArgumentException;
10
use Traversable;
11
use Yiisoft\Validator\ParametrizedRuleInterface;
12
use Yiisoft\Validator\PreValidatableRuleInterface;
13
use Yiisoft\Validator\Rule\Trait\HandlerClassNameTrait;
0 ignored issues
show
Bug introduced by
A parse error occurred: Syntax error, unexpected T_TRAIT, expecting T_STRING or '{' on line 13 at column 27
Loading history...
14
use Yiisoft\Validator\Rule\Trait\PreValidatableTrait;
15
use Yiisoft\Validator\Rule\Trait\RuleNameTrait;
16
use Yiisoft\Validator\RuleInterface;
17
use Yiisoft\Validator\RulesDumper;
18
19
use function is_array;
20
21
/**
22
 * Can be used for validation of nested structures.
23
 */
24
#[Attribute(Attribute::TARGET_PROPERTY)]
25
final class Nested implements ParametrizedRuleInterface, PreValidatableRuleInterface
26
{
27
    use HandlerClassNameTrait;
28
    use PreValidatableTrait;
29
    use RuleNameTrait;
30
31 4
    public function __construct(
32
        /**
33
         * @var RuleInterface[][]
34
         */
35
        private iterable $rules = [],
36
        private bool $errorWhenPropertyPathIsNotFound = false,
37
        private string $propertyPathIsNotFoundMessage = 'Property path "{path}" is not found.',
38
        private bool $skipOnEmpty = false,
39
        private bool $skipOnError = false,
40
        private ?Closure $when = null,
41
    ) {
42 4
        $rules = $rules instanceof Traversable ? iterator_to_array($rules) : $rules;
43 4
        if (empty($rules)) {
44 1
            throw new InvalidArgumentException('Rules must not be empty.');
45
        }
46
47 3
        if ($this->checkRules($rules)) {
48 1
            $message = sprintf('Each rule should be an instance of %s.', RuleInterface::class);
49 1
            throw new InvalidArgumentException($message);
50
        }
51
52 2
        $this->rules = $rules;
53
    }
54
55
    /**
56
     * @return iterable
57
     */
58 10
    public function getRules(): iterable
59
    {
60 10
        return $this->rules;
61
    }
62
63
    /**
64
     * @return bool
65
     */
66 10
    public function isErrorWhenPropertyPathIsNotFound(): bool
67
    {
68 10
        return $this->errorWhenPropertyPathIsNotFound;
69
    }
70
71
    /**
72
     * @return string
73
     */
74 2
    public function getPropertyPathIsNotFoundMessage(): string
75
    {
76 2
        return $this->propertyPathIsNotFoundMessage;
77
    }
78
79 3
    private function checkRules(array $rules): bool
80
    {
81 3
        return array_reduce(
82
            $rules,
83 3
            function (bool $carry, $rule) {
84 3
                return $carry || (is_array($rule) ? $this->checkRules($rule) : !$rule instanceof RuleInterface);
85
            },
86
            false
87
        );
88
    }
89
90 4
    public function getOptions(): array
91
    {
92 4
        return (new RulesDumper())->asArray($this->rules);
93
    }
94
}
95