respect-validation/library/Rules/KeyOptional.php
Henrique Moody 2aa5e39c54
Improve KeySet rule
After changes in the key-related rules, the KeySet rule became unusable.
Besides, when evaluating an input, it wasn't reporting every single
failure because it would not validate the items in the array if they had
missing or extra keys.

This commit will make several improvements to the rule. It will create
some not(keyExists($key)) rules for the extra keys, which makes the
error reporting much better. A limit of 10 additional keys will show up
when asserting an input with extra keys. I put that limit in place to
prevent the creation of too many rules.
2024-12-02 20:09:47 +01:00

51 lines
1.3 KiB
PHP

<?php
/*
* Copyright (c) Alexandre Gomes Gaigalas <alganet@gmail.com>
* SPDX-License-Identifier: MIT
*/
declare(strict_types=1);
namespace Respect\Validation\Rules;
use Respect\Validation\Helpers\CanBindEvaluateRule;
use Respect\Validation\Result;
use Respect\Validation\Rules\Core\KeyRelated;
use Respect\Validation\Rules\Core\Wrapper;
use Respect\Validation\Validatable;
final class KeyOptional extends Wrapper implements KeyRelated
{
use CanBindEvaluateRule;
public function __construct(
private readonly int|string $key,
Validatable $rule,
) {
$rule->setName($rule->getName() ?? (string) $key);
parent::__construct($rule);
}
public function getKey(): int|string
{
return $this->key;
}
public function evaluate(mixed $input): Result
{
$keyExistsResult = $this->bindEvaluate(new KeyExists($this->key), $this, $input);
if (!$keyExistsResult->isValid) {
return $keyExistsResult->withInvertedMode();
}
$child = $this->rule
->evaluate($input[$this->key])
->withId((string) $this->key);
return (new Result($child->isValid, $input, $this))
->withChildren($child)
->withId((string) $this->key)
->withNameIfMissing($this->rule->getName() ?? (string) $this->key);
}
}