merged branch bschussek/issue2059 (PR #5941)

This PR was merged into the 2.0 branch.

Commits
-------

dc80385 [Form] Fixed NumberToLocalizedStringTransformer to accept both comma and dot as decimal separator, if possible

Discussion
----------

[Form] Fixed NumberToLocalizedStringTransformer to accept both comma and dot

Bug fix: yes
Feature addition: no
Backwards compatibility break: no
Symfony2 tests pass: yes
Fixes the following tickets: #2059
Todo: -
License of the code: MIT
Documentation PR: -

The behaviour after this is as follows:

* if "grouping" (thousands separators) is disabled (the default)
  * you may use comma and dot as decimal separator in all locales
* if "grouping" is enabled
  * you may use a comma as decimal separator in all locales where the thousands separator is not a comma (e.g. "de", "fr", but not "en")
  * you may use a dot as decimal separator in all locales where the thousands separator is not a dot (e.g. "en", "fr", but not "de")

If the form is displayed again, all numbers are displayed in your locale, regardless of which decimal separator you used for input.

**Example 1 (locale "fr"):**

* you enter: "1234.56"
* after submission:
  * without grouping: "1234,56"
  * with grouping: "1 234,56"

**Example 2 (locale "en"):**

* you enter "1234,56"
* after submission:
  * without grouping: "1234.56"
  * with grouping: error (because "," is the thousands separator; "1234,560" would have been accepted)
This commit is contained in:
Fabien Potencier 2012-11-08 17:45:21 +01:00
commit 9122260df9
2 changed files with 104 additions and 3 deletions

View File

@ -104,6 +104,17 @@ class NumberToLocalizedStringTransformer implements DataTransformerInterface
}
$formatter = $this->getNumberFormatter();
$groupSep = $formatter->getSymbol(\NumberFormatter::GROUPING_SEPARATOR_SYMBOL);
$decSep = $formatter->getSymbol(\NumberFormatter::DECIMAL_SEPARATOR_SYMBOL);
if ('.' !== $decSep && (!$this->grouping || '.' !== $groupSep)) {
$value = str_replace('.', $decSep, $value);
}
if (',' !== $decSep && (!$this->grouping || ',' !== $groupSep)) {
$value = str_replace(',', $decSep, $value);
}
$value = $formatter->parse($value);
if (intl_is_failure($formatter->getErrorCode())) {

View File

@ -88,14 +88,104 @@ class NumberToLocalizedStringTransformerTest extends LocalizedTestCase
{
$transformer = new NumberToLocalizedStringTransformer(null, true);
// completely valid format
$this->assertEquals(1234.5, $transformer->reverseTransform('1.234,5'));
$this->assertEquals(12345.912, $transformer->reverseTransform('12.345,912'));
// omit group separator
$this->assertEquals(1234.5, $transformer->reverseTransform('1234,5'));
$this->assertEquals(12345.912, $transformer->reverseTransform('12345,912'));
}
public function testDecimalSeparatorMayBeDotIfGroupingSeparatorIsNotDot()
{
\Locale::setDefault('fr');
$transformer = new NumberToLocalizedStringTransformer(null, true);
// 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\UnexpectedTypeException
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
*/
public function testDecimalSeparatorMayNotBeDotIfGroupingSeparatorIsDot()
{
$transformer = new NumberToLocalizedStringTransformer(null, true);
$transformer->reverseTransform('1.234.5');
}
/**
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
*/
public function testDecimalSeparatorMayNotBeDotIfGroupingSeparatorIsDot_noGroupSep()
{
$transformer = new NumberToLocalizedStringTransformer(null, true);
$transformer->reverseTransform('1234.5');
}
public function testDecimalSeparatorMayBeDotIfGroupingSeparatorIsDotButNoGroupingUsed()
{
\Locale::setDefault('fr');
$transformer = new NumberToLocalizedStringTransformer();
$this->assertEquals(1234.5, $transformer->reverseTransform('1234,5'));
$this->assertEquals(1234.5, $transformer->reverseTransform('1234.5'));
}
public function testDecimalSeparatorMayBeCommaIfGroupingSeparatorIsNotComma()
{
\Locale::setDefault('ak');
$transformer = new NumberToLocalizedStringTransformer(null, true);
// 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()
{
\Locale::setDefault('en');
$transformer = new NumberToLocalizedStringTransformer(null, true);
$transformer->reverseTransform('1,234,5');
}
/**
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
*/
public function testDecimalSeparatorMayNotBeCommaIfGroupingSeparatorIsComma_noGroupSep()
{
\Locale::setDefault('en');
$transformer = new NumberToLocalizedStringTransformer(null, true);
$transformer->reverseTransform('1234,5');
}
public function testDecimalSeparatorMayBeCommaIfGroupingSeparatorIsCommaButNoGroupingUsed()
{
\Locale::setDefault('en');
$transformer = new NumberToLocalizedStringTransformer();
$this->assertEquals(1234.5, $transformer->reverseTransform('1234,5'));
$this->assertEquals(1234.5, $transformer->reverseTransform('1234.5'));
}
/**
* @expectedException \Symfony\Component\Form\Exception\UnexpectedTypeException
*/
public function testTransformExpectsNumeric()
{
@ -105,7 +195,7 @@ class NumberToLocalizedStringTransformerTest extends LocalizedTestCase
}
/**
* @expectedException Symfony\Component\Form\Exception\UnexpectedTypeException
* @expectedException \Symfony\Component\Form\Exception\UnexpectedTypeException
*/
public function testReverseTransformExpectsString()
{
@ -115,7 +205,7 @@ class NumberToLocalizedStringTransformerTest extends LocalizedTestCase
}
/**
* @expectedException Symfony\Component\Form\Exception\TransformationFailedException
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
*/
public function testReverseTransformExpectsValidNumber()
{