0 follower

Final Class Yiisoft\Validator\Rule\NestedHandler

InheritanceYiisoft\Validator\Rule\NestedHandler
ImplementsYiisoft\Validator\RuleHandlerInterface

A handler for {@see Nested} rule. Validates nested structures.

Public Methods

Hide inherited methods

Method Description Defined By
validate() Yiisoft\Validator\Rule\NestedHandler

Method Details

Hide inherited methods

validate() public method

public Yiisoft\Validator\Result validate ( mixed $value, Yiisoft\Validator\RuleInterface $rule, Yiisoft\Validator\ValidationContext $context )
$value mixed
$rule Yiisoft\Validator\RuleInterface
$context Yiisoft\Validator\ValidationContext

                public function validate(mixed $value, RuleInterface $rule, ValidationContext $context): Result
{
    if (!$rule instanceof Nested) {
        throw new UnexpectedRuleException(Nested::class, $rule);
    }
    if ($rule->getRules() === null) {
        if (!is_object($value)) {
            return (new Result())->addError($rule->getNoRulesWithNoObjectMessage(), [
                'property' => $context->getTranslatedProperty(),
                'Property' => $context->getCapitalizedTranslatedProperty(),
                'type' => get_debug_type($value),
            ]);
        }
        $dataSet = new ObjectDataSet($value, $rule->getValidatedObjectPropertyVisibility());
        return $context->validate($dataSet);
    }
    $value = $context->getParameter(ValidationContext::PARAMETER_VALUE_AS_ARRAY) ?? $value;
    if (is_array($value)) {
        $data = $value;
    } elseif (is_object($value)) {
        $data = (new ObjectDataSet($value, $rule->getValidatedObjectPropertyVisibility()))->getData();
        if ($data === null) {
            return (new Result())->addError($rule->getIncorrectDataSetTypeMessage(), [
                'property' => $context->getTranslatedProperty(),
                'Property' => $context->getCapitalizedTranslatedProperty(),
                'type' => get_debug_type($data),
            ]);
        }
    } else {
        return (new Result())->addError($rule->getIncorrectInputMessage(), [
            'property' => $context->getTranslatedProperty(),
            'Property' => $context->getCapitalizedTranslatedProperty(),
            'type' => get_debug_type($value),
        ]);
    }
    $compoundResult = new Result();
    foreach ($rule->getRules() as $valuePath => $rules) {
        if ($rule->isPropertyPathRequired() && !ArrayHelper::pathExists($data, $valuePath)) {
            $valuePathList = is_int($valuePath)
                ? [$valuePath]
                : StringHelper::parsePath($valuePath);
            $compoundResult->addError(
                $rule->getNoPropertyPathMessage(),
                [
                    'path' => $valuePath,
                    'property' => $context->getTranslatedProperty(),
                    'Property' => $context->getCapitalizedTranslatedProperty(),
                ],
                $valuePathList,
            );
            continue;
        }
        $validatedValue = ArrayHelper::getValueByPath($data, $valuePath);
        if (is_int($valuePath)) {
            $itemResult = $context->validate($validatedValue, $rules);
        } else {
            $valuePathList = StringHelper::parsePath($valuePath);
            $property = end($valuePathList);
            $itemResult = $context->validate(
                ArrayHelper::keyExists($data, $valuePathList) ? [$property => $validatedValue] : [],
                [$property => $rules],
            );
        }
        if ($itemResult->isValid()) {
            continue;
        }
        foreach ($itemResult->getErrors() as $error) {
            $valuePathList = is_int($valuePath)
                ? [$valuePath, ...$error->getValuePath()]
                : [...StringHelper::parsePath($valuePath), ...array_slice($error->getValuePath(), 1)];
            $compoundResult->addErrorWithoutPostProcessing(
                $error->getMessage(),
                $error->getParameters(),
                $valuePathList,
            );
        }
    }
    if ($value instanceof PostValidationHookInterface) {
        $value->processValidationResult($compoundResult);
    }
    return $compoundResult;
}