Symfony form conditional validation with PostValidators

Posted on Categories:PHP, MySQL, Symfony

This post describes how to use Symfony postValidators to create conditional validation of the form.
In this example I’m checking for user_type variable that can be set to person or firm value. If variable user_type has value person, the form should have one set of required fields, and another set for value firm.
[php]class sfGuardUserProfileForm extends BasesfGuardUserProfileForm {

protected $postValidateFields = array(
‘person’ => array(),
‘firm’ => array(‘company’, ‘OIB’, ‘city_id’, ‘street’)
);
public function configure()
{

$this->validatorSchema->setPostValidator(
new sfValidatorCallback(array(‘callback’ => array($this, ‘userPostValidate’)))
);

}

public function userPostValidate($validator, $values)
{
$errors = array();

foreach($this->postValidateFields[$values[‘user_type’]] as $k=>$f)
{
if($values[$f] == ”)
$errors[$f] = new sfValidatorError($validator, ‘Obavezno polje’);
}

if(!empty($errors))
throw new sfValidatorErrorSchema ($validator, $errors);

return $values;
}
[/php]

Function userPostValidate iterates through all fields and checks if required fields are filled.
If we want to use embedded forms, There are a few more steps to follow.
First, we need embedded form’s error schema. It can be acquired like this:
[php]
$embValidatorSchema = $this->getEmbeddedForm ($k)->getValidatorSchema();
[/php]
Note that $k in example above is embedded form’s index. After that, we can iterate through that embedded form’s fields and validate fields. If there are errors, they have to be passed to embedded form’s error schema:
[php]
$emb_errors[$ef] = new sfValidatorError($embValidatorSchema, ‘Obavezno polje’);
[/php]
Finally, we can pass all errors to main error schema:
[php]
if(!empty($emb_errors))
$errors[$k] = new sfValidatorErrorSchema($validator, $emb_errors);
[/php]

Here’s an complete example how it can be done:
[php]
protected $postValidateFields = array(
‘person’ => array(‘first_name’, ‘last_name’),
‘firm’ => array(‘company’,’OIB’, ‘Lokacija’=>array(‘city_id’, ‘street’)));

public function userPostValidate($validator, $values)
{
$errors = array();

foreach($this->postValidateFields[$values[‘user_type’]] as $k=>$f)
{
if(is_array($f))
{
$emb_errors = array();
$embValidatorSchema = $this->getEmbeddedForm ($k)->getValidatorSchema();

foreach($f as $ef)
{
if($values[$k][$ef] == ”)
$emb_errors[$ef] = new sfValidatorError($embValidatorSchema, ‘Obavezno polje’);
}
if(!empty($emb_errors))
$errors[$k] = new sfValidatorErrorSchema($validator, $emb_errors);

}
else
{
if($values[$f] == ”)
$errors[$f] = new sfValidatorError($validator, ‘Obavezno polje’);
}
}

if(!empty($errors))
throw new sfValidatorErrorSchema ($validator, $errors);

return $values;
}
[/php]