Symfony: conditional validator

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.

share it...Share on FacebookTweet about this on TwitterShare on LinkedInShare on Google+Pin on PinterestDigg thisEmail this to someone

3 Comments

Leave a Reply to rodrigo.cubillos Cancel reply