Passed
Pull Request — master (#320)
by Alexander
04:48 queued 01:45
created

StopOnErrorHandler   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 39
Duplicated Lines 0 %

Test Coverage

Coverage 94.12%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 8
eloc 18
c 1
b 0
f 0
dl 0
loc 39
ccs 16
cts 17
cp 0.9412
rs 10

2 Methods

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