Passed
Push — master ( f4cee7...db5d9e )
by
unknown
05:36 queued 02:32
created

NestedHandler::validate()   C

Complexity

Conditions 15
Paths 15

Size

Total Lines 86
Code Lines 47

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 33
CRAP Score 15

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 15
eloc 47
c 1
b 0
f 0
nc 15
nop 3
dl 0
loc 86
ccs 33
cts 33
cp 1
crap 15
rs 5.9166

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Validator\Rule;
6
7
use Yiisoft\Arrays\ArrayHelper;
8
use Yiisoft\Strings\StringHelper;
9
use Yiisoft\Validator\DataSet\ObjectDataSet;
10
use Yiisoft\Validator\Exception\UnexpectedRuleException;
11
use Yiisoft\Validator\Result;
12
use Yiisoft\Validator\RuleHandlerInterface;
13
use Yiisoft\Validator\ValidationContext;
14
15
use function is_array;
16
use function is_int;
17
use function is_object;
18
19
/**
20
 * A handler for {@see Nested} rule. Validates nested structures.
21
 */
22
final class NestedHandler implements RuleHandlerInterface
23
{
24
    public function validate(mixed $value, object $rule, ValidationContext $context): Result
25
    {
26
        if (!$rule instanceof Nested) {
27
            throw new UnexpectedRuleException(Nested::class, $rule);
28
        }
29
30
        /** @var mixed $value */
31
        $value = $context->getParameter(ValidationContext::PARAMETER_VALUE_AS_ARRAY) ?? $value;
32
33
        if ($rule->getRules() === null) {
34
            if (!is_object($value)) {
35
                return (new Result())->addError($rule->getNoRulesWithNoObjectMessage(), [
36
                    'attribute' => $context->getTranslatedAttribute(),
37
                    'type' => get_debug_type($value),
38
                ]);
39
            }
40
41
            $dataSet = new ObjectDataSet($value, $rule->getValidatedObjectPropertyVisibility());
42
43
            return $context->validate($dataSet);
44
        }
45
46 53
        if (is_array($value)) {
47
            $data = $value;
48 53
        } elseif (is_object($value)) {
49 1
            $data = (new ObjectDataSet($value, $rule->getValidatedObjectPropertyVisibility()))->getData();
50
            if ($data === null) {
51
                return (new Result())->addError($rule->getIncorrectDataSetTypeMessage(), [
52 52
                    'type' => get_debug_type($data),
53
                ]);
54 52
            }
55 10
        } else {
56 5
            return (new Result())->addError($rule->getIncorrectInputMessage(), [
57 5
                'attribute' => $context->getTranslatedAttribute(),
58 5
                'type' => get_debug_type($value),
59
            ]);
60
        }
61
62 5
        $compoundResult = new Result();
63
64 5
        foreach ($rule->getRules() as $valuePath => $rules) {
65
            if ($rule->isPropertyPathRequired() && !ArrayHelper::pathExists($data, $valuePath)) {
0 ignored issues
show
Bug introduced by
It seems like $data can also be of type null; however, parameter $array of Yiisoft\Arrays\ArrayHelper::pathExists() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

65
            if ($rule->isPropertyPathRequired() && !ArrayHelper::pathExists(/** @scrutinizer ignore-type */ $data, $valuePath)) {
Loading history...
66
                if (is_int($valuePath)) {
67 42
                    $valuePathList = [$valuePath];
68 33
                } else {
69 9
                    /** @var list<string> $valuePathList */
70
                    $valuePathList = StringHelper::parsePath($valuePath);
71 4
                }
72 4
73 3
                $compoundResult->addError(
74 4
                    $rule->getNoPropertyPathMessage(),
75
                    [
76
                        'path' => $valuePath,
77
                        'attribute' => $context->getTranslatedAttribute(),
78 5
                    ],
79 5
                    $valuePathList,
80 5
                );
81
82
                continue;
83
            }
84 34
85
            /** @var mixed $validatedValue */
86 34
            $validatedValue = ArrayHelper::getValueByPath($data, $valuePath);
0 ignored issues
show
Bug introduced by
It seems like $data can also be of type null; however, parameter $array of Yiisoft\Arrays\ArrayHelper::getValueByPath() does only seem to accept array|object, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

86
            $validatedValue = ArrayHelper::getValueByPath(/** @scrutinizer ignore-type */ $data, $valuePath);
Loading history...
87 33
88 4
            $itemResult = $context->validate($validatedValue, $rules);
89 1
            if ($itemResult->isValid()) {
90
                continue;
91
            }
92 3
93
            foreach ($itemResult->getErrors() as $error) {
94
                if (is_int($valuePath)) {
95 4
                    $valuePathList = [$valuePath];
96 4
                } else {
97
                    /** @var list<string> $valuePathList */
98
                    $valuePathList = StringHelper::parsePath($valuePath);
99 4
                }
100
101
                if (!empty($valuePathList)) {
102
                    array_push($valuePathList, ...$error->getValuePath());
0 ignored issues
show
Bug introduced by
It seems like $valuePathList can also be of type Yiisoft\Validator\Rule\list; however, parameter $array of array_push() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

102
                    array_push(/** @scrutinizer ignore-type */ $valuePathList, ...$error->getValuePath());
Loading history...
103
                }
104 4
105
                $compoundResult->addError($error->getMessage(), $error->getParameters(), $valuePathList);
106
            }
107
        }
108 29
109 29
        return $compoundResult;
110
    }
111
}
112