Symfony2 forms without an entity and with a conditional validator

Recently on a project I had a situation where I was using the Symfony2 forms component without an entity. In addition to each field’s constraints, I needed to something similar to symfony 1.4’s conditional validator so that I could make sure that the form on the whole was valid. There are a bunch of docs out there on how to use callback functions on an entity to do this, however I didn’t see much on how to get the entire form that has no entity to do a callback. After reading some of the source code, found that you can set up some ‘form level’ constraints in the setDefaultOptions method. So it will look something like this:

You pass the Callback constraint an array methods which it can call. If you pass one of those methods is an array it is parsed as class::method. In my case by passing $this it uses the currently instantiated form, rather than trying to call the method statically.

From there you can do something like this:

The first parameter is the form’s data fields. From there you can add global level errors to the form, such as if a combination of fields are not valid.

Good luck out there.

Posted In: PHP, Symfony

Tags: , , , , , ,

  • Soullivaneuh

    Great tip ! Thanks ! :)

  • Fabien Rondeau

    Great post, I am trying to figure how to set the violation to one of the field using the “addViolationAt”. Do you have any tip on how to get the subPath of a field from this point ?

  • Matt Daum

    I think you may be able to use the getPropertyPath() function on the $context

  • Fabien Rondeau

    This is available only when you have an entity behind your form.
    I found a way to do it by adding ‘error_mapping’ => array( ‘myViolationField’ => ‘myTypeKey’ ) on the default resolver and $context->addViolationAt(‘myViolationField’ , ‘My error message’). Like that the violation is mapped to ‘myViolationField’ which is linked to my real field.

  • Kegan VanSickle

    This works beautifully, just what I needed. Thanks!

  • Pelofy

    Awesome.. big help. Just what we needed for our advanced search form validation.

  • Micah

    This worked perfectly. Thank you both!

  • turibe

    Very helpful. FYI, if you only need one callback you can simplify your code to:

    ‘constraints’ => new Callback([$this, ‘checkAvailableFunds’])

  • Meenakshi Gaikwad

    Gr8 post..saved my time a lot..thanks Matt!!