Skip to content

Commit f01bbc7

Browse files
committed
feature #35783 [Validator] Add the divisibleBy option to the Count constraint (fancyweb)
This PR was merged into the 5.1-dev branch. Discussion ---------- [Validator] Add the divisibleBy option to the Count constraint | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | - | License | MIT | Doc PR | TODO From my experience, it is sometimes useful to assert that the number of elements in a collection is a multiple of X. Commits ------- 8dfb7b2 [Validator] Add the divisibleBy option to the Count constraint
2 parents d33a483 + 8dfb7b2 commit f01bbc7

File tree

6 files changed

+49
-2
lines changed

6 files changed

+49
-2
lines changed

src/Symfony/Component/Validator/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ CHANGELOG
88
* added option `alpha3` to `Country` constraint
99
* allow to define a reusable set of constraints by extending the `Compound` constraint
1010
* added `Sequentially` constraint, to sequentially validate a set of constraints (any violation raised will prevent further validation of the nested constraints)
11+
* added the `divisibleBy` option to the `Count` constraint
1112

1213
5.0.0
1314
-----

src/Symfony/Component/Validator/Constraints/Count.php

+6-2
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,21 @@ class Count extends Constraint
2424
{
2525
const TOO_FEW_ERROR = 'bef8e338-6ae5-4caf-b8e2-50e7b0579e69';
2626
const TOO_MANY_ERROR = '756b1212-697c-468d-a9ad-50dd783bb169';
27+
const NOT_DIVISIBLE_BY_ERROR = DivisibleBy::NOT_DIVISIBLE_BY;
2728

2829
protected static $errorNames = [
2930
self::TOO_FEW_ERROR => 'TOO_FEW_ERROR',
3031
self::TOO_MANY_ERROR => 'TOO_MANY_ERROR',
32+
self::NOT_DIVISIBLE_BY_ERROR => 'NOT_DIVISIBLE_BY_ERROR',
3133
];
3234

3335
public $minMessage = 'This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more.';
3436
public $maxMessage = 'This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less.';
3537
public $exactMessage = 'This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements.';
38+
public $divisibleByMessage = 'The number of elements in this collection should be a multiple of {{ compared_value }}.';
3639
public $min;
3740
public $max;
41+
public $divisibleBy;
3842

3943
public function __construct($options = null)
4044
{
@@ -50,8 +54,8 @@ public function __construct($options = null)
5054

5155
parent::__construct($options);
5256

53-
if (null === $this->min && null === $this->max) {
54-
throw new MissingOptionsException(sprintf('Either option "min" or "max" must be given for constraint %s', __CLASS__), ['min', 'max']);
57+
if (null === $this->min && null === $this->max && null === $this->divisibleBy) {
58+
throw new MissingOptionsException(sprintf('Either option "min", "max" or "divisibleBy" must be given for constraint %s', __CLASS__), ['min', 'max', 'divisibleBy']);
5559
}
5660
}
5761
}

src/Symfony/Component/Validator/Constraints/CountValidator.php

+14
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,20 @@ public function validate($value, Constraint $constraint)
6060
->setPlural((int) $constraint->min)
6161
->setCode(Count::TOO_FEW_ERROR)
6262
->addViolation();
63+
64+
return;
65+
}
66+
67+
if (null !== $constraint->divisibleBy) {
68+
$this->context
69+
->getValidator()
70+
->inContext($this->context)
71+
->validate($count, [
72+
new DivisibleBy([
73+
'value' => $constraint->divisibleBy,
74+
'message' => $constraint->divisibleByMessage,
75+
]),
76+
], $this->context->getGroup());
6377
}
6478
}
6579
}

src/Symfony/Component/Validator/Resources/translations/validators.en.xlf

+4
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,10 @@
370370
<source>This value is not a valid hostname.</source>
371371
<target>This value is not a valid hostname.</target>
372372
</trans-unit>
373+
<trans-unit id="96">
374+
<source>The number of elements in this collection should be a multiple of {{ compared_value }}.</source>
375+
<target>The number of elements in this collection should be a multiple of {{ compared_value }}.</target>
376+
</trans-unit>
373377
</body>
374378
</file>
375379
</xliff>

src/Symfony/Component/Validator/Resources/translations/validators.fr.xlf

+4
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,10 @@
370370
<source>This value is not a valid hostname.</source>
371371
<target>Cette valeur n'est pas un nom d'hôte valide.</target>
372372
</trans-unit>
373+
<trans-unit id="96">
374+
<source>The number of elements in this collection should be a multiple of {{ compared_value }}.</source>
375+
<target>Le nombre d'éléments de cette collection doit être un multiple de {{ compared_value }}.</target>
376+
</trans-unit>
373377
</body>
374378
</file>
375379
</xliff>

src/Symfony/Component/Validator/Tests/Constraints/CountValidatorTest.php

+20
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\Validator\Constraints\Count;
1515
use Symfony\Component\Validator\Constraints\CountValidator;
16+
use Symfony\Component\Validator\Constraints\DivisibleBy;
1617
use Symfony\Component\Validator\Test\ConstraintValidatorTestCase;
1718

1819
/**
@@ -202,4 +203,23 @@ public function testConstraintAnnotationDefaultOption()
202203
$this->assertEquals(5, $constraint->max);
203204
$this->assertEquals('message', $constraint->exactMessage);
204205
}
206+
207+
// Since the contextual validator is mocked, this test only asserts that it
208+
// is called with the right DivisibleBy constraint.
209+
public function testDivisibleBy()
210+
{
211+
$constraint = new Count([
212+
'divisibleBy' => 123,
213+
'divisibleByMessage' => 'foo {{ compared_value }}',
214+
]);
215+
216+
$this->expectValidateValue(0, 3, [new DivisibleBy([
217+
'value' => 123,
218+
'message' => 'foo {{ compared_value }}',
219+
])], $this->group);
220+
221+
$this->validator->validate(['foo', 'bar', 'ccc'], $constraint);
222+
223+
$this->assertNoViolation();
224+
}
205225
}

0 commit comments

Comments
 (0)