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.
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]);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With