diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/PercentToLocalizedStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/PercentToLocalizedStringTransformer.php index 7fc191a054..6d209c9d60 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/PercentToLocalizedStringTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/PercentToLocalizedStringTransformer.php @@ -119,6 +119,18 @@ class PercentToLocalizedStringTransformer implements DataTransformerInterface } $formatter = $this->getNumberFormatter(); + $groupSep = $formatter->getSymbol(\NumberFormatter::GROUPING_SEPARATOR_SYMBOL); + $decSep = $formatter->getSymbol(\NumberFormatter::DECIMAL_SEPARATOR_SYMBOL); + $grouping = $formatter->getAttribute(\NumberFormatter::GROUPING_USED); + + if ('.' !== $decSep && (!$grouping || '.' !== $groupSep)) { + $value = str_replace('.', $decSep, $value); + } + + if (',' !== $decSep && (!$grouping || ',' !== $groupSep)) { + $value = str_replace(',', $decSep, $value); + } + // replace normal spaces so that the formatter can read them $value = $formatter->parse(str_replace(' ', "\xc2\xa0", $value)); diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/PercentToLocalizedStringTransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/PercentToLocalizedStringTransformerTest.php index abcc72e231..24cef424d1 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/PercentToLocalizedStringTransformerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/PercentToLocalizedStringTransformerTest.php @@ -119,4 +119,121 @@ class PercentToLocalizedStringTransformerTest extends TestCase $transformer->reverseTransform(1); } + + public function testDecimalSeparatorMayBeDotIfGroupingSeparatorIsNotDot() + { + IntlTestHelper::requireFullIntl($this, '4.8.1.1'); + + \Locale::setDefault('fr'); + $transformer = new PercentToLocalizedStringTransformer(1, 'integer'); + + // completely valid format + $this->assertEquals(1234.5, $transformer->reverseTransform('1 234,5')); + // accept dots + $this->assertEquals(1234.5, $transformer->reverseTransform('1 234.5')); + // omit group separator + $this->assertEquals(1234.5, $transformer->reverseTransform('1234,5')); + $this->assertEquals(1234.5, $transformer->reverseTransform('1234.5')); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testDecimalSeparatorMayNotBeDotIfGroupingSeparatorIsDot() + { + // Since we test against "de_AT", we need the full implementation + IntlTestHelper::requireFullIntl($this, '4.8.1.1'); + + \Locale::setDefault('de_AT'); + + $transformer = new PercentToLocalizedStringTransformer(1, 'integer'); + + $transformer->reverseTransform('1.234.5'); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testDecimalSeparatorMayNotBeDotIfGroupingSeparatorIsDotWithNoGroupSep() + { + // Since we test against "de_DE", we need the full implementation + IntlTestHelper::requireFullIntl($this, '4.8.1.1'); + + \Locale::setDefault('de_DE'); + + $transformer = new PercentToLocalizedStringTransformer(1, 'integer'); + + $transformer->reverseTransform('1234.5'); + } + + public function testDecimalSeparatorMayBeDotIfGroupingSeparatorIsDotButNoGroupingUsed() + { + // Since we test against other locales, we need the full implementation + IntlTestHelper::requireFullIntl($this, false); + + \Locale::setDefault('fr'); + $transformer = new PercentToLocalizedStringTransformer(1, 'integer'); + + $this->assertEquals(1234.5, $transformer->reverseTransform('1234,5')); + $this->assertEquals(1234.5, $transformer->reverseTransform('1234.5')); + } + + public function testDecimalSeparatorMayBeCommaIfGroupingSeparatorIsNotComma() + { + // Since we test against other locales, we need the full implementation + IntlTestHelper::requireFullIntl($this, '4.8.1.1'); + + \Locale::setDefault('bg'); + $transformer = new PercentToLocalizedStringTransformer(1, 'integer'); + + // completely valid format + $this->assertEquals(1234.5, $transformer->reverseTransform('1 234.5')); + // accept commas + $this->assertEquals(1234.5, $transformer->reverseTransform('1 234,5')); + // omit group separator + $this->assertEquals(1234.5, $transformer->reverseTransform('1234.5')); + $this->assertEquals(1234.5, $transformer->reverseTransform('1234,5')); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testDecimalSeparatorMayNotBeCommaIfGroupingSeparatorIsComma() + { + IntlTestHelper::requireFullIntl($this, '4.8.1.1'); + + $transformer = new PercentToLocalizedStringTransformer(1, 'integer'); + + $transformer->reverseTransform('1,234,5'); + } + + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testDecimalSeparatorMayNotBeCommaIfGroupingSeparatorIsCommaWithNoGroupSep() + { + IntlTestHelper::requireFullIntl($this, '4.8.1.1'); + + $transformer = new PercentToLocalizedStringTransformer(1, 'integer'); + + $transformer->reverseTransform('1234,5'); + } + + public function testDecimalSeparatorMayBeCommaIfGroupingSeparatorIsCommaButNoGroupingUsed() + { + $formatter = new \NumberFormatter(\Locale::getDefault(), \NumberFormatter::DECIMAL); + $formatter->setAttribute(\NumberFormatter::FRACTION_DIGITS, 1); + $formatter->setAttribute(\NumberFormatter::GROUPING_USED, false); + + $transformer = $this->getMockBuilder('Symfony\Component\Form\Extension\Core\DataTransformer\PercentToLocalizedStringTransformer') + ->setMethods(array('getNumberFormatter')) + ->setConstructorArgs(array(1, 'integer')) + ->getMock(); + $transformer->expects($this->any()) + ->method('getNumberFormatter') + ->willReturn($formatter); + + $this->assertEquals(1234.5, $transformer->reverseTransform('1234,5')); + $this->assertEquals(1234.5, $transformer->reverseTransform('1234.5')); + } }