Here we will see how to implement a conditional validator for Symfony’s forms.
As you may know the form framework inside Symfony gives us the ability to use validators for each form field, therefore we can validate the required fields, the data format, etc.
When we need to validate certain logic for a field which could not be accomplish it with the normal Symfony validators, we have to use a post validator. A post validator is executed after all normal Symfony validators and it receives an array with all entered values through the form.
As a practical case, we might want to validate that an entered password in a login form is equal to the entered username. Obviously, this is a easy but practical example.
The login form could be as follow:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | <?php class loginForm extends sfForm { public function configure() { $this->setWidgets(array( 'username' => new sfWidgetFormInput(), 'password' => new sfWidgetFormInputPassword(), )); $this->setValidators(array( 'username' => new sfValidatorString(array('required' => true)), 'password' => new sfValidatorString(array('required' => true)), )); $this->widgetSchema->setNameFormat('login[%s]'); // add a post validator $this->validatorSchema->setPostValidator( new sfValidatorCallback(array('callback' => array($this, 'checkPassword'))) ); } public function checkPassword($validator, $values) { // before validating the password, check that the username is not empty if (!empty($values['username']) && $values['password'] != $values['username']) { // password is not correct, throw an error throw new sfValidatorError($validator, 'Invalid password'); } // password is correct, return the clean values return $values; } } |
In this way, the validator callback will throw a “global” error when the entered password is not equal to the entered username. If we want to get a specific field error we should modify the checkPassword() method:
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?php public function checkPassword($validator, $values) { if (!empty($values['username']) && $values['password'] != $values['username']) { $error = new sfValidatorError($validator, 'Invalid password'); // throw an error bound to the password field throw new sfValidatorErrorSchema($validator, array('password' => $error)); } return $values; } |
That is! I hope it’s helpful.