Browse Source

merged branch mrtorrent/integer_transformer_cast_fix (PR #2520)

Commits
-------

c9d05d7 Let NumberFormatter handle integer type casting

Discussion
----------

Let NumberFormatter handle integer type casting

The integer to localised string transformer is currently casting everything it gets to an integer, even if it is not a number. This responsibility should be passed off to NumberFormatter.

Partially addresses #2389 by not mistakenly typecasting a boolean false into an integer 0

---------------------------------------------------------------------------

by mrtorrent at 2011/10/30 15:04:28 -0700

Apologies, forgot the template:

Bug fix: yes
Feature addition: no
Backwards compatibility break: no
Symfony2 tests pass: yes
Fixes the following tickets: #2389 (partial)
Fabien Potencier 13 năm trước cách đây
mục cha
commit
2e90a813a4

+ 21 - 2
src/Symfony/Component/Form/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformer.php

@@ -11,6 +11,9 @@
 
 namespace Symfony\Component\Form\Extension\Core\DataTransformer;
 
+use Symfony\Component\Form\Exception\TransformationFailedException;
+use Symfony\Component\Form\Exception\UnexpectedTypeException;
+
 /**
  * Transforms between an integer and a localized number with grouping
  * (each thousand) and comma separators.
@@ -24,8 +27,24 @@ class IntegerToLocalizedStringTransformer extends NumberToLocalizedStringTransfo
      */
     public function reverseTransform($value)
     {
-        $value = parent::reverseTransform($value);
+        if (!is_string($value)) {
+            throw new UnexpectedTypeException($value, 'string');
+        }
+
+        if ('' === $value) {
+            return null;
+        }
+
+        $formatter = $this->getNumberFormatter();
+        $value = $formatter->parse(
+            $value,
+            PHP_INT_SIZE == 8 ? $formatter::TYPE_INT64 : $formatter::TYPE_INT32
+        );
+
+        if (intl_is_failure($formatter->getErrorCode())) {
+            throw new TransformationFailedException($formatter->getErrorMessage());
+        }
 
-        return null === $value ? null : (int) $value;
+        return $value;
     }
 }

+ 73 - 0
tests/Symfony/Tests/Component/Form/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformerTest.php

@@ -0,0 +1,73 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Tests\Component\Form\Extension\Core\DataTransformer;
+
+require_once __DIR__ . '/LocalizedTestCase.php';
+
+use Symfony\Component\Form\Extension\Core\DataTransformer\IntegerToLocalizedStringTransformer;
+
+class IntegerToLocalizedStringTransformerTest extends LocalizedTestCase
+{
+    protected function setUp()
+    {
+        parent::setUp();
+
+        \Locale::setDefault('de_AT');
+    }
+
+    public function testReverseTransform()
+    {
+        $transformer = new IntegerToLocalizedStringTransformer();
+
+        $this->assertEquals(1, $transformer->reverseTransform('1'));
+        $this->assertEquals(1, $transformer->reverseTransform('1,5'));
+        $this->assertEquals(1234, $transformer->reverseTransform('1234,5'));
+        $this->assertEquals(12345, $transformer->reverseTransform('12345,912'));
+    }
+
+    public function testReverseTransform_empty()
+    {
+        $transformer = new IntegerToLocalizedStringTransformer();
+
+        $this->assertSame(null, $transformer->reverseTransform(''));
+    }
+
+    public function testReverseTransformWithGrouping()
+    {
+        $transformer = new IntegerToLocalizedStringTransformer(null, true);
+
+        $this->assertEquals(1234, $transformer->reverseTransform('1.234,5'));
+        $this->assertEquals(12345, $transformer->reverseTransform('12.345,912'));
+        $this->assertEquals(1234, $transformer->reverseTransform('1234,5'));
+        $this->assertEquals(12345, $transformer->reverseTransform('12345,912'));
+    }
+
+    /**
+     * @expectedException Symfony\Component\Form\Exception\UnexpectedTypeException
+     */
+    public function testReverseTransformExpectsString()
+    {
+        $transformer = new IntegerToLocalizedStringTransformer();
+
+        $transformer->reverseTransform(1);
+    }
+
+    /**
+     * @expectedException Symfony\Component\Form\Exception\TransformationFailedException
+     */
+    public function testReverseTransformExpectsValidNumber()
+    {
+        $transformer = new IntegerToLocalizedStringTransformer();
+
+        $transformer->reverseTransform('foo');
+    }
+}