From 138200cd884c13dfeb813f7be75c8598d009b6b3 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 5 Jul 2019 10:41:57 +0200 Subject: [PATCH] [Form] Allow to translate each language into its language in LanguageType --- .../Form/Extension/Core/Type/LanguageType.php | 32 +++++++++++-- .../Extension/Core/Type/LanguageTypeTest.php | 47 +++++++++++++++++++ 2 files changed, 76 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Form/Extension/Core/Type/LanguageType.php b/src/Symfony/Component/Form/Extension/Core/Type/LanguageType.php index 47cd043a1b8fe..16a231cc265ad 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/LanguageType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/LanguageType.php @@ -13,6 +13,8 @@ use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\ChoiceList\Loader\IntlCallbackChoiceLoader; +use Symfony\Component\Form\Exception\LogicException; +use Symfony\Component\Intl\Exception\MissingResourceException; use Symfony\Component\Intl\Languages; use Symfony\Component\OptionsResolver\Options; use Symfony\Component\OptionsResolver\OptionsResolver; @@ -27,19 +29,43 @@ public function configureOptions(OptionsResolver $resolver) $resolver->setDefaults([ 'choice_loader' => function (Options $options) { $choiceTranslationLocale = $options['choice_translation_locale']; - $alpha3 = $options['alpha3']; + $useAlpha3Codes = $options['alpha3']; + $choiceSelfTranslation = $options['choice_self_translation']; - return new IntlCallbackChoiceLoader(function () use ($choiceTranslationLocale, $alpha3) { - return array_flip($alpha3 ? Languages::getAlpha3Names($choiceTranslationLocale) : Languages::getNames($choiceTranslationLocale)); + return new IntlCallbackChoiceLoader(function () use ($choiceTranslationLocale, $useAlpha3Codes, $choiceSelfTranslation) { + if (true === $choiceSelfTranslation) { + foreach (Languages::getLanguageCodes() as $alpha2Code) { + try { + $languageCode = $useAlpha3Codes ? Languages::getAlpha3Code($alpha2Code) : $alpha2Code; + $languagesList[$languageCode] = Languages::getName($alpha2Code, $alpha2Code); + } catch (MissingResourceException $e) { + // ignore errors like "Couldn't read the indices for the locale 'meta'" + } + } + } else { + $languagesList = $useAlpha3Codes ? Languages::getAlpha3Names($choiceTranslationLocale) : Languages::getNames($choiceTranslationLocale); + } + + return array_flip($languagesList); }); }, 'choice_translation_domain' => false, 'choice_translation_locale' => null, 'alpha3' => false, + 'choice_self_translation' => false, ]); + $resolver->setAllowedTypes('choice_self_translation', ['bool']); $resolver->setAllowedTypes('choice_translation_locale', ['null', 'string']); $resolver->setAllowedTypes('alpha3', 'bool'); + + $resolver->setNormalizer('choice_self_translation', function (Options $options, $value) { + if (true === $value && $options['choice_translation_locale']) { + throw new LogicException('Cannot use the "choice_self_translation" and "choice_translation_locale" options at the same time. Remove one of them.'); + } + + return $value; + }); } /** 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 a7c064a7ac80b..488e60bc97e7a 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/LanguageTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/LanguageTypeTest.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Form\Tests\Extension\Core\Type; use Symfony\Component\Form\ChoiceList\View\ChoiceView; +use Symfony\Component\Form\Exception\LogicException; use Symfony\Component\Intl\Util\IntlTestHelper; class LanguageTypeTest extends BaseTypeTest @@ -86,6 +87,52 @@ public function testChoiceTranslationLocaleAndAlpha3Option() $this->assertNotContainsEquals(new ChoiceView('my', 'my', 'бірманська'), $choices); } + /** + * @requires extension intl + */ + public function testChoiceSelfTranslationOption() + { + $choices = $this->factory + ->create(static::TESTED_TYPE, null, [ + 'choice_self_translation' => true, + ]) + ->createView()->vars['choices']; + + $this->assertContainsEquals(new ChoiceView('cs', 'cs', 'čeština'), $choices); + $this->assertContainsEquals(new ChoiceView('es', 'es', 'español'), $choices); + $this->assertContainsEquals(new ChoiceView('fr', 'fr', 'français'), $choices); + $this->assertContainsEquals(new ChoiceView('ta', 'ta', 'தமிழ்'), $choices); + $this->assertContainsEquals(new ChoiceView('uk', 'uk', 'українська'), $choices); + $this->assertContainsEquals(new ChoiceView('yi', 'yi', 'ייִדיש'), $choices); + $this->assertContainsEquals(new ChoiceView('zh', 'zh', '中文'), $choices); + } + + /** + * @requires extension intl + */ + public function testChoiceSelfTranslationAndAlpha3Options() + { + $choices = $this->factory + ->create(static::TESTED_TYPE, null, [ + 'alpha3' => true, + 'choice_self_translation' => true, + ]) + ->createView()->vars['choices']; + + $this->assertContainsEquals(new ChoiceView('spa', 'spa', 'español'), $choices, '', false, false); + $this->assertContainsEquals(new ChoiceView('yid', 'yid', 'ייִדיש'), $choices, '', false, false); + } + + public function testSelfTranslationNotAllowedWithChoiceTranslation() + { + $this->expectException(LogicException::class); + + $this->factory->create(static::TESTED_TYPE, null, [ + 'choice_translation_locale' => 'es', + 'choice_self_translation' => true, + ]); + } + public function testMultipleLanguagesIsNotIncluded() { $choices = $this->factory->create(static::TESTED_TYPE, 'language')