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` 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 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);
},
```

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
-----

* 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