[Form] Allow to translate each language into its language in LanguageType

This commit is contained in:
Javier Eguiluz 2019-07-05 10:41:57 +02:00 committed by Fabien Potencier
parent e0f6cdb1c7
commit 138200cd88
2 changed files with 76 additions and 3 deletions

View File

@ -13,6 +13,8 @@ namespace Symfony\Component\Form\Extension\Core\Type;
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 @@ class LanguageType extends AbstractType
$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;
});
}
/**

View File

@ -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 @@ class LanguageTypeTest extends BaseTypeTest
$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')