Baby Webmaster
Baby Webmaster

Reputation: 335

Symfony validation: range between two numbers, OR a value

I would like to validate a number to be between 10 and 20, or 30 and 40 or equal to 99.

I could imagine the code to be something similar to this, but it does not work:

In Entity\NameOfFile.php:

/*
 * @Assert\Range(
 *   min=10,
 *   max=20
 * )
 *
 * @Assert\Range(
 *  min=30,
 *  max=40
 * )
 *
 * @Assert\IdenticalTo(value = 99)
 */
 private $myVariable;

Or maybe something similar to this:

 /*
  * @Assert\Choice({
  *  Range({min = 10, max = 20}),
  *  Range({min = 10, max = 20}), 
  *  99
  * )}
  */
  private $myVariable;

I also added min and max messages.

In the first option, apparently only the first Assert is taken into consideration and the second one is ignored. The second option, does not work at all.

Ps: Please, a solution without Regex

EDIT: Following the advice of M Khalid Juanid, the code looks like this:

/**
 * @Assert\Expression(
 *     "this.getmyVariable() in 10..20 or this.getmyVariable() in 30..40 or this.getmyVariable() == 99",
 *     message="Your error message", groups{"groupA"}
 * )
*private $myVariable;
 */

  ***
if($appendForm->isValid(array($groupA))
{
***  
}

It works fine, but only when the validation is not assigned to groupA. How can, the validation be assigned to a group, in this case?

Upvotes: 3

Views: 2337

Answers (3)

Sonny Milton
Sonny Milton

Reputation: 1

Since Symfony 5.1, there is a new validator that can check if at least one of several constraints is met. AtLeastOneOf

 /**
 * @Assert\AtLeastOneOf({
 *      @Assert\Range(
 *          min=10,
 *          max=20
 *      ),
 *      @Assert\Range(
 *          min=30,
 *          max=40
 *      ),
 *      @Assert\IdenticalTo(value = 99)
 * })
 */
private $myVariable;

Upvotes: 0

M Khalid Junaid
M Khalid Junaid

Reputation: 64476

You can use @Assert\Expression for your mulitple criteria

/**
 * @Assert\Expression(
 *     "this.checkRange()",
 *     message="Your error message"
 * )
 */
class YourEntityName
{
    public function checkRange(){
        if(
            ($this->yourPorperty >= 10 && $this->yourPorperty <= 20)
            || ($this->yourPorperty >= 30 && $this->yourPorperty <= 40)
            || ($this->yourPorperty == 90)
        ){
            return true;
        }

        return false;
    }
}

As per docs The expression option is the expression that must return true in order for validation to pass

Even more simpler according to the documentation

/**
 * @Assert\Expression(
 *     "this.getYourPorperty() in 10..20 or this.getYourPorperty() in 30..40 or this.getYourPorperty() == 90",
 *     message="Your error message"
 * )
 */

Upvotes: 4

Nicolas
Nicolas

Reputation: 414

You can use a custom validation constraint. To create one you can refer to the official documentation: http://symfony.com/doc/3.4/validation/custom_constraint.html

You will have to put all your constraints in the validate function of the Validator class.

Upvotes: 0

Related Questions