Symfony2 validator, NotBlank but allow null

12,511

Solution 1

The NotBlank constraint treats null as a blank value, as can be seen in this test.

When using doctrine, this can be solved by using the Valid constraint. If the value of the field is not null, it will attempt to validate it.

Since you are not using doctrine entities, you'll probably have to use a callback validator or write your own constraint.

EDIT

To answer your new question on adding a callback constraint as a property constraint: No, it is not possible to do that.

The callback constraint acts on the whole object, not just a single property. Here's an example of how you can use the callback constraint:

use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Validator\ExecutionContext;

$app = new Silex\Application();

$app->register(new Silex\Provider\ValidatorServiceProvider());

class Person
{
    public $name;

    public function validateName(ExecutionContext $context)
    {
        if ('John Doe' === $this->name) {
            $context->addViolationAtPath('name', 'Name must not be "John Doe"');
        }
    }

    static public function loadValidatorMetadata(ClassMetadata $metadata)
    {
        $metadata->addConstraint(new Assert\Callback(array('validateName')));
        $metadata->addPropertyConstraint('name', new Assert\NotNull());
    }
}

$person = new Person();
$person->name = 'John Doe';
$violations = $app['validator']->validate($person);
var_dump('Violations for John Doe');
var_dump((string) $violations);

$person = new Person();
$violations = $app['validator']->validate($person);
var_dump('Violations for Person with name null');
var_dump((string) $violations);

$person = new Person();
$person->name = 'Igor Wiedler';
$violations = $app['validator']->validate($person);
var_dump('Violations for Igor Wiedler');
var_dump((string) $violations);

Solution 2

For anyone who runs into this on a later version (4.3 onwards), you can set allowNull = true:

namespace App\Entity;

use Symfony\Component\Validator\Constraints as Assert;

class SomeEntity
{
    /**
     * @Assert\NotBlank(allowNull = true)
     */
    protected $someProperty;
}
Share:
12,511
ChrisR
Author by

ChrisR

Zend Certified PHP Engineer and Certified Scrum master with over 15 years of professional web application development experience working with small, large, local and offshore teams. Experienced with frameworks like Zend Framework, Silex and Symfony and self built frameworks for specific application development. Building and maintaining complex software, working with legacy code and building a RESTful webservices from the ground up according to the real restful principles. Fond interest and knowledge of modern front-end applications/frameworks like AngularJS and React along with the frontend eco system. Likes working with people, building teams and helping them improve.

Updated on June 27, 2022

Comments

  • ChrisR
    ChrisR almost 2 years

    I'm having trouble validating a value to allow NULL but not an empty string with the Symfony2 validator component.

    I've integrated the component in a Silex application and used the Property Constraint target to validate some properties of my Application Entities (not a Doctrine Entity).

    I've added this static method to my Entity class to validate name and service_id on my Entity, problem is that when service_id is NULL which should be valid the NotBlank constraint kicks in and reports a violation.

    static public function loadValidatorMetadata(ClassMetadata $metadata)
    {
        // name should never be NULL or a blank string
        $metadata->addPropertyConstraint('name', new Assert\NotNull());
        $metadata->addPropertyConstraint('name', new Assert\NotBlank());
    
        // service_id should either be a non-blank string or NULL
        $metadata->addPropertyConstraint('service_id', new Assert\NotBlank());
    }
    

    Bottomline, I'm looking how to allow either a String or NULL as service_id but not allow an empty string.

    PS: I've also tried the MinLength(1) constraint but that allows empty strings unfortunately.

    • dbrumann
      dbrumann about 12 years
      There is a Null-Validator, but it won't help you either, as only NULL will be valid, i.e. if it's a string (empty or not) it will be violated. Why not write a custom Validator?
    • ChrisR
      ChrisR about 12 years
      A custom validator is indeed an option but to me it seemed such a common usecase that it's hard to believe it's impossible to do out of the box.
    • codepushr
      codepushr almost 10 years
      Me, too. In fact this seems even wrong (or at least the wording). For me NotBlank means that there should be a validation for a blank string. I don't understand why the constraint treats null as a blank value.
  • ChrisR
    ChrisR about 12 years
    From what I've tried callback validators won't work on property constraints in Silex or am I wrong?
  • igorw
    igorw about 12 years
    I've updated my answer to explain how to use the callback constraint.