From 2c5685d20370b4a40c9a568ea7aae17aa81662ac Mon Sep 17 00:00:00 2001 From: Jorrit Schippers Date: Fri, 20 Mar 2020 13:10:52 +0100 Subject: [PATCH] Support customized intl php.ini settings `IntlDateParser->parse()` behaves differently when `intl.error_level` and/or `intl.use_exceptions` are not 0. This change makes sure `\IntlException` is caught when `intl.use_exceptions` is 1 and warnings thrown when `intl.error_level` is not 0 are ignored. --- .../DateTimeToLocalizedStringTransformer.php | 7 ++- ...teTimeToLocalizedStringTransformerTest.php | 46 +++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformer.php index 2dfbbf17d60d1..c231af62e157d 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformer.php @@ -117,8 +117,13 @@ public function reverseTransform($value) // date-only patterns require parsing to be done in UTC, as midnight might not exist in the local timezone due // to DST changes $dateOnly = $this->isPatternDateOnly(); + $dateFormatter = $this->getIntlDateFormatter($dateOnly); - $timestamp = $this->getIntlDateFormatter($dateOnly)->parse($value); + try { + $timestamp = @$dateFormatter->parse($value); + } catch (\IntlException $ex) { + throw new TransformationFailedException($ex->getMessage(), $ex->getCode(), $ex); + } if (0 != intl_get_error_code()) { throw new TransformationFailedException(intl_get_error_message()); diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php index 808571cbef41e..c9821bfe7475b 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php @@ -27,6 +27,12 @@ protected function setUp(): void { parent::setUp(); + // Normalize intl. configuration settings. + if (\extension_loaded('intl')) { + $this->iniSet('intl.use_exceptions', 0); + $this->iniSet('intl.error_level', 0); + } + // Since we test against "de_AT", we need the full implementation IntlTestHelper::requireFullIntl($this, '57.1'); @@ -322,4 +328,44 @@ public function testReverseTransformFiveDigitYearsWithTimestamp() $transformer = new DateTimeToLocalizedStringTransformer('UTC', 'UTC', null, null, \IntlDateFormatter::GREGORIAN, 'yyyy-MM-dd HH:mm:ss'); $transformer->reverseTransform('20107-03-21 12:34:56'); } + + public function testReverseTransformWrapsIntlErrorsWithErrorLevel() + { + if (!\extension_loaded('intl')) { + $this->markTestSkipped('intl extension is not loaded'); + } + + $this->iniSet('intl.error_level', E_WARNING); + + $this->expectException('Symfony\Component\Form\Exception\TransformationFailedException'); + $transformer = new DateTimeToLocalizedStringTransformer(); + $transformer->reverseTransform('12345'); + } + + public function testReverseTransformWrapsIntlErrorsWithExceptions() + { + if (!\extension_loaded('intl')) { + $this->markTestSkipped('intl extension is not loaded'); + } + + $this->iniSet('intl.use_exceptions', 1); + + $this->expectException('Symfony\Component\Form\Exception\TransformationFailedException'); + $transformer = new DateTimeToLocalizedStringTransformer(); + $transformer->reverseTransform('12345'); + } + + public function testReverseTransformWrapsIntlErrorsWithExceptionsAndErrorLevel() + { + if (!\extension_loaded('intl')) { + $this->markTestSkipped('intl extension is not loaded'); + } + + $this->iniSet('intl.use_exceptions', 1); + $this->iniSet('intl.error_level', E_WARNING); + + $this->expectException('Symfony\Component\Form\Exception\TransformationFailedException'); + $transformer = new DateTimeToLocalizedStringTransformer(); + $transformer->reverseTransform('12345'); + } }