[Form] 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.
This commit is contained in:
Jorrit Schippers 2020-03-20 13:10:52 +01:00 committed by Nicolas Grekas
parent 0e2d5e960a
commit 61025d1d1b
2 changed files with 53 additions and 2 deletions

View File

@ -117,11 +117,16 @@ class DateTimeToLocalizedStringTransformer extends BaseDateTimeTransformer
// 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 $e) {
throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e);
}
if (0 != intl_get_error_code()) {
throw new TransformationFailedException(intl_get_error_message());
throw new TransformationFailedException(intl_get_error_message(), intl_get_error_code());
} elseif ($timestamp > 253402214400) {
// This timestamp represents UTC midnight of 9999-12-31 to prevent 5+ digit years
throw new TransformationFailedException('Years beyond 9999 are not supported.');

View File

@ -27,6 +27,12 @@ class DateTimeToLocalizedStringTransformerTest extends TestCase
{
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');
@ -334,4 +340,44 @@ class DateTimeToLocalizedStringTransformerTest extends TestCase
$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');
}
}