Notes on Symfony 2 v2.0.0 documentation

Validator Component

Constraints that an object must follow can be configured in a number of different formats (YAML, XML, annotations, or PHP).

Validation

The use the validation service directly, use Validator::validate(), which reads and checks an object’s constraints.

<?php
use Symfony\Component\HttpFoundation\Response;
use Acme\BlogBundle\Entity\Author;
// ...

public function indexAction()
{
    $author = new Author();
    // ... do something to the $author object

    $validator = $this->get('validator');
    $errors = $validator->validate($author);

    if (count($errors) > 0) {
        return new Response(print_r($errors, true));
    } else {
        return new Response('The author is valid! Yes!');
    }
}

If the $name property is empty, you will see the following error message:

<?php
Acme\BlogBundle\Author.name:
    This value should not be blank

Symfony’s form library uses the validator service internally to validate the underlying object after values have been submitted and bound. The constraint violations on the object are converted into FieldError objects that can easily be displayed with your form. The typical form submission workflow looks like the following from inside a controller:

<?php
use Acme\BlogBundle\Entity\Author;
use Acme\BlogBundle\Form\AuthorType;
use Symfony\Component\HttpFoundation\Request;
// ...

public function updateAction(Request $request)
{
    $author = new Acme\BlogBundle\Entity\Author();
    $form = $this->createForm(new AuthorType(), $author);

    if ($request->getMethod() == 'POST') {
        $form->bindRequest($request);

        if ($form->isValid()) {
            // the validation passed, do something with the $author object

            return $this->redirect($this->generateUrl('...'));
        }
    }

    return $this->render('BlogBundle:Author:form.html.twig', array(
        'form' => $form->createView(),
    ));
}

Enabling Validator Annotations

The Symfony2 validator is enabled by default, but you must explicitly enable annotations if you’re using the annotation method to specify your constraints:

<?php
# app/config/config.yml
framework:
    validation: { enable_annotations: true }

Constraint Types

The constraint types are quite similar to ZF form validators.

Basic

  • NotBlank
  • Blank
  • NotNull
  • Null
  • True
  • False
  • Type

String Constraints

  • Email
  • MinLength
  • MaxLength
  • Url
  • Regex
  • Ip

Number Constraints

  • Max
  • Min

Date Constraints

  • Date
  • DateTime
  • Time

File Constraints

  • File
  • Image

There are also collection constraints

Collection Constraints

  • Choice
  • Collection
  • UniqueEntity
  • Language
  • Locale
  • Country

And custom constraints can be added

Other Constraints

  • Callback
  • All
  • Valid

For details on each constraint above, see the Constraint Reference.

Constraints can be applied to a class property or a public getter method (that start with ‘get’ or ‘is’). This is the YAML for a getter method constraint

<?php
Acme\BlogBundle\Entity\Author:
    getters:
        passwordLegal:
            - "True": { message: "The password cannot match your first name" }

You need to, of course, create the isPassWordLegal() method.

Validating Classes

Some constraints apply to the entire class being validated. For example, the Callback constraint is a generic constraint that’s applied to the class itself. When that class is validated, methods specified by that constraint are simply executed so that each can provide more custom validation.

Validation Groups

In some cases, however, you’ll need to validate an object against only some of the constraints on that class. To do this, you can organize each constraint into one or more “validation groups”, and then apply validation against just one group of constraints.

For example, suppose you have a User class, which is used both when a user registers and when a user updates his/her contact information

<?phplater
# src/Acme/BlogBundle/Resources/config/validation.yml
Acme\BlogBundle\Entity\User:
    properties:
        email:
            - Email: { groups: [registration] }
        password:
            - NotBlank: { groups: [registration] }
            - MinLength: { limit: 7, groups: [registration] }
        city:
            - MinLength: 2

With this configuration, there are two validation groups:

  • Default - contains the constraints not assigned to any other group;
  • registration - contains the constraints on the email and password fields only.

To tell the validator to use a specific group, pass one or more group names as the second argument to the validate() method:

<?php
$errors = $validator->validate($author, array('registration'));

Validating Values and Arrays

So far, you’ve seen how you can validate entire objects. But sometimes, you just want to validate a simple value - like to verify that a string is a valid email address. This is actually pretty easy to do. From inside a controller, it looks like this:

<?php
use Symfony\Component\Validator\Constraints\Email;

public function addEmailAction($email)
{
    $emailConstraint = new Email();
    // all constraint "options" can be set this way
    $emailConstraint->message = 'Invalid email address';

    // use the validator to validate the value
    $errorList = $this->get('validator')->validateValue($email, $emailConstraint);

    if (count($errorList) == 0) {
        // this IS a valid email address, do something
    } else {
        // this is *not* a valid email address
        $errorMessage = $errorList[0]->getMessage()

        // do something with the error
    }

    // ...
}