Skip to content

Commit 99d6f37

Browse files
committed
[Form] Fixed PercentToLocalizedStringTransformer to accept both comma and dot as decimal separator, if possible
1 parent 66f54ff commit 99d6f37

File tree

3 files changed

+124
-0
lines changed

3 files changed

+124
-0
lines changed

src/Symfony/Component/Form/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ CHANGELOG
2525
* "choice_value"
2626
* "choice_attr"
2727
* "group_by"
28+
* added PercentToLocalizedStringTransformer to accept both comma and dot as decimal separator, if possible
2829

2930
2.6.2
3031
-----

src/Symfony/Component/Form/Extension/Core/DataTransformer/PercentToLocalizedStringTransformer.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,18 @@ public function reverseTransform($value)
119119
}
120120

121121
$formatter = $this->getNumberFormatter();
122+
$groupSep = $formatter->getSymbol(\NumberFormatter::GROUPING_SEPARATOR_SYMBOL);
123+
$decSep = $formatter->getSymbol(\NumberFormatter::DECIMAL_SEPARATOR_SYMBOL);
124+
$grouping = $formatter->getAttribute(\NumberFormatter::GROUPING_USED);
125+
126+
if ('.' !== $decSep && (!$grouping || '.' !== $groupSep)) {
127+
$value = str_replace('.', $decSep, $value);
128+
}
129+
130+
if (',' !== $decSep && (!$grouping || ',' !== $groupSep)) {
131+
$value = str_replace(',', $decSep, $value);
132+
}
133+
122134
// replace normal spaces so that the formatter can read them
123135
$value = $formatter->parse(str_replace(' ', ' ', $value));
124136

src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/PercentToLocalizedStringTransformerTest.php

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,4 +118,115 @@ public function testReverseTransformExpectsString()
118118

119119
$transformer->reverseTransform(1);
120120
}
121+
122+
public function testDecimalSeparatorMayBeDotIfGroupingSeparatorIsNotDot()
123+
{
124+
\Locale::setDefault('fr');
125+
$transformer = new PercentToLocalizedStringTransformer(1, 'integer');
126+
127+
// completely valid format
128+
$this->assertEquals(1234.5, $transformer->reverseTransform('1 234,5'));
129+
// accept dots
130+
$this->assertEquals(1234.5, $transformer->reverseTransform('1 234.5'));
131+
// omit group separator
132+
$this->assertEquals(1234.5, $transformer->reverseTransform('1234,5'));
133+
$this->assertEquals(1234.5, $transformer->reverseTransform('1234.5'));
134+
}
135+
136+
/**
137+
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
138+
*/
139+
public function testDecimalSeparatorMayNotBeDotIfGroupingSeparatorIsDot()
140+
{
141+
// Since we test against "de_DE", we need the full implementation
142+
IntlTestHelper::requireFullIntl($this, false);
143+
144+
\Locale::setDefault('de_DE');
145+
146+
$transformer = new PercentToLocalizedStringTransformer(1, 'integer');
147+
148+
$transformer->reverseTransform('1.234.5');
149+
}
150+
151+
/**
152+
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
153+
*/
154+
public function testDecimalSeparatorMayNotBeDotIfGroupingSeparatorIsDotWithNoGroupSep()
155+
{
156+
// Since we test against "de_DE", we need the full implementation
157+
IntlTestHelper::requireFullIntl($this, false);
158+
159+
\Locale::setDefault('de_DE');
160+
161+
$transformer = new PercentToLocalizedStringTransformer(1, 'integer');
162+
163+
$transformer->reverseTransform('1234.5');
164+
}
165+
166+
public function testDecimalSeparatorMayBeDotIfGroupingSeparatorIsDotButNoGroupingUsed()
167+
{
168+
// Since we test against other locales, we need the full implementation
169+
IntlTestHelper::requireFullIntl($this, false);
170+
171+
\Locale::setDefault('fr');
172+
$transformer = new PercentToLocalizedStringTransformer(1, 'integer');
173+
174+
$this->assertEquals(1234.5, $transformer->reverseTransform('1234,5'));
175+
$this->assertEquals(1234.5, $transformer->reverseTransform('1234.5'));
176+
}
177+
178+
public function testDecimalSeparatorMayBeCommaIfGroupingSeparatorIsNotComma()
179+
{
180+
// Since we test against other locales, we need the full implementation
181+
IntlTestHelper::requireFullIntl($this, false);
182+
183+
\Locale::setDefault('bg');
184+
$transformer = new PercentToLocalizedStringTransformer(1, 'integer');
185+
186+
// completely valid format
187+
$this->assertEquals(1234.5, $transformer->reverseTransform('1 234.5'));
188+
// accept commas
189+
$this->assertEquals(1234.5, $transformer->reverseTransform('1 234,5'));
190+
// omit group separator
191+
$this->assertEquals(1234.5, $transformer->reverseTransform('1234.5'));
192+
$this->assertEquals(1234.5, $transformer->reverseTransform('1234,5'));
193+
}
194+
195+
/**
196+
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
197+
*/
198+
public function testDecimalSeparatorMayNotBeCommaIfGroupingSeparatorIsComma()
199+
{
200+
$transformer = new PercentToLocalizedStringTransformer(1, 'integer');
201+
202+
$transformer->reverseTransform('1,234,5');
203+
}
204+
205+
/**
206+
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
207+
*/
208+
public function testDecimalSeparatorMayNotBeCommaIfGroupingSeparatorIsCommaWithNoGroupSep()
209+
{
210+
$transformer = new PercentToLocalizedStringTransformer(1, 'integer');
211+
212+
$transformer->reverseTransform('1234,5');
213+
}
214+
215+
public function testDecimalSeparatorMayBeCommaIfGroupingSeparatorIsCommaButNoGroupingUsed()
216+
{
217+
$formatter = new \NumberFormatter(\Locale::getDefault(), \NumberFormatter::DECIMAL);
218+
$formatter->setAttribute(\NumberFormatter::FRACTION_DIGITS, 1);
219+
$formatter->setAttribute(\NumberFormatter::GROUPING_USED, false);
220+
221+
$transformer = $this->getMockBuilder('Symfony\Component\Form\Extension\Core\DataTransformer\PercentToLocalizedStringTransformer')
222+
->setMethods(['getNumberFormatter'])
223+
->setConstructorArgs([1, 'integer'])
224+
->getMock();
225+
$transformer->expects($this->any())
226+
->method('getNumberFormatter')
227+
->willReturn($formatter);
228+
229+
$this->assertEquals(1234.5, $transformer->reverseTransform('1234,5'));
230+
$this->assertEquals(1234.5, $transformer->reverseTransform('1234.5'));
231+
}
121232
}

0 commit comments

Comments
 (0)