One field should not be empty if some fields are empty in symfony form

In my Symfony 2 application (2.4.2) there is a Form Type that consists of 3 fields.

I would like the check to be like this: If field A and field B empty, field C should not be empty. This means that at least one field must receive some data.

I am currently checking the received data in the controller. Is there a more recommended way to do this?

+7
php symfony
source share
3 answers

There are even simpler solutions than creating a custom validator. The simplest of these is probably the expression constraint:

 class MyEntity { private $fieldA; private $fieldB; /** * @Assert\Expression( * expression="this.fieldA != '' || this.fieldB != '' || value != ''", * message="Either field A or field B or field C must be set" * ) */ private $fieldC; } 

You can also add a validation method to your class and annotate it with a callback restriction:

 /** * @Assert\Callback */ public function validateFields(ExecutionContextInterface $context) { if ('' === $this->fieldA && '' === $this->fieldB && '' === $this->fieldC) { $context->addViolation('At least one of the fields must be filled'); } } 

The method will be executed during class verification.

+12
source share

This is probably a precedent for Custom Validation Constraint . I did not use it myself, but basically you create Constraint and Validator . Then you specify your Constraint in config/validation.yml .

 Your\Bundle\Entity\YourEntity: constraints: - Your\BundleValidator\Constraints\YourConstraint: ~ 

Actual validation is done using Validator . You can tell Symfony to pass the entire object to your validate method to access multiple fields with:

 public function getTargets() { return self::CLASS_CONSTRAINT; } 

And your validate :

 public function validate($entity, Constraint $constraint) { // Do whatever validation you need // You can specify an error message inside your Constraint if (/* $entity->getFieldA(), ->getFieldB(), ->getFieldC() ... */) { $this->context->addViolationAt( 'foo', $constraint->message, array(), null ); } } 
+3
source share

You can do this using "Group Sequence Providers" , for example:

 use Symfony\Component\Validator\GroupSequenceProviderInterface; /** * @Assert\GroupSequenceProvider */ class MyObject implements GroupSequenceProviderInterface { /** * @Assert\NotBlank(groups={"OptionA"}) */ private $fieldA; /** * @Assert\NotBlank(groups={"OptionA"}) */ private $fieldB; /** * @Assert\NotBlank(groups={"OptionB"}) */ private $fieldC; public function getGroupSequence() { $groups = array('MyObject'); if ($this->fieldA == null && $this->fieldB == null) { $groups[] = 'OptionB'; } else { $groups[] = 'OptionA'; } return $groups; } } 

Not tested, but I think it will work

0
source share

All Articles