Passed
Pull Request — master (#626)
by
unknown
06:09 queued 03:16
created

OneOfHandler::validate()   B

Complexity

Conditions 8
Paths 10

Size

Total Lines 30
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 8
eloc 15
c 1
b 0
f 0
nc 10
nop 3
dl 0
loc 30
rs 8.4444
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Validator\Rule;
6
7
use Yiisoft\Arrays\ArrayHelper;
8
use Yiisoft\Validator\Exception\UnexpectedRuleException;
9
use Yiisoft\Validator\Result;
10
use Yiisoft\Validator\Rule\Trait\TranslatedAttributesHandlerTrait;
11
use Yiisoft\Validator\RuleHandlerInterface;
12
use Yiisoft\Validator\EmptyCondition\WhenEmpty;
13
use Yiisoft\Validator\ValidationContext;
14
15
use function is_array;
16
use function is_object;
17
18
/**
19
 * Validates that one of specified attributes is filled.
20
 *
21
 * @see OneOf
22
 */
23
final class OneOfHandler implements RuleHandlerInterface
24
{
25
    use TranslatedAttributesHandlerTrait;
26
27
    public function validate(mixed $value, object $rule, ValidationContext $context): Result
28
    {
29
        if (!$rule instanceof OneOf) {
30
            throw new UnexpectedRuleException(OneOf::class, $rule);
31
        }
32
33
        /** @var mixed $value */
34
        $value = $context->getParameter(ValidationContext::PARAMETER_VALUE_AS_ARRAY) ?? $value;
35
36
        $result = new Result();
37
38
        if (!is_array($value) && !is_object($value)) {
39
            return $result->addError($rule->getIncorrectInputMessage(), [
40
                'attribute' => $context->getTranslatedAttribute(),
41
                'type' => get_debug_type($value),
42
            ]);
43
        }
44
45
        $filledCount = 0;
46
        foreach ($rule->getAttributes() as $attribute) {
47
            if (!(new WhenEmpty())(ArrayHelper::getValue($value, $attribute), $context->isAttributeMissing())) {
48
                $filledCount++;
49
            }
50
51
            if ($filledCount > 1) {
52
                return $this->getGenericErrorResult($rule, $context);
53
            }
54
        }
55
56
        return $filledCount === 1 ? $result : $this->getGenericErrorResult($rule, $context);
57
    }
58
59
    private function getGenericErrorResult(OneOf $rule, ValidationContext $context): Result
60
    {
61
        return (new Result())->addError($rule->getMessage(), [
62
            'attributes' => $this->getFormattedAttributesString($rule->getAttributes(), $context),
63
        ]);
64
    }
65
}
66