Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[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 19 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` is deprecated and will be removed in Symfony 5.0, use a `\Closure` instead.

Before:

```php
'empty_data' => 'some_function',
```

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 some_function($form, $data);
},
```

Workflow
--------

Expand Down
19 changes: 19 additions & 0 deletions 19 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
----

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

Before:

```php
'empty_data' => 'some_function',
```

After:

```php
'empty_data' => function (FormInterface $form, $data) {
return some_function($form, $data);
},
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 5 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
Morty Proxy This is a proxified and sanitized view of the page, visit original site.