From 7e97fbb6e434ace58ace5f354a2e2261d0824aa4 Mon Sep 17 00:00:00 2001 From: Jules Pietri Date: Wed, 30 Mar 2016 08:05:41 +0200 Subject: [PATCH] [Form] let `TextType` implements `DataTransformerInterface` closes #5906. The submitted data should always be transformed back to the model as a string as NULL in this case could stand for "unset this value" whereas a string property of a class could rely on the string type. Furthermore, this prevents potential issues with PHP 7 which allows type hinting of strings in functions. --- UPGRADE-3.1.md | 2 + src/Symfony/Component/Form/CHANGELOG.md | 1 + .../Form/Extension/Core/Type/TextType.php | 34 ++++++++++++++++- .../Extension/Core/Type/TextTypeTest.php | 37 +++++++++++++++++++ 4 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 src/Symfony/Component/Form/Tests/Extension/Core/Type/TextTypeTest.php diff --git a/UPGRADE-3.1.md b/UPGRADE-3.1.md index 2bf81288c639..64afbcbe4aab 100644 --- a/UPGRADE-3.1.md +++ b/UPGRADE-3.1.md @@ -18,6 +18,8 @@ Form * Support for data objects that implements both `Traversable` and `ArrayAccess` in `ResizeFormListener::preSubmit` method has been deprecated and will be removed in Symfony 4.0. + * `TextType` now implements `DataTransformerInterface` and will always return + an empty string when `empty_data` option is explicitly assigned to it. FrameworkBundle --------------- diff --git a/src/Symfony/Component/Form/CHANGELOG.md b/src/Symfony/Component/Form/CHANGELOG.md index db7cf28fdbaa..08c13c580308 100644 --- a/src/Symfony/Component/Form/CHANGELOG.md +++ b/src/Symfony/Component/Form/CHANGELOG.md @@ -7,6 +7,7 @@ CHANGELOG * deprecated the "choices_as_values" option of ChoiceType * deprecated support for data objects that implements both `Traversable` and `ArrayAccess` in `ResizeFormListener::preSubmit` method + * implemented `DataTransformerInterface` in `TextType` 3.0.0 ----- diff --git a/src/Symfony/Component/Form/Extension/Core/Type/TextType.php b/src/Symfony/Component/Form/Extension/Core/Type/TextType.php index 81504f907937..4776ebc4287b 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/TextType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/TextType.php @@ -12,10 +12,24 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\DataTransformerInterface; +use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; -class TextType extends AbstractType +class TextType extends AbstractType implements DataTransformerInterface { + public function buildForm(FormBuilderInterface $builder, array $options) + { + // When empty_data is explicitly set to an empty string, + // a string should always be returned when NULL is submitted + // This gives more control and thus helps preventing some issues + // with PHP 7 which allows type hinting strings in functions + // See https://github.com/symfony/symfony/issues/5906#issuecomment-203189375 + if ('' === $options['empty_data']) { + $builder->addViewTransformer($this); + } + } + /** * {@inheritdoc} */ @@ -33,4 +47,22 @@ public function getBlockPrefix() { return 'text'; } + + /** + * {@inheritdoc} + */ + public function transform($data) + { + // Model data should not be transformed + return $data; + } + + /** + * {@inheritdoc} + *. + */ + public function reverseTransform($data) + { + return null === $data ? '' : $data; + } } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/TextTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/TextTypeTest.php new file mode 100644 index 000000000000..ac63c4cf452b --- /dev/null +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/TextTypeTest.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Core\Type; + +use Symfony\Component\Form\Test\TypeTestCase as TestCase; + +class TextTypeTest extends TestCase +{ + public function testSubmitNullReturnsNull() + { + $form = $this->factory->create('Symfony\Component\Form\Extension\Core\Type\TextType', 'name'); + + $form->submit(null); + + $this->assertNull($form->getData()); + } + + public function testSubmitNullReturnsEmptyStringWithEmptyDataAsString() + { + $form = $this->factory->create('Symfony\Component\Form\Extension\Core\Type\TextType', 'name', array( + 'empty_data' => '', + )); + + $form->submit(null); + + $this->assertSame('', $form->getData()); + } +}