Symfony проверяет объект при условии

#symfony #validation

Вопрос:

Я хотел бы проверить свой AddressDto объект только в том случае, если $hasAddress он истинен. Возможно ли это каким-то образом?

 final class UserDto
{
    /**
     * @var bool
     * @AssertNotNull()
     */
    public $hasAddress;

    /**
     * @var AddressDto
     * @AssertValid()
     */
    public $address;
}
 
 final class AddressDto
{
    /**
     * @AssertNotBlank()
     */
    public $postalCode;

    /**
     * @AssertNotBlank()
     */
    public $city;

    /**
     * @AssertNotBlank()
     */
    public $street;

    /**
     * @AssertNotBlank()
     */
    public $houseNumber;
}
 

Я попробовал проверку обратного вызова, которая работает, но я не могу прикрепить ошибки к полям, только к родительской форме.

 final class UserDto
{
    /**
     * @var bool
     * @AssertNotNull()
     */
    public $hasAddress;

    /**
     * @var AddressDto
     */
    public $address;

    /**
     * @AssertCallback()
     */
    public function validate(ExecutionContextInterface $context, $payload): void
    {
        if ($this->hasAddress) {
            $errors = $context->getValidator()->validate($this->address, new AssertValid());

            foreach ($errors as $error) {
                $context->buildViolation($error->getMessage())
                    ->addViolation();
            }
        }
    }
}
 

Ответ №1:

Я проверил документацию валидатора, и вам просто нужно добавить «atPath» в контекст, который позволяет указать поле, которое вы проверяете. Вот ссылка на документацию: https://symfony.com/doc/current/validation/custom_constraint.html.

Таким образом, код должен быть:

 public function validate(ExecutionContextInterface $context, $payload): void
{
    if ($this->hasAddress) {
        $errors = $context->getValidator()->validate($this->address, new AssertValid());

        foreach ($errors as $error) {
            $context->buildViolation($error->getMessage())
                ->atPath('address')
                ->addViolation();
        }
    }
}