Passed
Pull Request — master (#316)
by Dmitriy
02:46
created

StopOnErrorHandler::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 0
dl 0
loc 2
ccs 1
cts 1
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Validator\Rule;
6
7
use InvalidArgumentException;
8
use Yiisoft\Translator\TranslatorInterface;
9
use Yiisoft\Validator\Exception\UnexpectedRuleException;
10
use Yiisoft\Validator\Result;
11
use Yiisoft\Validator\RuleHandlerInterface;
12
use Yiisoft\Validator\ValidationContext;
13
14
/**
15
 * Can be used for early stopping the validation process of the value when the validation on the stage was failed.
16
 *
17
 * For example, we have several rules, but we want not to process the rest rules when fail was ocurred:
18
 *
19
 * ```php
20
 * $request = [
21
 *     'username' => 'yiisoft',
22
 * ];
23
 * ```
24
 *
25
 * So to make validation we can configure it like this:
26
 *
27
 * ```php
28
 * $rule = new StopOnError([
29
 *      new HasLength(min: 3),
30
 *      new ExistInDatabase(), // Heavy operation. It would be great not to call it if the previous rule was failed.
31
 *     )];
32
 * ]);
33
 * ```
34
 */
35
final class StopOnErrorHandler implements RuleHandlerInterface
36
{
37 6
    public function __construct(private TranslatorInterface $translator)
38
    {
39
    }
40
41 5
    public function validate(mixed $value, object $rule, ValidationContext $context): Result
42
    {
43 5
        if (!$rule instanceof StopOnError) {
44 1
            throw new UnexpectedRuleException(StopOnError::class, $rule);
45
        }
46
47 4
        if ($rule->getRules() === []) {
48
            throw new InvalidArgumentException(
49
                'Rules for StopOnError rule are required.'
50
            );
51
        }
52
53 4
        $compoundResult = new Result();
54 4
        $results = [];
55
56 4
        foreach ($rule->getRules() as $rule) {
57 4
            $rules = [$rule];
58
59 4
            if (is_iterable($rule)) {
60 1
                $rules = [new StopOnError($rule)];
61
            }
62
63 4
            $lastResult = $context->getValidator()->validate($value, $rules);
64 4
            $results[] = $lastResult;
65
66 4
            if (!$lastResult->isValid()) {
67 3
                break;
68
            }
69
        }
70
71 4
        foreach ($results as $result) {
72 4
            foreach ($result->getErrors() as $error) {
73 3
                $compoundResult->addError($error->getMessage(), $error->getValuePath());
74
            }
75
        }
76
77 4
        return $compoundResult;
78
    }
79
}
80