8000 [Form] Deprecate a callable empty_data in ChoiceType by peter-gribanov · Pull Request #25924 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[Form] Deprecate a callable empty_data in ChoiceType #25924

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

19 changes: 19 additions & 0 deletions UPGRADE-4.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,25 @@ Validator
* Calling `EmailValidator::__construct()` method with a boolean parameter is deprecated and will be removed in 5.0, use `EmailValidator("strict")` instead.
* Deprecated the `checkDNS` and `dnsMessage` options of the `Url` constraint. They will be removed in 5.0.

Form
----

* Using callable strings as `empty_data` in `ChoiceType` has been deprecated in Symfony 4.1 use a `\Closure` instead.
Copy link
Member

Choose a reason for hiding this comment

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

Better: … is deprecated and will be removed in Symfony 5.0, use a…


Before:

```php
'empty_data' => 'SomeValueObject::getDefaultValue',
```

After:

```php
'empty_data' => function (FormInterface $form, $data) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Or just Closure::fromCallable('some_function') 😉

return SomeValueObject::getDefaultValue();
},
```

Workflow
--------

Expand Down
19 changes: 19 additions & 0 deletions UPGRADE-5.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,25 @@ Validator
* Calling `EmailValidator::__construct()` method with a boolean parameter has been removed, use `EmailValidator("strict")` instead.
* Removed the `checkDNS` and `dnsMessage` options from the `Url` constraint.

Form
----

* Using callable strings as `empty_data` in `ChoiceType` has been deprecated in Symfony 4.1 use a `\Closure` instead.
Copy link
Member

Choose a reason for hiding this comment

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

Should be:

* Support for callable strings as `empty_data` in `ChoiceType` has been removed. Use a `\Closure` instead.


Before:

```php
'empty_data' => 'SomeValueObject::getDefaultValue',
```

After:

```php
'empty_data' => function (FormInterface $form, $data) {
return SomeValueObject::getDefaultValue();
},
Copy link
Member
@derrabus derrabus Jan 25, 2018

Choose a reason for hiding this comment

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

I think, you should rather use a global function call as an example. A static method call can still be written as ['SomeValueObject', 'getDefaultValue'] and I personally would prefer that notation over an anonymous function.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

And in vain you prefer such a call to static functions.
This leads to the fact that the connection to the real function is lost and this is guaranteed to lead to problems during refactoring.

Copy link
Member

Choose a reason for hiding this comment

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

Well, it was not my intention to discuss my personal preferences. Shouldn't have mentioned it. Still, the static call adds unnecessary distraction to the example, imho.

```

Workflow
--------

Expand Down
5 changes: 5 additions & 0 deletions src/Symfony/Component/Form/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
CHANGELOG
=========

4.1.0
-----

* Using callable strings as `empty_data` in `ChoiceType` has been deprecated in Symfony 4.1 use a `\Closure` instead.
Copy link
Member

Choose a reason for hiding this comment

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

The version information is redundant. To match the message style of other entries in this file, I'd suggest:

* deprecated support for callable strings as `empty_data` in `ChoiceType`


4.0.0
-----

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,14 @@ public function buildForm(FormBuilderInterface $builder, array $options)
$emptyData = $form->getConfig()->getEmptyData();

if (false === FormUtil::isEmpty($emptyData) && array() !== $emptyData) {
$data = is_callable($emptyData) ? call_user_func($emptyData, $form, $data) : $emptyData;
if (is_callable($emptyData)) {
if (is_string($emptyData)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I've introduced that change as a bug fix in #17822 targeting 2.7.
But I've made a mistake, IMO we should do it like https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Form/Form.php#L610 and merge it in 2.7 as bug fix too. No need to deprecate anything.

Copy link
Member

Choose a reason for hiding this comment

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

#17822 is over 1.5y old now. People might have built code against that "feature" already. :-(

Copy link
Member

Choose a reason for hiding this comment

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

Also, I would not check for instanceof \Closure as this would forbid array callables and invokable objects for no reason.

Copy link
Contributor

Choose a reason for hiding this comment

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

The empty_data MUST be a closure for all forms, I'm not sure people rely on this hidden feature which is just a bug I introduced no matter when IMO.

@trigger_error('Passing callable strings is deprecated since version 4.1 and will be removed in 5.0. You should use a "\Closure" instead.', E_USER_DEPRECATED);
}
$data = call_user_func($emptyData, $form, $data);
} else {
$data = $emptyData;
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,47 @@ public function testSubmitMultipleChoiceExpandedWithEmptyData()
$this->assertSame(array('test'), $form->getData());
}

/**
* @group legacy
*/
public function testSubmitSingleChoiceWithCallableEmptyData()
{
$form = $this->factory->create(static::TESTED_TYPE, null, array(
'multiple' => false,
'expanded' => true,
'choices' => array('test'),
'empty_data' => __CLASS__.'::emptyDataResolver',
));

$form->submit(null);

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

/**
* @return string
*/
public static function emptyDataResolver()
{
return 'test';
}

public function testSubmitSingleChoiceWithClosureEmptyData()
{
$form = $this->factory->create(static::TESTED_TYPE, null, array(
'multiple' => false,
'expanded' => true,
'choices' => array('test'),
'empty_data' => function () {
return 'test';
},
));

$form->submit(null);

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

public function testSubmitMultipleNonExpanded()
{
$form = $this->factory->create(static::TESTED_TYPE, null, array(
Expand Down
0