Skip to content

Commit 592e72f

Browse files
committed
feature #28637 [Validator] add number constraints (jschaedl)
This PR was squashed before being merged into the 4.3-dev branch (closes #28637). Discussion ---------- [Validator] add number constraints | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #28608 | License | MIT | Doc PR | tbd. I added the following constraints: * `Positive` * `PositiveOrZero` * `Negative` * `NegativeOrZero` Commits ------- 0187039 [Validator] add number constraints
2 parents 6070151 + 0187039 commit 592e72f

13 files changed

+686
-0
lines changed

src/Symfony/Component/Validator/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ CHANGELOG
1010
* added `Json` constraint
1111
* added `Unique` constraint
1212
* added a new `normalizer` option to the string constraints and to the `NotBlank` constraint
13+
* added `Positive` constraint
14+
* added `PositiveOrZero` constraint
15+
* added `Negative` constraint
16+
* added `NegativeOrZero` constraint
1317

1418
4.2.0
1519
-----
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Validator\Constraints;
13+
14+
/**
15+
* @Annotation
16+
* @Target({"PROPERTY", "METHOD", "ANNOTATION"})
17+
*
18+
* @author Jan Schädlich <jan.schaedlich@sensiolabs.de>
19+
*/
20+
class Negative extends LessThan
21+
{
22+
use NumberConstraintTrait;
23+
24+
public $message = 'This value should be negative.';
25+
26+
public function __construct($options = null)
27+
{
28+
parent::__construct($this->configureNumberConstraintOptions($options));
29+
}
30+
31+
public function validatedBy(): string
32+
{
33+
return LessThanValidator::class;
34+
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Validator\Constraints;
13+
14+
/**
15+
* @Annotation
16+
* @Target({"PROPERTY", "METHOD", "ANNOTATION"})
17+
*
18+
* @author Jan Schädlich <jan.schaedlich@sensiolabs.de>
19+
*/
20+
class NegativeOrZero extends LessThanOrEqual
21+
{
22+
use NumberConstraintTrait;
23+
24+
public $message = 'This value should be either negative or zero.';
25+
26+
public function __construct($options = null)
27+
{
28+
parent::__construct($this->configureNumberConstraintOptions($options));
29+
}
30+
31+
public function validatedBy(): string
32+
{
33+
return LessThanOrEqualValidator::class;
34+
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Validator\Constraints;
13+
14+
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
15+
16+
/**
17+
* @author Jan Schädlich <jan.schaedlich@sensiolabs.de>
18+
*/
19+
trait NumberConstraintTrait
20+
{
21+
private function configureNumberConstraintOptions($options): array
22+
{
23+
if (null === $options) {
24+
$options = [];
25+
} elseif (!\is_array($options)) {
26+
$options = [$this->getDefaultOption() => $options];
27+
}
28+
29+
if (isset($options['propertyPath'])) {
30+
throw new ConstraintDefinitionException(sprintf('The "propertyPath" option of the "%s" constraint cannot be set.', \get_class($this)));
31+
}
32+
33+
if (isset($options['value'])) {
34+
throw new ConstraintDefinitionException(sprintf('The "value" option of the "%s" constraint cannot be set.', \get_class($this)));
35+
}
36+
37+
$options['value'] = 0;
38+
39+
return $options;
40+
}
41+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Validator\Constraints;
13+
14+
/**
15+
* @Annotation
16+
* @Target({"PROPERTY", "METHOD", "ANNOTATION"})
17+
*
18+
* @author Jan Schädlich <jan.schaedlich@sensiolabs.de>
19+
*/
20+
class Positive extends GreaterThan
21+
{
22+
use NumberConstraintTrait;
23+
24+
public $message = 'This value should be positive.';
25+
26+
public function __construct($options = null)
27+
{
28+
parent::__construct($this->configureNumberConstraintOptions($options));
29+
}
30+
31+
public function validatedBy(): string
32+
{
33+
return GreaterThanValidator::class;
34+
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Validator\Constraints;
13+
14+
/**
15+
* @Annotation
16+
* @Target({"PROPERTY", "METHOD", "ANNOTATION"})
17+
*
18+
* @author Jan Schädlich <jan.schaedlich@sensiolabs.de>
19+
*/
20+
class PositiveOrZero extends GreaterThanOrEqual
21+
{
22+
use NumberConstraintTrait;
23+
24+
public $message = 'This value should be either positive or zero.';
25+
26+
public function __construct($options = null)
27+
{
28+
parent::__construct($this->configureNumberConstraintOptions($options));
29+
}
30+
31+
public function validatedBy(): string
32+
{
33+
return GreaterThanOrEqualValidator::class;
34+
}
35+
}

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

+16
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,22 @@
330330
<source>This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}.</source>
331331
<target>Diese internationale Bankleitzahl (BIC) ist nicht mit der IBAN {{ iban }} assoziiert.</target>
332332
</trans-unit>
333+
<trans-unit id="87">
334+
<source>This value should be positive.</source>
335+
<target>Dieser Wert sollte positiv sein.</target>
336+
</trans-unit>
337+
<trans-unit id="88">
338+
<source>This value should be either positive or zero.</source>
339+
<target>Dieser Wert sollte entweder positiv oder 0 sein.</target>
340+
</trans-unit>
341+
<trans-unit id="89">
342+
<source>This value should be negative.</source>
343+
<target>Dieser Wert sollte negativ sein.</target>
344+
</trans-unit>
345+
<trans-unit id="90">
346+
<source>This value should be either negative or zero.</source>
347+
<target>Dieser Wert sollte entweder negativ oder 0 sein.</target>
348+
</trans-unit>
333349
</body>
334350
</file>
335351
</xliff>

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

+16
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,22 @@
334334
<source>This value should be valid JSON.</source>
335335
<target>This value should be valid JSON.</target>
336336
</trans-unit>
337+
<trans-unit id="87">
338+
<source>This value should be positive.</source>
339+
<target>This value should be positive.</target>
340+
</trans-unit>
341+
<trans-unit id="88">
342+
<source>This value should be either positive or zero.</source>
343+
<target>This value should be either positive or zero.</target>
344+
</trans-unit>
345+
<trans-unit id="89">
346+
<source>This value should be negative.</source>
347+
<target>This value should be negative.</target>
348+
</trans-unit>
349+
<trans-unit id="90">
350+
<source>This value should be either negative or zero.</source>
351+
<target>This value should be either negative or zero.</target>
352+
</trans-unit>
337353
</body>
338354
</file>
339355
</xliff>

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

+16
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,22 @@
278278
<source>This value should not be identical to {{ compared_value_type }} {{ compared_value }}.</source>
279279
<target>Giá trị không được phép giống như {{ compared_value_type }} {{ compared_value }}.</target>
280280
</trans-unit>
281+
<trans-unit id="87">
282+
<source>This value should be positive.</source>
283+
<target>Giá trị này có thể thực hiện được.</target>
284+
</trans-unit>
285+
<trans-unit id="88">
286+
<source>This value should be either positive or zero.</source>
287+
<target>Giá trị này có thể thực hiện được hoặc bằng không.</target>
288+
</trans-unit>
289+
<trans-unit id="89">
290+
<source>This value should be negative.</source>
291+
<target>Giá trị này nên bị từ chối.</target>
292+
</trans-unit>
293+
<trans-unit id="90">
294+
<source>This value should be either negative or zero.</source>
295+
<target>Giá trị này nên bị từ chối hoặc bằng không.</target>
296+
</trans-unit>
281297
</body>
282298
</file>
283299
</xliff>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Validator\Tests\Constraints;
13+
14+
use Symfony\Component\Validator\Constraints\PositiveOrZero;
15+
16+
/**
17+
* @author Jan Schädlich <jan.schaedlich@sensiolabs.de>
18+
*/
19+
class GreaterThanOrEqualValidatorWithPositiveOrZeroConstraintTest extends GreaterThanOrEqualValidatorTest
20+
{
21+
protected function createConstraint(array $options = null)
22+
{
23+
return new PositiveOrZero();
24+
}
25+
26+
/**
27+
* {@inheritdoc}
28+
*/
29+
public function provideValidComparisons()
30+
{
31+
return [
32+
[0, 0],
33+
[1, 0],
34+
[2, 0],
35+
[2.5, 0],
36+
['0', '0'],
37+
['333', '0'],
38+
[null, 0],
39+
];
40+
}
41+
42+
/**
43+
* {@inheritdoc}
44+
*/
45+
public function provideInvalidComparisons()
46+
{
47+
return [
48+
[-1, '-1', 0, '0', 'integer'],
49+
[-2, '-2', 0, '0', 'integer'],
50+
[-2.5, '-2.5', 0, '0', 'integer'],
51+
];
52+
}
53+
54+
/**
55+
* @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
56+
* @expectedExceptionMessage The "propertyPath" option of the "Symfony\Component\Validator\Constraints\PositiveOrZero" constraint cannot be set.
57+
*/
58+
public function testThrowsConstraintExceptionIfPropertyPath()
59+
{
60+
return new PositiveOrZero(['propertyPath' => 'field']);
61+
}
62+
63+
/**
64+
* @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
65+
* @expectedExceptionMessage The "value" option of the "Symfony\Component\Validator\Constraints\PositiveOrZero" constraint cannot be set.
66+
*/
67+
public function testThrowsConstraintExceptionIfValue()
68+
{
69+
return new PositiveOrZero(['value' => 0]);
70+
}
71+
72+
/**
73+
* @dataProvider provideInvalidConstraintOptions
74+
* @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
75+
* @expectedExceptionMessage requires either the "value" or "propertyPath" option to be set.
76+
*/
77+
public function testThrowsConstraintExceptionIfNoValueOrPropertyPath($options)
78+
{
79+
$this->markTestSkipped('Value option always set for PositiveOrZero constraint');
80+
}
81+
82+
/**
83+
* @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
84+
* @expectedExceptionMessage requires only one of the "value" or "propertyPath" options to be set, not both.
85+
*/
86+
public function testThrowsConstraintExceptionIfBothValueAndPropertyPath()
87+
{
88+
$this->markTestSkipped('Value option is set for PositiveOrZero constraint automatically');
89+
}
90+
91+
public function testInvalidValuePath()
92+
{
93+
$this->markTestSkipped('PropertyPath option is not used in PositiveOrZero constraint');
94+
}
95+
96+
/**
97+
* @dataProvider provideValidComparisonsToPropertyPath
98+
*/
99+
public function testValidComparisonToPropertyPath($comparedValue)
100+
{
101+
$this->markTestSkipped('PropertyPath option is not used in PositiveOrZero constraint');
102+
}
103+
104+
/**
105+
* @dataProvider provideValidComparisonsToPropertyPath
106+
*/
107+
public function testValidComparisonToPropertyPathOnArray($comparedValue)
108+
{
109+
$this->markTestSkipped('PropertyPath option is not used in Positive constraint');
110+
}
111+
}

0 commit comments

Comments
 (0)