Conditional Validation in Symfony Forms
I recently had call to create a form that performed validation on some of it’s fields conditionally, requiring one set of fields if a toggle was marked, another set if not. After getting it all set up I thought some of you out there might find it useful (and I’m pretty sure I’m going to come looking for this again eventually) so here you go.
First I registered a post callback validator with a new function I created in my form class:
public function configure() {
...
$this->mergePostValidator(new sfValidatorCallback(array('callback' => array($this, 'checkConditionalRequirements'))));
}
Then in my new function I create a new error schema and re-run validation on all fields that I determine should be required based on the current data:
public function checkConditionalRequirements($validator, $values, $arguments) {
// container for errors that arise
$errorSchema = new sfValidatorErrorSchema($validator);
// list of required fields that we're building
$required = array();
// only require a password on new objects
if($this->getObject()->isNew()) {
array_push($required, 'password');
}
// register appropriate required fields based on current form context
if($values['condition_field'] == '1') {
array_push($required, 'field_one', 'field_two');
}
else {
array_push($required, 'field_three');
}
// re-process validation on all marked fields
foreach($required as $field) {
$this->validatorSchema[$field]->setOption('required', true);
try {
$this->validatorSchema[$field]->clean($values[$field]);
}
catch(sfValidatorErrorSchema $e) {
$errorSchema->addErrors($e);
}
catch(sfValidatorError $e) {
$errorSchema->addError($e, $field);
}
}
// if something went wrong let's return it to the currently running validation process in a form it will understand
if(count($errorSchema)) {
throw $errorSchema;
}
// return clean values
return $values;
}
That’s it, and it can be easily extended to re-run validation against more than just requirements.
Categories: Symfony