From e250dfa702d7cd1a5639e84225a389a661c8e2d3 Mon Sep 17 00:00:00 2001 From: Yonel Ceruto Date: Thu, 5 Apr 2018 16:33:25 -0400 Subject: [PATCH 1/2] Add choice_translation_locale option for Intl choice types --- UPGRADE-4.2.md | 34 ++++++ src/Symfony/Component/Form/CHANGELOG.md | 6 + .../Loader/IntlCallbackChoiceLoader.php | 59 ++++++++++ .../Form/Extension/Core/Type/CountryType.php | 27 ++++- .../Form/Extension/Core/Type/CurrencyType.php | 27 ++++- .../Form/Extension/Core/Type/LanguageType.php | 27 ++++- .../Form/Extension/Core/Type/LocaleType.php | 27 ++++- .../Loader/IntlCallbackChoiceLoaderTest.php | 104 ++++++++++++++++++ .../Extension/Core/Type/CountryTypeTest.php | 19 ++++ .../Extension/Core/Type/CurrencyTypeTest.php | 17 +++ .../Extension/Core/Type/LanguageTypeTest.php | 19 ++++ .../Extension/Core/Type/LocaleTypeTest.php | 17 +++ 12 files changed, 379 insertions(+), 4 deletions(-) create mode 100644 UPGRADE-4.2.md create mode 100644 src/Symfony/Component/Form/ChoiceList/Loader/IntlCallbackChoiceLoader.php create mode 100644 src/Symfony/Component/Form/Tests/ChoiceList/Loader/IntlCallbackChoiceLoaderTest.php diff --git a/UPGRADE-4.2.md b/UPGRADE-4.2.md new file mode 100644 index 0000000000000..d647aeabef6ae --- /dev/null +++ b/UPGRADE-4.2.md @@ -0,0 +1,34 @@ +UPGRADE FROM 4.1 to 4.2 +======================= + +Form +---- + + * Deprecated the `ChoiceLoaderInterface` implementation in `CountryType`, `LanguageType`, `LocaleType` and `CurrencyType`, use the `choice_loader` option instead. + + Before: + ```php + class MyCountryType extends CountryType + { + public function loadChoiceList() + { + // override the method + } + } + ``` + + After: + ```php + class MyCountryType extends AbstractType + { + public function getParent() + { + return CountryType::class; + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefault('choice_loader', ...); // override the option instead + } + } + ``` diff --git a/src/Symfony/Component/Form/CHANGELOG.md b/src/Symfony/Component/Form/CHANGELOG.md index a3a36bf7bca6d..2d524c26cc100 100644 --- a/src/Symfony/Component/Form/CHANGELOG.md +++ b/src/Symfony/Component/Form/CHANGELOG.md @@ -1,6 +1,12 @@ CHANGELOG ========= +4.2.0 +----- + + * added `choice_translation_locale` option to `CountryType`, `LanguageType`, `LocaleType` and `CurrencyType` + * deprecated the `ChoiceLoaderInterface` implementation in `CountryType`, `LanguageType`, `LocaleType` and `CurrencyType` + 4.1.0 ----- diff --git a/src/Symfony/Component/Form/ChoiceList/Loader/IntlCallbackChoiceLoader.php b/src/Symfony/Component/Form/ChoiceList/Loader/IntlCallbackChoiceLoader.php new file mode 100644 index 0000000000000..f0140814fad6c --- /dev/null +++ b/src/Symfony/Component/Form/ChoiceList/Loader/IntlCallbackChoiceLoader.php @@ -0,0 +1,59 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\ChoiceList\Loader; + +/** + * Callback choice loader optimized for Intl choice types. + * + * @author Jules Pietri + * @author Yonel Ceruto + */ +class IntlCallbackChoiceLoader extends CallbackChoiceLoader +{ + /** + * {@inheritdoc} + */ + public function loadChoicesForValues(array $values, $value = null) + { + // Optimize + $values = array_filter($values); + if (empty($values)) { + return array(); + } + + // If no callable is set, values are the same as choices + if (null === $value) { + return $values; + } + + return $this->loadChoiceList($value)->getChoicesForValues($values); + } + + /** + * {@inheritdoc} + */ + public function loadValuesForChoices(array $choices, $value = null) + { + // Optimize + $choices = array_filter($choices); + if (empty($choices)) { + return array(); + } + + // If no callable is set, choices are the same as values + if (null === $value) { + return $choices; + } + + return $this->loadChoiceList($value)->getValuesForChoices($choices); + } +} diff --git a/src/Symfony/Component/Form/Extension/Core/Type/CountryType.php b/src/Symfony/Component/Form/Extension/Core/Type/CountryType.php index a96a42d3d6b67..1a0fd80a08760 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/CountryType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/CountryType.php @@ -14,7 +14,9 @@ use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\ChoiceList\ArrayChoiceList; use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface; +use Symfony\Component\Form\ChoiceList\Loader\IntlCallbackChoiceLoader; use Symfony\Component\Intl\Intl; +use Symfony\Component\OptionsResolver\Options; use Symfony\Component\OptionsResolver\OptionsResolver; class CountryType extends AbstractType implements ChoiceLoaderInterface @@ -27,6 +29,8 @@ class CountryType extends AbstractType implements ChoiceLoaderInterface * {@link \Symfony\Component\Intl\Intl::getRegionBundle()}. * * @var ArrayChoiceList + * + * @deprecated since Symfony 4.2 */ private $choiceList; @@ -36,9 +40,18 @@ class CountryType extends AbstractType implements ChoiceLoaderInterface public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(array( - 'choice_loader' => $this, + 'choice_loader' => function (Options $options) { + $choiceTranslationLocale = $options['choice_translation_locale']; + + return new IntlCallbackChoiceLoader(function () use ($choiceTranslationLocale) { + return array_flip(Intl::getRegionBundle()->getCountryNames($choiceTranslationLocale)); + }); + }, 'choice_translation_domain' => false, + 'choice_translation_locale' => null, )); + + $resolver->setAllowedTypes('choice_translation_locale', array('null', 'string')); } /** @@ -59,9 +72,13 @@ public function getBlockPrefix() /** * {@inheritdoc} + * + * @deprecated since Symfony 4.2 */ public function loadChoiceList($value = null) { + @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.2, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); + if (null !== $this->choiceList) { return $this->choiceList; } @@ -71,9 +88,13 @@ public function loadChoiceList($value = null) /** * {@inheritdoc} + * + * @deprecated since Symfony 4.2 */ public function loadChoicesForValues(array $values, $value = null) { + @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.2, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); + // Optimize $values = array_filter($values); if (empty($values)) { @@ -90,9 +111,13 @@ public function loadChoicesForValues(array $values, $value = null) /** * {@inheritdoc} + * + * @deprecated since Symfony 4.2 */ public function loadValuesForChoices(array $choices, $value = null) { + @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.2, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); + // Optimize $choices = array_filter($choices); if (empty($choices)) { diff --git a/src/Symfony/Component/Form/Extension/Core/Type/CurrencyType.php b/src/Symfony/Component/Form/Extension/Core/Type/CurrencyType.php index 9970d03ad7195..844a530e7fff5 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/CurrencyType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/CurrencyType.php @@ -14,7 +14,9 @@ use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\ChoiceList\ArrayChoiceList; use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface; +use Symfony\Component\Form\ChoiceList\Loader\IntlCallbackChoiceLoader; use Symfony\Component\Intl\Intl; +use Symfony\Component\OptionsResolver\Options; use Symfony\Component\OptionsResolver\OptionsResolver; class CurrencyType extends AbstractType implements ChoiceLoaderInterface @@ -27,6 +29,8 @@ class CurrencyType extends AbstractType implements ChoiceLoaderInterface * {@link \Symfony\Component\Intl\Intl::getCurrencyBundle()}. * * @var ArrayChoiceList + * + * @deprecated since Symfony 4.2 */ private $choiceList; @@ -36,9 +40,18 @@ class CurrencyType extends AbstractType implements ChoiceLoaderInterface public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(array( - 'choice_loader' => $this, + 'choice_loader' => function (Options $options) { + $choiceTranslationLocale = $options['choice_translation_locale']; + + return new IntlCallbackChoiceLoader(function () use ($choiceTranslationLocale) { + return array_flip(Intl::getCurrencyBundle()->getCurrencyNames($choiceTranslationLocale)); + }); + }, 'choice_translation_domain' => false, + 'choice_translation_locale' => null, )); + + $resolver->setAllowedTypes('choice_translation_locale', array('null', 'string')); } /** @@ -59,9 +72,13 @@ public function getBlockPrefix() /** * {@inheritdoc} + * + * @deprecated since Symfony 4.2 */ public function loadChoiceList($value = null) { + @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.2, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); + if (null !== $this->choiceList) { return $this->choiceList; } @@ -71,9 +88,13 @@ public function loadChoiceList($value = null) /** * {@inheritdoc} + * + * @deprecated since Symfony 4.2 */ public function loadChoicesForValues(array $values, $value = null) { + @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.2, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); + // Optimize $values = array_filter($values); if (empty($values)) { @@ -90,9 +111,13 @@ public function loadChoicesForValues(array $values, $value = null) /** * {@inheritdoc} + * + * @deprecated since Symfony 4.2 */ public function loadValuesForChoices(array $choices, $value = null) { + @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.2, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); + // Optimize $choices = array_filter($choices); if (empty($choices)) { diff --git a/src/Symfony/Component/Form/Extension/Core/Type/LanguageType.php b/src/Symfony/Component/Form/Extension/Core/Type/LanguageType.php index 279402a3e28e3..d69160379b343 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/LanguageType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/LanguageType.php @@ -14,7 +14,9 @@ use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\ChoiceList\ArrayChoiceList; use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface; +use Symfony\Component\Form\ChoiceList\Loader\IntlCallbackChoiceLoader; use Symfony\Component\Intl\Intl; +use Symfony\Component\OptionsResolver\Options; use Symfony\Component\OptionsResolver\OptionsResolver; class LanguageType extends AbstractType implements ChoiceLoaderInterface @@ -27,6 +29,8 @@ class LanguageType extends AbstractType implements ChoiceLoaderInterface * {@link \Symfony\Component\Intl\Intl::getLanguageBundle()}. * * @var ArrayChoiceList + * + * @deprecated since Symfony 4.2 */ private $choiceList; @@ -36,9 +40,18 @@ class LanguageType extends AbstractType implements ChoiceLoaderInterface public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(array( - 'choice_loader' => $this, + 'choice_loader' => function (Options $options) { + $choiceTranslationLocale = $options['choice_translation_locale']; + + return new IntlCallbackChoiceLoader(function () use ($choiceTranslationLocale) { + return array_flip(Intl::getLanguageBundle()->getLanguageNames($choiceTranslationLocale)); + }); + }, 'choice_translation_domain' => false, + 'choice_translation_locale' => null, )); + + $resolver->setAllowedTypes('choice_translation_locale', array('null', 'string')); } /** @@ -59,9 +72,13 @@ public function getBlockPrefix() /** * {@inheritdoc} + * + * @deprecated since Symfony 4.2 */ public function loadChoiceList($value = null) { + @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.2, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); + if (null !== $this->choiceList) { return $this->choiceList; } @@ -71,9 +88,13 @@ public function loadChoiceList($value = null) /** * {@inheritdoc} + * + * @deprecated since Symfony 4.2 */ public function loadChoicesForValues(array $values, $value = null) { + @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.2, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); + // Optimize $values = array_filter($values); if (empty($values)) { @@ -90,9 +111,13 @@ public function loadChoicesForValues(array $values, $value = null) /** * {@inheritdoc} + * + * @deprecated since Symfony 4.2 */ public function loadValuesForChoices(array $choices, $value = null) { + @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.2, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); + // Optimize $choices = array_filter($choices); if (empty($choices)) { diff --git a/src/Symfony/Component/Form/Extension/Core/Type/LocaleType.php b/src/Symfony/Component/Form/Extension/Core/Type/LocaleType.php index de795956b77a1..5b7b6111a0184 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/LocaleType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/LocaleType.php @@ -14,7 +14,9 @@ use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\ChoiceList\ArrayChoiceList; use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface; +use Symfony\Component\Form\ChoiceList\Loader\IntlCallbackChoiceLoader; use Symfony\Component\Intl\Intl; +use Symfony\Component\OptionsResolver\Options; use Symfony\Component\OptionsResolver\OptionsResolver; class LocaleType extends AbstractType implements ChoiceLoaderInterface @@ -27,6 +29,8 @@ class LocaleType extends AbstractType implements ChoiceLoaderInterface * {@link \Symfony\Component\Intl\Intl::getLocaleBundle()}. * * @var ArrayChoiceList + * + * @deprecated since Symfony 4.2 */ private $choiceList; @@ -36,9 +40,18 @@ class LocaleType extends AbstractType implements ChoiceLoaderInterface public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(array( - 'choice_loader' => $this, + 'choice_loader' => function (Options $options) { + $choiceTranslationLocale = $options['choice_translation_locale']; + + return new IntlCallbackChoiceLoader(function () use ($choiceTranslationLocale) { + return array_flip(Intl::getLocaleBundle()->getLocaleNames($choiceTranslationLocale)); + }); + }, 'choice_translation_domain' => false, + 'choice_translation_locale' => null, )); + + $resolver->setAllowedTypes('choice_translation_locale', array('null', 'string')); } /** @@ -59,9 +72,13 @@ public function getBlockPrefix() /** * {@inheritdoc} + * + * @deprecated since Symfony 4.2 */ public function loadChoiceList($value = null) { + @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.2, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); + if (null !== $this->choiceList) { return $this->choiceList; } @@ -71,9 +88,13 @@ public function loadChoiceList($value = null) /** * {@inheritdoc} + * + * @deprecated since Symfony 4.2 */ public function loadChoicesForValues(array $values, $value = null) { + @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.2, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); + // Optimize $values = array_filter($values); if (empty($values)) { @@ -90,9 +111,13 @@ public function loadChoicesForValues(array $values, $value = null) /** * {@inheritdoc} + * + * @deprecated since Symfony 4.2 */ public function loadValuesForChoices(array $choices, $value = null) { + @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.2, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); + // Optimize $choices = array_filter($choices); if (empty($choices)) { diff --git a/src/Symfony/Component/Form/Tests/ChoiceList/Loader/IntlCallbackChoiceLoaderTest.php b/src/Symfony/Component/Form/Tests/ChoiceList/Loader/IntlCallbackChoiceLoaderTest.php new file mode 100644 index 0000000000000..03e975dce1a24 --- /dev/null +++ b/src/Symfony/Component/Form/Tests/ChoiceList/Loader/IntlCallbackChoiceLoaderTest.php @@ -0,0 +1,104 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\ChoiceList\Loader; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Form\ChoiceList\ChoiceListInterface; +use Symfony\Component\Form\ChoiceList\LazyChoiceList; +use Symfony\Component\Form\ChoiceList\Loader\IntlCallbackChoiceLoader; + +/** + * @author Jules Pietri + * @author Yonel Ceruto + */ +class IntlCallbackChoiceLoaderTest extends TestCase +{ + /** + * @var \Symfony\Component\Form\ChoiceList\Loader\IntlCallbackChoiceLoader + */ + private static $loader; + + /** + * @var callable + */ + private static $value; + + /** + * @var array + */ + private static $choices; + + /** + * @var string[] + */ + private static $choiceValues; + + /** + * @var \Symfony\Component\Form\ChoiceList\LazyChoiceList + */ + private static $lazyChoiceList; + + public static function setUpBeforeClass() + { + self::$loader = new IntlCallbackChoiceLoader(function () { + return self::$choices; + }); + self::$value = function ($choice) { + return $choice->value ?? null; + }; + self::$choices = array( + (object) array('value' => 'choice_one'), + (object) array('value' => 'choice_two'), + ); + self::$choiceValues = array('choice_one', 'choice_two'); + self::$lazyChoiceList = new LazyChoiceList(self::$loader, self::$value); + } + + public function testLoadChoiceList() + { + $this->assertInstanceOf(ChoiceListInterface::class, self::$loader->loadChoiceList(self::$value)); + } + + public function testLoadChoiceListOnlyOnce() + { + $loadedChoiceList = self::$loader->loadChoiceList(self::$value); + + $this->assertSame($loadedChoiceList, self::$loader->loadChoiceList(self::$value)); + } + + public function testLoadChoicesForValuesLoadsChoiceListOnFirstCall() + { + $this->assertSame( + self::$loader->loadChoicesForValues(self::$choiceValues, self::$value), + self::$lazyChoiceList->getChoicesForValues(self::$choiceValues), + 'Choice list should not be reloaded.' + ); + } + + public function testLoadValuesForChoicesLoadsChoiceListOnFirstCall() + { + $this->assertSame( + self::$loader->loadValuesForChoices(self::$choices, self::$value), + self::$lazyChoiceList->getValuesForChoices(self::$choices), + 'Choice list should not be reloaded.' + ); + } + + public static function tearDownAfterClass() + { + self::$loader = null; + self::$value = null; + self::$choices = array(); + self::$choiceValues = array(); + self::$lazyChoiceList = null; + } +} diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/CountryTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/CountryTypeTest.php index 5f9af3e1c1b27..a8e9ddc7d34d9 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/CountryTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/CountryTypeTest.php @@ -38,6 +38,25 @@ public function testCountriesAreSelectable() $this->assertContains(new ChoiceView('MY', 'MY', 'Malaysia'), $choices, '', false, false); } + /** + * @requires extension intl + */ + public function testChoiceTranslationLocaleOption() + { + $choices = $this->factory + ->create(static::TESTED_TYPE, null, array( + 'choice_translation_locale' => 'uk', + )) + ->createView()->vars['choices']; + + // Don't check objects for identity + $this->assertContains(new ChoiceView('DE', 'DE', 'Німеччина'), $choices, '', false, false); + $this->assertContains(new ChoiceView('GB', 'GB', 'Велика Британія'), $choices, '', false, false); + $this->assertContains(new ChoiceView('US', 'US', 'Сполучені Штати'), $choices, '', false, false); + $this->assertContains(new ChoiceView('FR', 'FR', 'Франція'), $choices, '', false, false); + $this->assertContains(new ChoiceView('MY', 'MY', 'Малайзія'), $choices, '', false, false); + } + public function testUnknownCountryIsNotIncluded() { $choices = $this->factory->create(static::TESTED_TYPE, 'country') diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/CurrencyTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/CurrencyTypeTest.php index be9264d7b19db..01733c491797e 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/CurrencyTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/CurrencyTypeTest.php @@ -35,6 +35,23 @@ public function testCurrenciesAreSelectable() $this->assertContains(new ChoiceView('SIT', 'SIT', 'Slovenian Tolar'), $choices, '', false, false); } + /** + * @requires extension intl + */ + public function testChoiceTranslationLocaleOption() + { + $choices = $this->factory + ->create(static::TESTED_TYPE, null, array( + 'choice_translation_locale' => 'uk', + )) + ->createView()->vars['choices']; + + // Don't check objects for identity + $this->assertContains(new ChoiceView('EUR', 'EUR', 'євро'), $choices, '', false, false); + $this->assertContains(new ChoiceView('USD', 'USD', 'долар США'), $choices, '', false, false); + $this->assertContains(new ChoiceView('SIT', 'SIT', 'словенський толар'), $choices, '', false, false); + } + public function testSubmitNull($expected = null, $norm = null, $view = null) { parent::testSubmitNull($expected, $norm, ''); diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/LanguageTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/LanguageTypeTest.php index 5ea3c4a732165..ebe3d4ebb9f0e 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/LanguageTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/LanguageTypeTest.php @@ -37,6 +37,25 @@ public function testCountriesAreSelectable() $this->assertContains(new ChoiceView('my', 'my', 'Burmese'), $choices, '', false, false); } + /** + * @requires extension intl + */ + public function testChoiceTranslationLocaleOption() + { + $choices = $this->factory + ->create(static::TESTED_TYPE, null, array( + 'choice_translation_locale' => 'uk', + )) + ->createView()->vars['choices']; + + // Don't check objects for identity + $this->assertContains(new ChoiceView('en', 'en', 'англійська'), $choices, '', false, false); + $this->assertContains(new ChoiceView('en_GB', 'en_GB', 'British English'), $choices, '', false, false); + $this->assertContains(new ChoiceView('en_US', 'en_US', 'англійська (США)'), $choices, '', false, false); + $this->assertContains(new ChoiceView('fr', 'fr', 'французька'), $choices, '', false, false); + $this->assertContains(new ChoiceView('my', 'my', 'бірманська'), $choices, '', false, false); + } + public function testMultipleLanguagesIsNotIncluded() { $choices = $this->factory->create(static::TESTED_TYPE, 'language') diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/LocaleTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/LocaleTypeTest.php index 58b94517d4572..ab0dfa4bf17d3 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/LocaleTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/LocaleTypeTest.php @@ -35,6 +35,23 @@ public function testLocalesAreSelectable() $this->assertContains(new ChoiceView('zh_Hant_MO', 'zh_Hant_MO', 'Chinese (Traditional, Macau SAR China)'), $choices, '', false, false); } + /** + * @requires extension intl + */ + public function testChoiceTranslationLocaleOption() + { + $choices = $this->factory + ->create(static::TESTED_TYPE, null, array( + 'choice_translation_locale' => 'uk', + )) + ->createView()->vars['choices']; + + // Don't check objects for identity + $this->assertContains(new ChoiceView('en', 'en', 'англійська'), $choices, '', false, false); + $this->assertContains(new ChoiceView('en_GB', 'en_GB', 'англійська (Велика Британія)'), $choices, '', false, false); + $this->assertContains(new ChoiceView('zh_Hant_MO', 'zh_Hant_MO', 'китайська (традиційна, Макао, О.А.Р Китаю)'), $choices, '', false, false); + } + public function testSubmitNull($expected = null, $norm = null, $view = null) { parent::testSubmitNull($expected, $norm, ''); From 9592fa64cff94c095c549e490e6462fee5e57086 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 22 Apr 2018 08:16:01 +0200 Subject: [PATCH 2/2] moved feature to 4.1 --- UPGRADE-4.1.md | 34 +++++++++++++++++++ UPGRADE-4.2.md | 34 ------------------- src/Symfony/Component/Form/CHANGELOG.md | 6 +--- .../Form/Extension/Core/Type/CountryType.php | 14 ++++---- .../Form/Extension/Core/Type/CurrencyType.php | 14 ++++---- .../Form/Extension/Core/Type/LanguageType.php | 14 ++++---- .../Form/Extension/Core/Type/LocaleType.php | 14 ++++---- 7 files changed, 63 insertions(+), 67 deletions(-) delete mode 100644 UPGRADE-4.2.md diff --git a/UPGRADE-4.1.md b/UPGRADE-4.1.md index 8d96b710ed9ec..28302c42d305a 100644 --- a/UPGRADE-4.1.md +++ b/UPGRADE-4.1.md @@ -27,6 +27,40 @@ EventDispatcher * The `TraceableEventDispatcherInterface` has been deprecated. +Form +---- + + * Deprecated the `ChoiceLoaderInterface` implementation in `CountryType`, + `LanguageType`, `LocaleType` and `CurrencyType`, use the `choice_loader` + option instead. + + Before: + ```php + class MyCountryType extends CountryType + { + public function loadChoiceList() + { + // override the method + } + } + ``` + + After: + ```php + class MyCountryType extends AbstractType + { + public function getParent() + { + return CountryType::class; + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefault('choice_loader', ...); // override the option instead + } + } + ``` + FrameworkBundle --------------- diff --git a/UPGRADE-4.2.md b/UPGRADE-4.2.md deleted file mode 100644 index d647aeabef6ae..0000000000000 --- a/UPGRADE-4.2.md +++ /dev/null @@ -1,34 +0,0 @@ -UPGRADE FROM 4.1 to 4.2 -======================= - -Form ----- - - * Deprecated the `ChoiceLoaderInterface` implementation in `CountryType`, `LanguageType`, `LocaleType` and `CurrencyType`, use the `choice_loader` option instead. - - Before: - ```php - class MyCountryType extends CountryType - { - public function loadChoiceList() - { - // override the method - } - } - ``` - - After: - ```php - class MyCountryType extends AbstractType - { - public function getParent() - { - return CountryType::class; - } - - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefault('choice_loader', ...); // override the option instead - } - } - ``` diff --git a/src/Symfony/Component/Form/CHANGELOG.md b/src/Symfony/Component/Form/CHANGELOG.md index 2d524c26cc100..0cf142de256cb 100644 --- a/src/Symfony/Component/Form/CHANGELOG.md +++ b/src/Symfony/Component/Form/CHANGELOG.md @@ -1,15 +1,11 @@ CHANGELOG ========= -4.2.0 +4.1.0 ----- * added `choice_translation_locale` option to `CountryType`, `LanguageType`, `LocaleType` and `CurrencyType` * deprecated the `ChoiceLoaderInterface` implementation in `CountryType`, `LanguageType`, `LocaleType` and `CurrencyType` - -4.1.0 ------ - * added `input=datetime_immutable` to DateType, TimeType, DateTimeType * added `rounding_mode` option to MoneyType diff --git a/src/Symfony/Component/Form/Extension/Core/Type/CountryType.php b/src/Symfony/Component/Form/Extension/Core/Type/CountryType.php index 1a0fd80a08760..e206936dd32e8 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/CountryType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/CountryType.php @@ -30,7 +30,7 @@ class CountryType extends AbstractType implements ChoiceLoaderInterface * * @var ArrayChoiceList * - * @deprecated since Symfony 4.2 + * @deprecated since Symfony 4.1 */ private $choiceList; @@ -73,11 +73,11 @@ public function getBlockPrefix() /** * {@inheritdoc} * - * @deprecated since Symfony 4.2 + * @deprecated since Symfony 4.1 */ public function loadChoiceList($value = null) { - @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.2, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.1, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); if (null !== $this->choiceList) { return $this->choiceList; @@ -89,11 +89,11 @@ public function loadChoiceList($value = null) /** * {@inheritdoc} * - * @deprecated since Symfony 4.2 + * @deprecated since Symfony 4.1 */ public function loadChoicesForValues(array $values, $value = null) { - @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.2, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.1, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); // Optimize $values = array_filter($values); @@ -112,11 +112,11 @@ public function loadChoicesForValues(array $values, $value = null) /** * {@inheritdoc} * - * @deprecated since Symfony 4.2 + * @deprecated since Symfony 4.1 */ public function loadValuesForChoices(array $choices, $value = null) { - @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.2, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.1, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); // Optimize $choices = array_filter($choices); diff --git a/src/Symfony/Component/Form/Extension/Core/Type/CurrencyType.php b/src/Symfony/Component/Form/Extension/Core/Type/CurrencyType.php index 844a530e7fff5..79d874ca400b6 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/CurrencyType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/CurrencyType.php @@ -30,7 +30,7 @@ class CurrencyType extends AbstractType implements ChoiceLoaderInterface * * @var ArrayChoiceList * - * @deprecated since Symfony 4.2 + * @deprecated since Symfony 4.1 */ private $choiceList; @@ -73,11 +73,11 @@ public function getBlockPrefix() /** * {@inheritdoc} * - * @deprecated since Symfony 4.2 + * @deprecated since Symfony 4.1 */ public function loadChoiceList($value = null) { - @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.2, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.1, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); if (null !== $this->choiceList) { return $this->choiceList; @@ -89,11 +89,11 @@ public function loadChoiceList($value = null) /** * {@inheritdoc} * - * @deprecated since Symfony 4.2 + * @deprecated since Symfony 4.1 */ public function loadChoicesForValues(array $values, $value = null) { - @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.2, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.1, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); // Optimize $values = array_filter($values); @@ -112,11 +112,11 @@ public function loadChoicesForValues(array $values, $value = null) /** * {@inheritdoc} * - * @deprecated since Symfony 4.2 + * @deprecated since Symfony 4.1 */ public function loadValuesForChoices(array $choices, $value = null) { - @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.2, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.1, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); // Optimize $choices = array_filter($choices); diff --git a/src/Symfony/Component/Form/Extension/Core/Type/LanguageType.php b/src/Symfony/Component/Form/Extension/Core/Type/LanguageType.php index d69160379b343..6d35c2392140f 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/LanguageType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/LanguageType.php @@ -30,7 +30,7 @@ class LanguageType extends AbstractType implements ChoiceLoaderInterface * * @var ArrayChoiceList * - * @deprecated since Symfony 4.2 + * @deprecated since Symfony 4.1 */ private $choiceList; @@ -73,11 +73,11 @@ public function getBlockPrefix() /** * {@inheritdoc} * - * @deprecated since Symfony 4.2 + * @deprecated since Symfony 4.1 */ public function loadChoiceList($value = null) { - @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.2, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.1, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); if (null !== $this->choiceList) { return $this->choiceList; @@ -89,11 +89,11 @@ public function loadChoiceList($value = null) /** * {@inheritdoc} * - * @deprecated since Symfony 4.2 + * @deprecated since Symfony 4.1 */ public function loadChoicesForValues(array $values, $value = null) { - @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.2, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.1, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); // Optimize $values = array_filter($values); @@ -112,11 +112,11 @@ public function loadChoicesForValues(array $values, $value = null) /** * {@inheritdoc} * - * @deprecated since Symfony 4.2 + * @deprecated since Symfony 4.1 */ public function loadValuesForChoices(array $choices, $value = null) { - @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.2, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.1, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); // Optimize $choices = array_filter($choices); diff --git a/src/Symfony/Component/Form/Extension/Core/Type/LocaleType.php b/src/Symfony/Component/Form/Extension/Core/Type/LocaleType.php index 5b7b6111a0184..4c0c467729ff1 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/LocaleType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/LocaleType.php @@ -30,7 +30,7 @@ class LocaleType extends AbstractType implements ChoiceLoaderInterface * * @var ArrayChoiceList * - * @deprecated since Symfony 4.2 + * @deprecated since Symfony 4.1 */ private $choiceList; @@ -73,11 +73,11 @@ public function getBlockPrefix() /** * {@inheritdoc} * - * @deprecated since Symfony 4.2 + * @deprecated since Symfony 4.1 */ public function loadChoiceList($value = null) { - @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.2, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.1, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); if (null !== $this->choiceList) { return $this->choiceList; @@ -89,11 +89,11 @@ public function loadChoiceList($value = null) /** * {@inheritdoc} * - * @deprecated since Symfony 4.2 + * @deprecated since Symfony 4.1 */ public function loadChoicesForValues(array $values, $value = null) { - @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.2, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.1, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); // Optimize $values = array_filter($values); @@ -112,11 +112,11 @@ public function loadChoicesForValues(array $values, $value = null) /** * {@inheritdoc} * - * @deprecated since Symfony 4.2 + * @deprecated since Symfony 4.1 */ public function loadValuesForChoices(array $choices, $value = null) { - @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.2, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); + @trigger_error(sprintf('Method "%s" is deprecated since Symfony 4.1, use "choice_loader" option instead.', __METHOD__), E_USER_DEPRECATED); // Optimize $choices = array_filter($choices); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy