Description
Introduction
Currently the consumers of the OptionsResolver
component (mainly the Form
component, later LDAP
started to use it and possibly many bundles and libraries too) need sometime to delete or rename an already defined option or change its default value keeping BC, seeing itself in the need to create notes like this:
and manage themselves where and how to trigger the corresponding depreciation message:
symfony/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php
Lines 250 to 257 in 07d2570
Moreover, it isn't always effective if the option has a default value. For instance, according to the previous code doing this:
$builder->add('foo', EntityType::class, [
// ...
'property' => null,
]);
it wouldn't show the deprecation message because when the configured default value is equal to the given value -> we don't know that this option is being used. Also, the normalizer function (as just one is allowed) can be overridden by any current child type or type extension in userland, in that case, the message wouldn't show either.
Proposal to improve the current scenario
Introduce a simpler and safer way to deprecate an option using a new method in OptionsResolver
:
public function setDeprecated(string $option, string $deprecationMessage = 'The option "%name%" is deprecated.', callable $callback = null): self
Then, if this option is used or has default value, the deprecation message always will be triggered. Conditionally you could deprecate some values of many feasible by using the 3rd argument.
It is a small but powerful feature as this information can be displayed anywhere, in the form profiler, debug:form
command, etc.
Other method that could help to know whether a given option is deprecated or not is:
public function isDeprecated(string $option): bool
Example
Deprecating a whole option:
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'property' => null,
'choice_label' => // ...
]);
$resolver->setDeprecated('property', 'The option "property" is deprecated since Symfony X.Y. Use "choice_label" instead.');
}
Deprecating an option value:
public function configureOptions(OptionsResolver $resolver)
{
$resolver
->setDefault('foo', false)
->setAllowedTypes('foo', ['null', 'bool'])
->setDeprecated('foo', 'Passing "null" to option "foo" is deprecated since ...', function ($value) {
return null === $value; // value before normalization
})
;
}
Let me know first if it's something that core & community need. I've prepared a tiny PR for that.
Cheers!