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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With