Skip to content

Commit f3753e9

Browse files
committed
bug #36140 [Validator] Add BC layer for notInRangeMessage when min and max are set (l-vo)
This PR was merged into the 4.4 branch. Discussion ---------- [Validator] Add BC layer for notInRangeMessage when min and max are set | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix #36133 | License | MIT | Doc PR | According to #36133, the improvement added in #32435 may lead to a BC break when the developer pass `min` and `max` options and a custom `minMessage` or `maxMessage`. In this case it's expected to receive a `minMessage`/`maxMessage` in the violation but a `notInRangeMessage` is received instead. So in the following conditions: - `min` and `max` options are set - `minMessage` or `maxMessage` is set A deprecation is triggered. If a limit is violated and matches to the min/max message passed as option (`minMessage` for `min` violated and `maxMessage` for `max` violated), `minMessage/maxMessage` is used in the violation instead of `notInRangeMessage`. Commits ------- 092d85c [Validator] Add BC layer for notInRangeMessage when min and max are set
2 parents 7e85a6a + 092d85c commit f3753e9

File tree

4 files changed

+134
-2
lines changed

4 files changed

+134
-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 be removed in 5.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 the "min" and "max" options are both set. 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: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,43 @@ public function testThrowsNoDefaultOptionConfiguredException()
4040
$this->expectExceptionMessage('No default option is configured');
4141
new Range('value');
4242
}
43+
44+
public function provideDeprecationTriggeredIfMinMaxAndMinMessageOrMaxMessageSet(): array
45+
{
46+
return [
47+
[['min' => 1, 'max' => 10, 'minMessage' => 'my_min_message'], true, false],
48+
[['min' => 1, 'max' => 10, 'maxMessage' => 'my_max_message'], false, true],
49+
[['min' => 1, 'max' => 10, 'minMessage' => 'my_min_message', 'maxMessage' => 'my_max_message'], true, true],
50+
];
51+
}
52+
53+
/**
54+
* @group legacy
55+
* @expectedDeprecation Since symfony/validator 4.4: minMessage and maxMessage are deprecated when min and max options are set together. Use notInRangeMessage instead.
56+
* @dataProvider provideDeprecationTriggeredIfMinMaxAndMinMessageOrMaxMessageSet
57+
*/
58+
public function testDeprecationTriggeredIfMinMaxAndMinMessageOrMaxMessageSet(array $options, bool $expectedDeprecatedMinMessageSet, bool $expectedDeprecatedMaxMessageSet)
59+
{
60+
$sut = new Range($options);
61+
$this->assertEquals($expectedDeprecatedMinMessageSet, $sut->deprecatedMinMessageSet);
62+
$this->assertEquals($expectedDeprecatedMaxMessageSet, $sut->deprecatedMaxMessageSet);
63+
}
64+
65+
public function provideDeprecationNotTriggeredIfNotMinMaxOrNotMinMessageNorMaxMessageSet(): array
66+
{
67+
return [
68+
[['min' => 1, 'minMessage' => 'my_min_message', 'maxMessage' => 'my_max_message']],
69+
[['max' => 10, 'minMessage' => 'my_min_message', 'maxMessage' => 'my_max_message']],
70+
[['min' => 1, 'max' => 10, 'notInRangeMessage' => 'my_message']],
71+
];
72+
}
73+
74+
/**
75+
* @doesNotPerformAssertions
76+
* @dataProvider provideDeprecationNotTriggeredIfNotMinMaxOrNotMinMessageNorMaxMessageSet
77+
*/
78+
public function testDeprecationNotTriggeredIfNotMinMaxOrNotMinMessageNorMaxMessageSet(array $options)
79+
{
80+
new Range($options);
81+
}
4382
}

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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy