bug #36149 [Form] Support customized intl php.ini settings (jorrit)

This PR was merged into the 3.4 branch.

Discussion
----------

[Form] Support customized intl php.ini settings

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | no
| License       | MIT
| Doc PR        | no

`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.

Commits
-------

61025d1d1b [Form] Support customized intl php.ini settings
This commit is contained in:
Nicolas Grekas 2020-03-23 13:05:41 +01:00
commit 5b5b61f425
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');
}
}