Symfony: the new definitive guide

The new Symfony book is already available, updated for 1.3 and 1.4 versions.

A few days ago the last definitive guide for Symfony has go out, which covers the last 1.3 and 1.4 versions of this already popular PHP framework. In this opportunity the name of the book is “A gentle Introduction to Symfony”.

In this new edition the two first chapters talk a little more about the framework philosophy. Also, there are some new chapters, one dedicated for Doctrine, another one for Symfony Form framework, and another one for emails. In summary, we can learn about:

  • If we want to learn about Symfony, we should read the Practical Symfony book if you want to learn the framework with a sample project; or we should read A Gentle introduction to symfony book if you want more theory and further explanations about main features.
  • If you want to find about how to configure Symfony we should read the Reference guide book.
  • If we want to learn more about Symfony about advanced stuff we should read More with symfony book.

definitive_guide

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.