I'm using symfony 2.8 version and I have encountered a following problem. I want my field 'seeAlso' of entity 'Article' to be restricted to have either zero (none) or at least 3 objects (another articles). So I have these in my yaml validation:
seeAlso:
- Count:
min: 3
minMessage: 'you have got to pick zero or at least three articles'
It checks if it is less than three well, but it does not allow me to let the field be empty. How do I make this work?
You should define a custom validation. You can proceed in two ways
First of all you need to create a constraint class
use Symfony\Component\Validator\Constraint;
/**
* @Annotation
*/
class ConstraintZeroOrAtLeastThreeConstraint extends Constraint
{
public $message = 'Put here a validation error message';
public function validatedBy()
{
return get_class($this).'Validator';
}
}
Here you have defined a constraint with a message and you're telling to symfony which is the validator (that we're going to define below)
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class ZeroOrAtLeastThreeConstraintValidator extends ConstraintValidator
{
public function validate($value, Constraint $constraint)
{
if (!count($value)) {
return;
}
if (count($value) >= 3) {
return;
}
$this
->context
->buildValidation('You should choose zero or at least three elements')
->addViolation();
}
}
Now you can use your validator upon the property by annotating it with @ ConstraintZeroOrAtLeastThreeConstraint
(that of course you have to import in entity file in order to use)
Of course you can even customize the values 0 and 3 to generalize this constraint into ZeroOrAtLeastTimesConstraint
by using
public function __construct($options)
{
if (!isset($options['atLeastTimes'])) {
throw new MissingOptionException(...);
}
$this->atLeastTimes = $options['atLeastTimes'];
}
/**
* @Assert\Callback
*/
public function validate(ExecutionContextInterface $context, $payload)
{
if (!count($this->getArticles()) {
return;
}
if (count($this->getArticles() >= 3) {
return;
}
$context
->buildViolation('You should choose 0 or at least 3 articles')
->addViolation();
}