Skip to content

Commit c73b8f8

Browse files
committed
[Validator] Add BC layer for notInRangeMessage when min and max are set
1 parent efb4a7f commit c73b8f8

File tree

4 files changed

+125
-2
lines changed

4 files changed

+125
-2
lines changed

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,17 @@ class Range extends Constraint
4646
public $max;
4747
public $maxPropertyPath;
4848

49+
// BC layer, to remove in 6.0
50+
/**
51+
* @internal
52+
*/
53+
public $deprecatedMinMessageSet = false;
54+
55+
/**
56+
* @internal
57+
*/
58+
public $deprecatedMaxMessageSet = false;
59+
4960
public function __construct($options = null)
5061
{
5162
if (\is_array($options)) {
@@ -60,6 +71,15 @@ public function __construct($options = null)
6071
if ((isset($options['minPropertyPath']) || isset($options['maxPropertyPath'])) && !class_exists(PropertyAccess::class)) {
6172
throw new LogicException(sprintf('The "%s" constraint requires the Symfony PropertyAccess component to use the "minPropertyPath" or "maxPropertyPath" option.', static::class));
6273
}
74+
75+
if (isset($options['min']) && isset($options['max'])) {
76+
$this->deprecatedMinMessageSet = isset($options['minMessage']);
77+
$this->deprecatedMaxMessageSet = isset($options['maxMessage']);
78+
79+
if ($this->deprecatedMinMessageSet || $this->deprecatedMaxMessageSet) {
80+
@trigger_error('Since symfony/validator 4.4: minMessage and maxMessage are deprecated when min and max options are set together. Use notInRangeMessage instead.', E_USER_DEPRECATED);
81+
}
82+
}
6383
}
6484

6585
parent::__construct($options);

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

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,24 @@ public function validate($value, Constraint $constraint)
8888
$hasUpperLimit = null !== $max;
8989

9090
if ($hasLowerLimit && $hasUpperLimit && ($value < $min || $value > $max)) {
91-
$violationBuilder = $this->context->buildViolation($constraint->notInRangeMessage)
91+
$message = $constraint->notInRangeMessage;
92+
$code = Range::NOT_IN_RANGE_ERROR;
93+
94+
if ($value < $min && $constraint->deprecatedMinMessageSet) {
95+
$message = $constraint->minMessage;
96+
$code = Range::TOO_LOW_ERROR;
97+
}
98+
99+
if ($value > $max && $constraint->deprecatedMaxMessageSet) {
100+
$message = $constraint->maxMessage;
101+
$code = Range::TOO_HIGH_ERROR;
102+
}
103+
104+
$violationBuilder = $this->context->buildViolation($message)
92105
->setParameter('{{ value }}', $this->formatValue($value, self::PRETTY_DATE))
93106
->setParameter('{{ min }}', $this->formatValue($min, self::PRETTY_DATE))
94107
->setParameter('{{ max }}', $this->formatValue($max, self::PRETTY_DATE))
95-
->setCode(Range::NOT_IN_RANGE_ERROR);
108+
->setCode($code);
96109

97110
if (null !== $constraint->maxPropertyPath) {
98111
$violationBuilder->setParameter('{{ max_limit_path }}', $constraint->maxPropertyPath);

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@
33
namespace Symfony\Component\Validator\Tests\Constraints;
44

55
use PHPUnit\Framework\TestCase;
6+
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
67
use Symfony\Component\Validator\Constraints\Range;
78

89
class RangeTest extends TestCase
910
{
11+
use ExpectDeprecationTrait;
12+
1013
public function testThrowsConstraintExceptionIfBothMinLimitAndPropertyPath()
1114
{
1215
$this->expectException('Symfony\Component\Validator\Exception\ConstraintDefinitionException');
@@ -40,4 +43,31 @@ public function testThrowsNoDefaultOptionConfiguredException()
4043
$this->expectExceptionMessage('No default option is configured');
4144
new Range('value');
4245
}
46+
47+
public function provideDeprecationTriggeredIfMinMaxAndMinMessageOrMaxMessageSet(): array
48+
{
49+
return [
50+
[['min' => 1, 'max' => 10, 'minMessage' => 'my_min_message'], true, false, true],
51+
[['min' => 1, 'max' => 10, 'maxMessage' => 'my_max_message'], false, true, true],
52+
[['min' => 1, 'max' => 10, 'minMessage' => 'my_min_message', 'maxMessage' => 'my_max_message'], true, true, true],
53+
[['min' => 1, 'minMessage' => 'my_min_message', 'maxMessage' => 'my_max_message'], false, false, false],
54+
[['max' => 10, 'minMessage' => 'my_min_message', 'maxMessage' => 'my_max_message'], false, false, false],
55+
[['min' => 1, 'max' => 10, 'notInRangeMessage' => 'my_message'], false, false, false],
56+
];
57+
}
58+
59+
/**
60+
* @group legacy
61+
* @dataProvider provideDeprecationTriggeredIfMinMaxAndMinMessageOrMaxMessageSet
62+
*/
63+
public function testDeprecationTriggeredIfMinMaxAndMinMessageOrMaxMessageSet(array $options, bool $expectedDeprecatedMinMessageSet, bool $expectedDeprecatedMaxMessageSet, bool $expectedDeprecation)
64+
{
65+
if ($expectedDeprecation) {
66+
$this->expectDeprecation('Since symfony/validator 4.4: minMessage and maxMessage are deprecated when min and max options are set together. Use notInRangeMessage instead.');
67+
}
68+
69+
$sut = new Range($options);
70+
$this->assertEquals($expectedDeprecatedMinMessageSet, $sut->deprecatedMinMessageSet);
71+
$this->assertEquals($expectedDeprecatedMaxMessageSet, $sut->deprecatedMaxMessageSet);
72+
}
4373
}

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

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,66 @@ public function testInvalidDatesCombinedMinPropertyPath($value, $dateTimeAsStrin
754754
->setCode(Range::NOT_IN_RANGE_ERROR)
755755
->assertRaised();
756756
}
757+
758+
public function provideMessageIfMinAndMaxSet(): array
759+
{
760+
$notInRangeMessage = (new Range(['min' => '']))->notInRangeMessage;
761+
762+
return [
763+
[
764+
[],
765+
12,
766+
$notInRangeMessage,
767+
Range::NOT_IN_RANGE_ERROR,
768+
],
769+
[
770+
['notInRangeMessage' => 'not_in_range_message'],
771+
12,
772+
'not_in_range_message',
773+
Range::NOT_IN_RANGE_ERROR,
774+
],
775+
[
776+
['minMessage' => 'min_message'],
777+
0,
778+
'min_message',
779+
Range::TOO_LOW_ERROR,
780+
],
781+
[
782+
['maxMessage' => 'max_message'],
783+
0,
784+
$notInRangeMessage,
785+
Range::NOT_IN_RANGE_ERROR,
786+
],
787+
[
788+
['minMessage' => 'min_message'],
789+
15,
790+
$notInRangeMessage,
791+
Range::NOT_IN_RANGE_ERROR,
792+
],
793+
[
794+
['maxMessage' => 'max_message'],
795+
15,
796+
'max_message',
797+
Range::TOO_HIGH_ERROR,
798+
],
799+
];
800+
}
801+
802+
/**
803+
* @group legacy
804+
* @dataProvider provideMessageIfMinAndMaxSet
805+
*/
806+
public function testMessageIfMinAndMaxSet(array $constraintExtraOptions, int $value, string $expectedMessage, string $expectedCode)
807+
{
808+
$constraint = new Range(array_merge(['min' => 1, 'max' => 10], $constraintExtraOptions));
809+
$this->validator->validate($value, $constraint);
810+
811+
$this
812+
->buildViolation($expectedMessage)
813+
->setParameters(['{{ min }}' => '1', '{{ max }}' => '10', '{{ value }}' => (string) $value])
814+
->setCode($expectedCode)
815+
->assertRaised();
816+
}
757817
}
758818

759819
final class Limit

0 commit comments

Comments
 (0)