diff --git a/src/Symfony/Component/Validator/CHANGELOG.md b/src/Symfony/Component/Validator/CHANGELOG.md
index d3bebec61e..1dea1e7fa1 100644
--- a/src/Symfony/Component/Validator/CHANGELOG.md
+++ b/src/Symfony/Component/Validator/CHANGELOG.md
@@ -8,6 +8,7 @@ CHANGELOG
* added option `alpha3` to `Country` constraint
* allow to define a reusable set of constraints by extending the `Compound` constraint
* added `Sequentially` constraint, to sequentially validate a set of constraints (any violation raised will prevent further validation of the nested constraints)
+ * added the `divisibleBy` option to the `Count` constraint
5.0.0
-----
diff --git a/src/Symfony/Component/Validator/Constraints/Count.php b/src/Symfony/Component/Validator/Constraints/Count.php
index b11f994f58..6d1e7afcd8 100644
--- a/src/Symfony/Component/Validator/Constraints/Count.php
+++ b/src/Symfony/Component/Validator/Constraints/Count.php
@@ -24,17 +24,21 @@ class Count extends Constraint
{
const TOO_FEW_ERROR = 'bef8e338-6ae5-4caf-b8e2-50e7b0579e69';
const TOO_MANY_ERROR = '756b1212-697c-468d-a9ad-50dd783bb169';
+ const NOT_DIVISIBLE_BY_ERROR = DivisibleBy::NOT_DIVISIBLE_BY;
protected static $errorNames = [
self::TOO_FEW_ERROR => 'TOO_FEW_ERROR',
self::TOO_MANY_ERROR => 'TOO_MANY_ERROR',
+ self::NOT_DIVISIBLE_BY_ERROR => 'NOT_DIVISIBLE_BY_ERROR',
];
public $minMessage = 'This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.';
public $maxMessage = 'This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.';
public $exactMessage = 'This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.';
+ public $divisibleByMessage = 'The number of elements in this collection should be a multiple of {{ compared_value }}.';
public $min;
public $max;
+ public $divisibleBy;
public function __construct($options = null)
{
@@ -50,8 +54,8 @@ class Count extends Constraint
parent::__construct($options);
- if (null === $this->min && null === $this->max) {
- throw new MissingOptionsException(sprintf('Either option "min" or "max" must be given for constraint %s', __CLASS__), ['min', 'max']);
+ if (null === $this->min && null === $this->max && null === $this->divisibleBy) {
+ throw new MissingOptionsException(sprintf('Either option "min", "max" or "divisibleBy" must be given for constraint %s', __CLASS__), ['min', 'max', 'divisibleBy']);
}
}
}
diff --git a/src/Symfony/Component/Validator/Constraints/CountValidator.php b/src/Symfony/Component/Validator/Constraints/CountValidator.php
index 5c40e47b21..9f9ac4d405 100644
--- a/src/Symfony/Component/Validator/Constraints/CountValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/CountValidator.php
@@ -60,6 +60,20 @@ class CountValidator extends ConstraintValidator
->setPlural((int) $constraint->min)
->setCode(Count::TOO_FEW_ERROR)
->addViolation();
+
+ return;
+ }
+
+ if (null !== $constraint->divisibleBy) {
+ $this->context
+ ->getValidator()
+ ->inContext($this->context)
+ ->validate($count, [
+ new DivisibleBy([
+ 'value' => $constraint->divisibleBy,
+ 'message' => $constraint->divisibleByMessage,
+ ]),
+ ], $this->context->getGroup());
}
}
}
diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.en.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.en.xlf
index 635e6736f6..8f8d2d0a0f 100644
--- a/src/Symfony/Component/Validator/Resources/translations/validators.en.xlf
+++ b/src/Symfony/Component/Validator/Resources/translations/validators.en.xlf
@@ -370,6 +370,10 @@
This value is not a valid hostname.
+
+
+ The number of elements in this collection should be a multiple of {{ compared_value }}.
+