Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Form] Let TextType implement DataTransformerInterface #18357

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 28, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions UPGRADE-3.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
---------------
Expand Down
1 change: 1 addition & 0 deletions src/Symfony/Component/Form/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
-----
Expand Down
34 changes: 33 additions & 1 deletion src/Symfony/Component/Form/Extension/Core/Type/TextType.php
Original file line number Diff line number Diff line change
Expand Up @@ -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}
*/
Expand All @@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* 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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there any config with the new system that allows one to distinguish between submit(null) and submit('') in the model data?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@backbone87 I don't really understand what is "new" for you, as I am feeling quite new myself in symfony :)

  1. But as far as I understand when you call Form::submit(null) here what happens:

  2. So at this point view data cannot be an empty string, it remains null.

    Then:

  3. Hence here we do have a view data as empty string but...:

Conclusion

This PR could add a view data transformer to prevent that call but I guess in order to prevent messing with other transformers and as this has to stay the default, @webmozart asked to add it as a model data transformer since it is the first registered => also the last called => minimum of potential BC breaks.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with "new system" i was refering to the state of the form component after your PR.

i was specially talking about how to distinguish between a text field that is submitted with null vs submitted with empty string.

consider a simple form with text field:

$form = $factory->create();
$form->add('name', TextType::class, [ 'required' => false ]);

and now the different submits:

// 1.
$form->submit(null);
assert $form->get('name')->getData() === null;

// 2.
$form->submit([]);
assert $form->get('name')->getData() === null;

// 3.
$form->submit([ 'name' => null ]);
assert $form->get('name')->getData() === null;

// 4.
$form->submit([ 'name' => '' ]);
assert $form->get('name')->getData() === '';

// 5.
$form->submit([ 'name' => 'Joe' ]);
assert $form->get('name')->getData() === 'Joe';
  • name is truely optional here, but is also allowed to be the empty string (that is also different from "name not given")
    1. can be viewed as a submission error, though one could normalize it to []

edit: this topic isnt directly related to your PR, but a general: "how does the TextType field work currently and is expected to work ideally". i mean there must be a reasoning to kill the empty string from the model value space of the text type.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@backbone87 Yes, the reasoning is to not break data transformers by passing null instead of an empty string.

Concerning TextType this PR does not introduce a "new" way, it just considers the setting of empty_data which was ignored before.

This is a bug fix, I'm not sure it should go in master though.

ping @webmozart


$this->assertSame('', $form->getData());
}
}