Passed
Pull Request — master (#331)
by Sergei
02:46
created

Each::propagateOptions()   A

Complexity

Conditions 6
Paths 17

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 6

Importance

Changes 0
Metric Value
eloc 12
dl 0
loc 22
ccs 13
cts 13
cp 1
rs 9.2222
c 0
b 0
f 0
cc 6
nc 17
nop 0
crap 6
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Validator\Rule;
6
7
use Attribute;
8
use Closure;
9
use JetBrains\PhpStorm\ArrayShape;
10
use Yiisoft\Validator\PropagateOptionsInterface;
11
use Yiisoft\Validator\Rule\Trait\RuleNameTrait;
12
use Yiisoft\Validator\Rule\Trait\SkipOnEmptyTrait;
13
use Yiisoft\Validator\Rule\Trait\SkipOnErrorTrait;
14
use Yiisoft\Validator\Rule\Trait\WhenTrait;
15
use Yiisoft\Validator\RuleInterface;
16
use Yiisoft\Validator\SerializableRuleInterface;
17
use Yiisoft\Validator\SkipOnEmptyInterface;
18
use Yiisoft\Validator\SkipOnErrorInterface;
19
use Yiisoft\Validator\ValidationContext;
20
use Yiisoft\Validator\WhenInterface;
21
22
/**
23
 * Validates an array by checking each of its elements against a set of rules.
24
 */
25
#[Attribute(Attribute::TARGET_PROPERTY | Attribute::IS_REPEATABLE)]
26
final class Each implements
27
    SerializableRuleInterface,
28
    SkipOnErrorInterface,
29
    WhenInterface,
30
    SkipOnEmptyInterface,
31
    PropagateOptionsInterface
32
{
33
    use RuleNameTrait;
34
    use SkipOnEmptyTrait;
35
    use SkipOnErrorTrait;
36
    use WhenTrait;
37
38 5
    public function __construct(
39
        /**
40
         * @var iterable<RuleInterface>
41
         */
42
        private iterable $rules = [],
43
        private string $incorrectInputMessage = 'Value must be array or iterable.',
44
        private string $message = '{error} {value} given.',
45
46
        /**
47
         * @var bool|callable|null
48
         */
49
        private $skipOnEmpty = null,
50
        private bool $skipOnError = false,
51
        /**
52
         * @var Closure(mixed, ValidationContext):bool|null
53
         */
54
        private ?Closure $when = null,
55
    ) {
56
    }
57
58 1
    public function propagateOptions(): void
59
    {
60 1
        $rules = [];
61 1
        foreach ($this->rules as $rule) {
62 1
            if ($rule instanceof SkipOnEmptyInterface) {
63 1
                $rule = $rule->skipOnEmpty($this->skipOnEmpty);
64
            }
65 1
            if ($rule instanceof SkipOnErrorInterface) {
66 1
                $rule = $rule->skipOnError($this->skipOnError);
67
            }
68 1
            if ($rule instanceof WhenInterface) {
69 1
                $rule = $rule->when($this->when);
70
            }
71
72 1
            $rules[] = $rule;
73
74 1
            if ($rule instanceof PropagateOptionsInterface) {
75 1
                $rule->propagateOptions();
76
            }
77
        }
78
79 1
        $this->rules = $rules;
80
    }
81
82
    /**
83
     * @return iterable<Closure|Closure[]|RuleInterface|RuleInterface[]>
84
     */
85 10
    public function getRules(): iterable
86
    {
87 10
        return $this->rules;
88
    }
89
90 3
    public function getIncorrectInputMessage(): string
91
    {
92 3
        return $this->incorrectInputMessage;
93
    }
94
95 9
    public function getMessage(): string
96
    {
97 9
        return $this->message;
98
    }
99
100 2
    #[ArrayShape([
101
        'incorrectInputMessage' => 'array',
102
        'message' => 'array',
103
        'skipOnEmpty' => 'bool',
104
        'skipOnError' => 'bool',
105
        'rules' => 'array',
106
    ])]
107
    public function getOptions(): array
108
    {
109 2
        $arrayOfRules = [];
110 2
        foreach ($this->rules as $rule) {
111 2
            if ($rule instanceof SerializableRuleInterface) {
112 2
                $arrayOfRules[] = array_merge([$rule->getName()], $rule->getOptions());
113
            } else {
114
                $arrayOfRules[] = [$rule->getName()];
115
            }
116
        }
117
118
        return [
119
            'incorrectInputMessage' => [
120 2
                'message' => $this->getIncorrectInputMessage(),
121
            ],
122
            'message' => [
123 2
                'message' => $this->getMessage(),
124
            ],
125 2
            'skipOnEmpty' => $this->getSkipOnEmptyOption(),
126 2
            'skipOnError' => $this->skipOnError,
127
            'rules' => $arrayOfRules,
128
        ];
129
    }
130
131 7
    public function getHandlerClassName(): string
132
    {
133 7
        return EachHandler::class;
134
    }
135
}
136