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:
commit
9122260df9
@ -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())) {
|
||||
|
@ -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()
|
||||
{
|
||||
|
Reference in New Issue
Block a user