Skip to content

Commit 772da24

Browse files
Merge branch '3.4' into 4.3
* 3.4: CS [Serializer] Skip uninitialized (PHP 7.4) properties in PropertyNormalizer and ObjectNormalizer stop using deprecated Doctrine persistence classes Fix regex lookahead syntax in ApplicationTest [SecurityBundle][FirewallMap] Remove unused property [DI] Improve performance of processDefinition Fix invalid Windows path normalization [Validator][ConstraintValidator] Safe fail on invalid timezones [DoctrineBridge] Fixed submitting invalid ids when using queries with limit fix comparisons with null values at property paths
2 parents d172acd + d683912 commit 772da24

15 files changed

+102
-15
lines changed

ConstraintValidator.php

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -87,16 +87,12 @@ protected function formatValue($value, $format = 0)
8787
{
8888
if (($format & self::PRETTY_DATE) && $value instanceof \DateTimeInterface) {
8989
if (class_exists('IntlDateFormatter')) {
90-
$locale = \Locale::getDefault();
91-
$formatter = new \IntlDateFormatter($locale, \IntlDateFormatter::MEDIUM, \IntlDateFormatter::SHORT, $value->getTimezone());
90+
$formatter = new \IntlDateFormatter(\Locale::getDefault(), \IntlDateFormatter::MEDIUM, \IntlDateFormatter::SHORT, 'UTC');
9291

93-
// neither the native nor the stub IntlDateFormatter support
94-
// DateTimeImmutable as of yet
95-
if (!$value instanceof \DateTime) {
96-
$value = new \DateTime($value->format('Y-m-d H:i:s.u e'));
97-
}
98-
99-
return $formatter->format($value);
92+
return $formatter->format(new \DateTime(
93+
$value->format('Y-m-d H:i:s.u'),
94+
new \DateTimeZone('UTC')
95+
));
10096
}
10197

10298
return $value->format('Y-m-d H:i:s');

Constraints/GreaterThanOrEqualValidator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class GreaterThanOrEqualValidator extends AbstractComparisonValidator
2424
*/
2525
protected function compareValues($value1, $value2)
2626
{
27-
return $value1 >= $value2;
27+
return null === $value2 || $value1 >= $value2;
2828
}
2929

3030
/**

Constraints/GreaterThanValidator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class GreaterThanValidator extends AbstractComparisonValidator
2424
*/
2525
protected function compareValues($value1, $value2)
2626
{
27-
return $value1 > $value2;
27+
return null === $value2 || $value1 > $value2;
2828
}
2929

3030
/**

Constraints/LessThanOrEqualValidator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class LessThanOrEqualValidator extends AbstractComparisonValidator
2424
*/
2525
protected function compareValues($value1, $value2)
2626
{
27-
return $value1 <= $value2;
27+
return null === $value2 || $value1 <= $value2;
2828
}
2929

3030
/**

Constraints/LessThanValidator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class LessThanValidator extends AbstractComparisonValidator
2424
*/
2525
protected function compareValues($value1, $value2)
2626
{
27-
return $value1 < $value2;
27+
return null === $value2 || $value1 < $value2;
2828
}
2929

3030
/**

Tests/ConstraintValidatorTest.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ public function testFormatValue($expected, $value, $format = 0)
2727

2828
public function formatValueProvider()
2929
{
30+
$defaultTimezone = date_default_timezone_get();
31+
date_default_timezone_set('Europe/Moscow'); // GMT+3
32+
3033
$data = [
3134
['true', true],
3235
['false', false],
@@ -36,10 +39,15 @@ public function formatValueProvider()
3639
['array', []],
3740
['object', $toString = new TestToStringObject()],
3841
['ccc', $toString, ConstraintValidator::OBJECT_TO_STRING],
39-
['object', $dateTime = (new \DateTimeImmutable('@0'))->setTimezone(new \DateTimeZone('UTC'))],
40-
[class_exists(\IntlDateFormatter::class) ? 'Jan 1, 1970, 12:00 AM' : '1970-01-01 00:00:00', $dateTime, ConstraintValidator::PRETTY_DATE],
42+
['object', $dateTime = new \DateTimeImmutable('1971-02-02T08:00:00UTC')],
43+
[class_exists(\IntlDateFormatter::class) ? 'Oct 4, 2019, 11:02 AM' : '2019-10-04 11:02:03', new \DateTimeImmutable('2019-10-04T11:02:03+09:00'), ConstraintValidator::PRETTY_DATE],
44+
[class_exists(\IntlDateFormatter::class) ? 'Feb 2, 1971, 8:00 AM' : '1971-02-02 08:00:00', $dateTime, ConstraintValidator::PRETTY_DATE],
45+
[class_exists(\IntlDateFormatter::class) ? 'Jan 1, 1970, 6:00 AM' : '1970-01-01 06:00:00', new \DateTimeImmutable('1970-01-01T06:00:00Z'), ConstraintValidator::PRETTY_DATE],
46+
[class_exists(\IntlDateFormatter::class) ? 'Jan 1, 1970, 3:00 PM' : '1970-01-01 15:00:00', (new \DateTimeImmutable('1970-01-01T23:00:00'))->setTimezone(new \DateTimeZone('America/New_York')), ConstraintValidator::PRETTY_DATE],
4147
];
4248

49+
date_default_timezone_set($defaultTimezone);
50+
4351
return $data;
4452
}
4553
}

Tests/Constraints/AbstractComparisonValidatorTestCase.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,31 @@ public function throwsOnInvalidStringDatesProvider()
234234
];
235235
}
236236

237+
/**
238+
* @dataProvider provideComparisonsToNullValueAtPropertyPath
239+
*/
240+
public function testCompareWithNullValueAtPropertyAt($dirtyValue, $dirtyValueAsString, $isValid)
241+
{
242+
$constraint = $this->createConstraint(['propertyPath' => 'value']);
243+
$constraint->message = 'Constraint Message';
244+
245+
$object = new ComparisonTest_Class(null);
246+
$this->setObject($object);
247+
248+
$this->validator->validate($dirtyValue, $constraint);
249+
250+
if ($isValid) {
251+
$this->assertNoViolation();
252+
} else {
253+
$this->buildViolation('Constraint Message')
254+
->setParameter('{{ value }}', $dirtyValueAsString)
255+
->setParameter('{{ compared_value }}', 'null')
256+
->setParameter('{{ compared_value_type }}', 'NULL')
257+
->setCode($this->getErrorCode())
258+
->assertRaised();
259+
}
260+
}
261+
237262
/**
238263
* @return array
239264
*/
@@ -255,6 +280,8 @@ public function provideAllInvalidComparisons()
255280
*/
256281
abstract public function provideInvalidComparisons();
257282

283+
abstract public function provideComparisonsToNullValueAtPropertyPath();
284+
258285
/**
259286
* @param array|null $options Options for the constraint
260287
*

Tests/Constraints/EqualToValidatorTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,11 @@ public function provideInvalidComparisons()
7575
[new ComparisonTest_Class(4), '4', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'],
7676
];
7777
}
78+
79+
public function provideComparisonsToNullValueAtPropertyPath()
80+
{
81+
return [
82+
[5, '5', false],
83+
];
84+
}
7885
}

Tests/Constraints/GreaterThanOrEqualValidatorTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,4 +78,11 @@ public function provideInvalidComparisons()
7878
['b', '"b"', 'c', '"c"', 'string'],
7979
];
8080
}
81+
82+
public function provideComparisonsToNullValueAtPropertyPath()
83+
{
84+
return [
85+
[5, '5', true],
86+
];
87+
}
8188
}

Tests/Constraints/GreaterThanValidatorTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,4 +80,11 @@ public function provideInvalidComparisons()
8080
['22', '"22"', '22', '"22"', 'string'],
8181
];
8282
}
83+
84+
public function provideComparisonsToNullValueAtPropertyPath()
85+
{
86+
return [
87+
[5, '5', true],
88+
];
89+
}
8390
}

Tests/Constraints/IdenticalToValidatorTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,11 @@ public function provideInvalidComparisons()
9393
[new ComparisonTest_Class(4), '4', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'],
9494
];
9595
}
96+
97+
public function provideComparisonsToNullValueAtPropertyPath()
98+
{
99+
return [
100+
[5, '5', false],
101+
];
102+
}
96103
}

Tests/Constraints/LessThanOrEqualValidatorTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,11 @@ public function provideInvalidComparisons()
8181
['c', '"c"', 'b', '"b"', 'string'],
8282
];
8383
}
84+
85+
public function provideComparisonsToNullValueAtPropertyPath()
86+
{
87+
return [
88+
[5, '5', true],
89+
];
90+
}
8491
}

Tests/Constraints/LessThanValidatorTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,11 @@ public function provideInvalidComparisons()
7979
['333', '"333"', '22', '"22"', 'string'],
8080
];
8181
}
82+
83+
public function provideComparisonsToNullValueAtPropertyPath()
84+
{
85+
return [
86+
[5, '5', true],
87+
];
88+
}
8289
}

Tests/Constraints/NotEqualToValidatorTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,11 @@ public function provideInvalidComparisons()
7575
[new ComparisonTest_Class(5), '5', new ComparisonTest_Class(5), '5', __NAMESPACE__.'\ComparisonTest_Class'],
7676
];
7777
}
78+
79+
public function provideComparisonsToNullValueAtPropertyPath()
80+
{
81+
return [
82+
[5, '5', true],
83+
];
84+
}
7885
}

Tests/Constraints/NotIdenticalToValidatorTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,11 @@ public function provideInvalidComparisons()
9393

9494
return $comparisons;
9595
}
96+
97+
public function provideComparisonsToNullValueAtPropertyPath()
98+
{
99+
return [
100+
[5, '5', true],
101+
];
102+
}
96103
}

0 commit comments

Comments
 (0)