Posts Tagged ‘propel’

Using the Symfony2 Validator component outside the framework

Wednesday, June 20th, 2012 | Limited, Programming

Symfony2 has a very nice Validator component for data validation. As with most of the components, it can be used outside of the framework, but unfortunately, the documentation on how to do this is rather lacking. Indeed, even using it within Symfony but outside the controller can be difficult and this is made especially difficult if you’re using Propel because you can’t use annotations.

However, it can be done, and this tutorial will show you how.

When using the validation component somewhere other than in a Symfony2 controller (be that in an entirely different project, or just in a custom class inside the framework), the problem is that you don’t have access to the service container. So we need to create the object for ourselves.

Lets start by importing the namespace into our class.

use Symfony\Component\Validator as Validator;

This will give us quick and easy access to the Validator classes. Now we can use the ValidatorFactory to generate a validation object.

$factory = Validator\ValidatorFactory::buildDefault();
$validator = $factory->getValidator();

This is good. It means we now have a validation object that we can run against annotated classes. But what if we are using Propel and need to specify our validation rules in a YAML file?

$yamlFile = "../src/Acme/DemoBundle/Resources/config/validation.yml";
$factory = Validator\ValidatorFactory::buildDefault(array($yamlFile), false);
$validator = $factory->getValidator();

Now we can use the rules we specified in the YAML file to validate our Propel classes.

$violations = $validator->validate($model);

Splendid, we’re done. One further trick I’ll throw in with this post – what happens when you need to validate multiple objects and give a combined list of errors back? Because the list we get back is a custom object, we can’t just array_merge the two $violations list. But luckily, there is a function in the object to do this.

$violations = new Validator\ConstraintViolationList;
$firstViolations = $validator->validate($firstModel);
$secondViolations = $validator->validate($secondModel);

if ( count($firstViolations) > 0 ) {
	$violations->addAll($frstViolations);
}

if ( count($secondViolations) > 0 ) {
	$violations->addAll($secondViolations);
}

That will return you a single ConstraintViolationList that you can iterate through, containing errors from both models.