diff --git a/UPGRADE-3.3.md b/UPGRADE-3.3.md index 9ce7ee90d1..d58a018f2b 100644 --- a/UPGRADE-3.3.md +++ b/UPGRADE-3.3.md @@ -130,6 +130,34 @@ Finder * The `ExceptionInterface` has been deprecated and will be removed in 4.0. +Form +---- + + * Using the "choices" option in ``CountryType``, ``CurrencyType``, ``LanguageType``, + ``LocaleType``, and ``TimezoneType`` without overriding the ``choice_loader`` + option has been deprecated and will be ignored in 4.0. + + Before: + ```php + $builder->add('custom_locales', LocaleType::class, array( + 'choices' => $availableLocales, + )); + ``` + + After: + ```php + $builder->add('custom_locales', LocaleType::class, array( + 'choices' => $availableLocales, + 'choice_loader' => null, + )); + // or + $builder->add('custom_locales', LocaleType::class, array( + 'choice_loader' => new CallbackChoiceLoader(function () { + return $this->getAvailableLocales(); + }), + )); + ``` + FrameworkBundle --------------- diff --git a/UPGRADE-4.0.md b/UPGRADE-4.0.md index a19b082c80..b9bf1295ee 100644 --- a/UPGRADE-4.0.md +++ b/UPGRADE-4.0.md @@ -193,6 +193,31 @@ Form } ``` + * Using the "choices" option in ``CountryType``, ``CurrencyType``, ``LanguageType``, + ``LocaleType``, and ``TimezoneType`` without overriding the ``choice_loader`` + option is now ignored. + + Before: + ```php + $builder->add('custom_locales', LocaleType::class, array( + 'choices' => $availableLocales, + )); + ``` + + After: + ```php + $builder->add('custom_locales', LocaleType::class, array( + 'choices' => $availableLocales, + 'choice_loader' => null, + )); + // or + $builder->add('custom_locales', LocaleType::class, array( + 'choice_loader' => new CallbackChoiceLoader(function () { + return $this->getAvailableLocales(); + }), + )); + ``` + FrameworkBundle --------------- diff --git a/src/Symfony/Component/Form/CHANGELOG.md b/src/Symfony/Component/Form/CHANGELOG.md index 1123119356..1c8936995c 100644 --- a/src/Symfony/Component/Form/CHANGELOG.md +++ b/src/Symfony/Component/Form/CHANGELOG.md @@ -4,6 +4,8 @@ CHANGELOG 3.3.0 ----- + * deprecated using "choices" option in ``CountryType``, ``CurrencyType``, ``LanguageType``, ``LocaleType``, and + ``TimezoneType`` when "choice_loader" is not ``null`` * added `Symfony\Component\Form\FormErrorIterator::findByCodes()` * added `getTypedExtensions`, `getTypes`, and `getTypeGuessers` to `Symfony\Component\Form\Test\FormIntegrationTestCase` * added `FormPass` diff --git a/src/Symfony/Component/Form/Extension/Core/Type/CountryType.php b/src/Symfony/Component/Form/Extension/Core/Type/CountryType.php index 6484a4c34f..02e8e09cdc 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/CountryType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/CountryType.php @@ -38,7 +38,13 @@ class CountryType extends AbstractType implements ChoiceLoaderInterface { $resolver->setDefaults(array( 'choice_loader' => function (Options $options) { - return $options['choices'] ? null : $this; + if ($options['choices']) { + @trigger_error(sprintf('Using the "choices" option in %s has been deprecated since version 3.3 and will be ignored in 4.0. Override the "choice_loader" option instead or set it to null.', __CLASS__), E_USER_DEPRECATED); + + return null; + } + + return $this; }, 'choice_translation_domain' => false, )); diff --git a/src/Symfony/Component/Form/Extension/Core/Type/CurrencyType.php b/src/Symfony/Component/Form/Extension/Core/Type/CurrencyType.php index 4a8d3c4421..990235c10a 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/CurrencyType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/CurrencyType.php @@ -38,7 +38,13 @@ class CurrencyType extends AbstractType implements ChoiceLoaderInterface { $resolver->setDefaults(array( 'choice_loader' => function (Options $options) { - return $options['choices'] ? null : $this; + if ($options['choices']) { + @trigger_error(sprintf('Using the "choices" option in %s has been deprecated since version 3.3 and will be ignored in 4.0. Override the "choice_loader" option instead or set it to null.', __CLASS__), E_USER_DEPRECATED); + + return null; + } + + return $this; }, 'choice_translation_domain' => false, )); diff --git a/src/Symfony/Component/Form/Extension/Core/Type/LanguageType.php b/src/Symfony/Component/Form/Extension/Core/Type/LanguageType.php index 3e62bdddce..2137c65a9e 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/LanguageType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/LanguageType.php @@ -38,7 +38,13 @@ class LanguageType extends AbstractType implements ChoiceLoaderInterface { $resolver->setDefaults(array( 'choice_loader' => function (Options $options) { - return $options['choices'] ? null : $this; + if ($options['choices']) { + @trigger_error(sprintf('Using the "choices" option in %s has been deprecated since version 3.3 and will be ignored in 4.0. Override the "choice_loader" option instead or set it to null.', __CLASS__), E_USER_DEPRECATED); + + return null; + } + + return $this; }, 'choice_translation_domain' => false, )); diff --git a/src/Symfony/Component/Form/Extension/Core/Type/LocaleType.php b/src/Symfony/Component/Form/Extension/Core/Type/LocaleType.php index d5f191c0a2..38e62af060 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/LocaleType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/LocaleType.php @@ -38,7 +38,13 @@ class LocaleType extends AbstractType implements ChoiceLoaderInterface { $resolver->setDefaults(array( 'choice_loader' => function (Options $options) { - return $options['choices'] ? null : $this; + if ($options['choices']) { + @trigger_error(sprintf('Using the "choices" option in %s has been deprecated since version 3.3 and will be ignored in 4.0. Override the "choice_loader" option instead or set it to null.', __CLASS__), E_USER_DEPRECATED); + + return null; + } + + return $this; }, 'choice_translation_domain' => false, )); diff --git a/src/Symfony/Component/Form/Extension/Core/Type/TimezoneType.php b/src/Symfony/Component/Form/Extension/Core/Type/TimezoneType.php index beb83dde4f..ffa86cb9aa 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/TimezoneType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/TimezoneType.php @@ -35,7 +35,13 @@ class TimezoneType extends AbstractType implements ChoiceLoaderInterface { $resolver->setDefaults(array( 'choice_loader' => function (Options $options) { - return $options['choices'] ? null : $this; + if ($options['choices']) { + @trigger_error(sprintf('Using the "choices" option in %s has been deprecated since version 3.3 and will be ignored in 4.0. Override the "choice_loader" option instead or set it to null.', __CLASS__), E_USER_DEPRECATED); + + return null; + } + + return $this; }, 'choice_translation_domain' => false, )); diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ExtendedChoiceTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ExtendedChoiceTypeTest.php index 6f9b4d128d..959ae488a1 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ExtendedChoiceTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ExtendedChoiceTypeTest.php @@ -14,13 +14,15 @@ namespace Symfony\Component\Form\Tests\Extension\Core\Type; use PHPUnit\Framework\TestCase; use Symfony\Component\Form\Forms; use Symfony\Component\Form\Tests\Fixtures\ChoiceTypeExtension; +use Symfony\Component\Form\Tests\Fixtures\LazyChoiceTypeExtension; class ExtendedChoiceTypeTest extends TestCase { /** + * @group legacy * @dataProvider provideTestedTypes */ - public function testChoicesAreOverridden($type) + public function testLegacyChoicesAreOverridden($type) { $factory = Forms::createFormFactoryBuilder() ->addTypeExtension(new ChoiceTypeExtension($type)) @@ -36,6 +38,44 @@ class ExtendedChoiceTypeTest extends TestCase $this->assertSame('b', $choices[1]->value); } + /** + * @dataProvider provideTestedTypes + */ + public function testChoicesAreOverridden($type) + { + $factory = Forms::createFormFactoryBuilder() + ->addTypeExtension(new ChoiceTypeExtension($type)) + ->getFormFactory() + ; + + $choices = $factory->create($type, null, array('choice_loader' => null))->createView()->vars['choices']; + + $this->assertCount(2, $choices); + $this->assertSame('A', $choices[0]->label); + $this->assertSame('a', $choices[0]->value); + $this->assertSame('B', $choices[1]->label); + $this->assertSame('b', $choices[1]->value); + } + + /** + * @dataProvider provideTestedTypes + */ + public function testChoiceLoaderIsOverridden($type) + { + $factory = Forms::createFormFactoryBuilder() + ->addTypeExtension(new LazyChoiceTypeExtension($type)) + ->getFormFactory() + ; + + $choices = $factory->create($type)->createView()->vars['choices']; + + $this->assertCount(2, $choices); + $this->assertSame('Lazy A', $choices[0]->label); + $this->assertSame('lazy_a', $choices[0]->value); + $this->assertSame('Lazy B', $choices[1]->label); + $this->assertSame('lazy_b', $choices[1]->value); + } + public function provideTestedTypes() { yield array(CountryTypeTest::TESTED_TYPE); diff --git a/src/Symfony/Component/Form/Tests/Fixtures/LazyChoiceTypeExtension.php b/src/Symfony/Component/Form/Tests/Fixtures/LazyChoiceTypeExtension.php new file mode 100644 index 0000000000..133b8829e0 --- /dev/null +++ b/src/Symfony/Component/Form/Tests/Fixtures/LazyChoiceTypeExtension.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Fixtures; + +use Symfony\Component\Form\AbstractTypeExtension; +use Symfony\Component\Form\ChoiceList\Loader\CallbackChoiceLoader; +use Symfony\Component\Form\Extension\Core\Type\ChoiceType; +use Symfony\Component\OptionsResolver\OptionsResolver; + +class LazyChoiceTypeExtension extends AbstractTypeExtension +{ + private $extendedType; + + public function __construct($extendedType = ChoiceType::class) + { + $this->extendedType = $extendedType; + } + + /** + * {@inheritdoc} + */ + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefault('choice_loader', new CallbackChoiceLoader(function () { + return array( + 'Lazy A' => 'lazy_a', + 'Lazy B' => 'lazy_b', + ); + })); + } + + /** + * {@inheritdoc} + */ + public function getExtendedType() + { + return $this->extendedType; + } +}