Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to allow empty values in symfony2 validators

I would like to apply validators on a object properties only when value is not empty ie.

Now standard symfony behavior:

class Entity
{
    /**
     * @ORM\Column(type="string", nullable=true)
     * @Assert\Email()
     */
    protected $email;
    (...)
}

that object will not pass validation if an email is null, or empty string, is there a way to tell validator to assert as a valid, an empty value, and validate only if field has data?

PS I know that I can write callback validator, but writting callback for every field just to have "allowEmpty" feature isn't so nice.

like image 1000
canni Avatar asked Sep 22 '11 17:09

canni


3 Answers

You must explicitly set 'required' => false in your FormBuilder class for all optional fields. Here's a paragraph describing field type options.


Edit. Getting quite a few downvotes. By default all validators treat null values as valid, except NotNull and NotEmpty. Neither of the two was used in the question. The question is implicitly about how to turn off the client-side required attribute that is turned on by default.

like image 188
kgilden Avatar answered Oct 16 '22 14:10

kgilden


Setting the required option is not the solution:

Also note that setting the required option to true will not result in server-side validation to be applied. In other words, if a user submits a blank value for the field (either with an old browser or web service, for example), it will be accepted as a valid value unless you use Symfony's NotBlank or NotNull validation constraint.

http://symfony.com/doc/current/book/forms.html#field-type-options

For my custom validators, I add a

if (null == $value) {
    return true;
}

to the isValid() method. However, I'm not sure what would be the best way for the standard validator classes.

like image 44
David de Boer Avatar answered Oct 16 '22 16:10

David de Boer


if i understand correctly you want server side validation only if value is entered. I am exactly in the same scenario. I want to validate a URL only if the URL is provided. The best way i came across was to write my own custom validation class. You can write a generic custom validation class.

I followed this link https://symfony-docs-chs.readthedocs.org/en/2.0/cookbook/validation/custom_constraint.html except for few changes because of symfony's latest version. Here is the implementation

Acme\BundleNameBundle\Validator\Constraints\cstmUrl

namespace Acme\BundleNameBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Constraints\Url;

/**
 * @Annotation
 */
class CstmUrl extends Url
{
    public $message = 'The URL "%string%" is not valid';
}

Acme\BundleNameBundle\Validator\Constraints\cstmUrlValidator

namespace Acme\BundleNameBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Constraints\Url;
use Symfony\Component\Validator\Constraints\UrlValidator;

class CstmUrlValidator extends UrlValidator
{
    public function validate($value, Constraint $constraint)
    {
        if(!$value || empty($value))
            return true;

        parent::validate($value, $constraint);
    }
}

Validtion.yml

Acme\BundleNameBundle\Entity\Student:
    Url:
        - Acme\BundleNameBundle\Validator\Constraints\CstmUrl: ~

inside Controller just bind the constraint you normally would do

'constraints'=> new CstmUrl(array("message"=>"Invalid url provided"))

I am sure there can be other better ways of doing it, but for now i feel this does the job well.

like image 3
Ahad Ali Avatar answered Oct 16 '22 15:10

Ahad Ali