Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony/Validator: Property validation in Callback

I'm trying to create an Address entity with postal code validated based on the given country. The way to go is oviously the CallbackValidator. For now I have this code:

use SLLH\IsoCodesValidator\Constraints\ZipCode;
use Symfony\Component\Validator\Constraints\Callback;
use Symfony\Component\Validator\Context\ExecutionContextInterface;

class Address
{
    /**
     * @Callback()
     */
    public function validatePostalCode(ExecutionContextInterface $context)
    {
        $constraint = new ZipCode([ 'country' => $this->country ]);
        $violations = $context->getValidator()->validate($this->postalCode, $constraint);

        foreach ($violations as $violation) {
            $context->getViolations()->add($violation);
        }
    }
}

The problem with this is that the violations don't have correct path. I don't know how to set it though. Also $context->buildViolation($violation->getMessage()) is not good because I'd have to manually copy all the properties the violation might have.

EDIT: I've tried it and it is indeed very ugly.

like image 903
enumag Avatar asked Oct 30 '22 13:10

enumag


1 Answers

This seems to work. The point is that you can actually specify the validation path if you use the contextual validator. Also you don't need to duplicate the violations as they are added directly to the intended context.

/**
 * @Callback()
 */
public function validatePostalCode(ExecutionContextInterface $context)
{
    $constraint = new ZipCode([ 'country' => $this->country ]);
    $validator = $context->getValidator()->inContext($context);
    $validator->atPath('postalCode')->validate($this->postalCode, $constraint, [Constraint::DEFAULT_GROUP]);
}
like image 51
enumag Avatar answered Nov 02 '22 10:11

enumag