mirror of
https://github.com/Respect/Validation.git
synced 2026-03-16 23:35:45 +01:00
All validators related to object properties only consider the properties of the object being validated, not those of its parent object. That's because PHP reflection only gets the properties visible to the current class (public or protected). The problem with that is that when there's a private property in the parent class, we're completely unaware of it. This commit will modify those rules by retrieving properties from the parent class, ensuring we capture all properties that require validation.
57 lines
1.6 KiB
PHP
57 lines
1.6 KiB
PHP
<?php
|
|
|
|
/*
|
|
* Copyright (c) Alexandre Gomes Gaigalas <alganet@gmail.com>
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Respect\Validation\Rules;
|
|
|
|
use Attribute;
|
|
use ReflectionClass;
|
|
use ReflectionObject;
|
|
use Respect\Validation\Path;
|
|
use Respect\Validation\Result;
|
|
use Respect\Validation\Rule;
|
|
use Respect\Validation\Rules\Core\Wrapper;
|
|
|
|
#[Attribute(Attribute::TARGET_PROPERTY | Attribute::IS_REPEATABLE)]
|
|
final class Property extends Wrapper
|
|
{
|
|
public function __construct(
|
|
private readonly string $propertyName,
|
|
Rule $rule,
|
|
) {
|
|
parent::__construct($rule);
|
|
}
|
|
|
|
public function evaluate(mixed $input): Result
|
|
{
|
|
$propertyExistsResult = (new PropertyExists($this->propertyName))->evaluate($input);
|
|
if (!$propertyExistsResult->hasPassed) {
|
|
return $propertyExistsResult->withNameFrom($this->rule);
|
|
}
|
|
|
|
return $this->rule
|
|
->evaluate($this->getPropertyValue($input, $this->propertyName))
|
|
->withPath(new Path($this->propertyName));
|
|
}
|
|
|
|
private function getPropertyValue(object $object, string $propertyName): mixed
|
|
{
|
|
$reflection = new ReflectionObject($object);
|
|
while ($reflection instanceof ReflectionClass) {
|
|
if ($reflection->hasProperty($propertyName)) {
|
|
$property = $reflection->getProperty($propertyName);
|
|
|
|
return $property->isInitialized($object) ? $property->getValue($object) : null;
|
|
}
|
|
|
|
$reflection = $reflection->getParentClass();
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|