diff --git a/src/Symfony/Component/Form/CHANGELOG.md b/src/Symfony/Component/Form/CHANGELOG.md index 2a356d51be..5a618f2a35 100644 --- a/src/Symfony/Component/Form/CHANGELOG.md +++ b/src/Symfony/Component/Form/CHANGELOG.md @@ -5,6 +5,7 @@ CHANGELOG ----- * added `CallbackChoiceLoader` + * implemented `ChoiceLoaderInterface` in children of `ChoiceType` 3.1.0 ----- diff --git a/src/Symfony/Component/Form/Extension/Core/Type/CountryType.php b/src/Symfony/Component/Form/Extension/Core/Type/CountryType.php index b4a65f2978..036946d56b 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/CountryType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/CountryType.php @@ -12,18 +12,31 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\ChoiceList\ArrayChoiceList; +use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface; use Symfony\Component\Intl\Intl; use Symfony\Component\OptionsResolver\OptionsResolver; -class CountryType extends AbstractType +class CountryType extends AbstractType implements ChoiceLoaderInterface { + /** + * Country loaded choice list. + * + * The choices are lazy loaded and generated from the Intl component. + * + * {@link \Symfony\Component\Intl\Intl::getRegionBundle()}. + * + * @var ArrayChoiceList + */ + private $choiceList; + /** * {@inheritdoc} */ public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(array( - 'choices' => array_flip(Intl::getRegionBundle()->getCountryNames()), + 'choice_loader' => $this, 'choice_translation_domain' => false, )); } @@ -43,4 +56,52 @@ class CountryType extends AbstractType { return 'country'; } + + /** + * {@inheritdoc} + */ + public function loadChoiceList($value = null) + { + if (null !== $this->choiceList) { + return $this->choiceList; + } + + return $this->choiceList = new ArrayChoiceList(array_flip(Intl::getRegionBundle()->getCountryNames()), $value); + } + + /** + * {@inheritdoc} + */ + public function loadChoicesForValues(array $values, $value = null) + { + // Optimize + 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 + 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/CurrencyType.php b/src/Symfony/Component/Form/Extension/Core/Type/CurrencyType.php index 7e0497fcc9..5edc298304 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/CurrencyType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/CurrencyType.php @@ -12,18 +12,31 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\ChoiceList\ArrayChoiceList; +use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface; use Symfony\Component\Intl\Intl; use Symfony\Component\OptionsResolver\OptionsResolver; -class CurrencyType extends AbstractType +class CurrencyType extends AbstractType implements ChoiceLoaderInterface { + /** + * Currency loaded choice list. + * + * The choices are lazy loaded and generated from the Intl component. + * + * {@link \Symfony\Component\Intl\Intl::getCurrencyBundle()}. + * + * @var ArrayChoiceList + */ + private $choiceList; + /** * {@inheritdoc} */ public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(array( - 'choices' => array_flip(Intl::getCurrencyBundle()->getCurrencyNames()), + 'choice_loader' => $this, 'choice_translation_domain' => false, )); } @@ -43,4 +56,52 @@ class CurrencyType extends AbstractType { return 'currency'; } + + /** + * {@inheritdoc} + */ + public function loadChoiceList($value = null) + { + if (null !== $this->choiceList) { + return $this->choiceList; + } + + return $this->choiceList = new ArrayChoiceList(array_flip(Intl::getCurrencyBundle()->getCurrencyNames()), $value); + } + + /** + * {@inheritdoc} + */ + public function loadChoicesForValues(array $values, $value = null) + { + // Optimize + 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 + 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/LanguageType.php b/src/Symfony/Component/Form/Extension/Core/Type/LanguageType.php index 022ab24a8b..c77d6d0416 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/LanguageType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/LanguageType.php @@ -12,18 +12,31 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\ChoiceList\ArrayChoiceList; +use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface; use Symfony\Component\Intl\Intl; use Symfony\Component\OptionsResolver\OptionsResolver; -class LanguageType extends AbstractType +class LanguageType extends AbstractType implements ChoiceLoaderInterface { + /** + * Language loaded choice list. + * + * The choices are lazy loaded and generated from the Intl component. + * + * {@link \Symfony\Component\Intl\Intl::getLanguageBundle()}. + * + * @var ArrayChoiceList + */ + private $choiceList; + /** * {@inheritdoc} */ public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(array( - 'choices' => array_flip(Intl::getLanguageBundle()->getLanguageNames()), + 'choice_loader' => $this, 'choice_translation_domain' => false, )); } @@ -43,4 +56,52 @@ class LanguageType extends AbstractType { return 'language'; } + + /** + * {@inheritdoc} + */ + public function loadChoiceList($value = null) + { + if (null !== $this->choiceList) { + return $this->choiceList; + } + + return $this->choiceList = new ArrayChoiceList(array_flip(Intl::getLanguageBundle()->getLanguageNames()), $value); + } + + /** + * {@inheritdoc} + */ + public function loadChoicesForValues(array $values, $value = null) + { + // Optimize + 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 + 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/LocaleType.php b/src/Symfony/Component/Form/Extension/Core/Type/LocaleType.php index 86ff038b74..44e362f0f7 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/LocaleType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/LocaleType.php @@ -12,18 +12,31 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\ChoiceList\ArrayChoiceList; +use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface; use Symfony\Component\Intl\Intl; use Symfony\Component\OptionsResolver\OptionsResolver; -class LocaleType extends AbstractType +class LocaleType extends AbstractType implements ChoiceLoaderInterface { + /** + * Locale loaded choice list. + * + * The choices are lazy loaded and generated from the Intl component. + * + * {@link \Symfony\Component\Intl\Intl::getLocaleBundle()}. + * + * @var ArrayChoiceList + */ + private $choiceList; + /** * {@inheritdoc} */ public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(array( - 'choices' => array_flip(Intl::getLocaleBundle()->getLocaleNames()), + 'choice_loader' => $this, 'choice_translation_domain' => false, )); } @@ -43,4 +56,52 @@ class LocaleType extends AbstractType { return 'locale'; } + + /** + * {@inheritdoc} + */ + public function loadChoiceList($value = null) + { + if (null !== $this->choiceList) { + return $this->choiceList; + } + + return $this->choiceList = new ArrayChoiceList(array_flip(Intl::getLocaleBundle()->getLocaleNames()), $value); + } + + /** + * {@inheritdoc} + */ + public function loadChoicesForValues(array $values, $value = null) + { + // Optimize + 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 + 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/TimezoneType.php b/src/Symfony/Component/Form/Extension/Core/Type/TimezoneType.php index 7f2f34f705..aaa5bd1c6e 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/TimezoneType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/TimezoneType.php @@ -12,16 +12,20 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\ChoiceList\ArrayChoiceList; +use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; -class TimezoneType extends AbstractType +class TimezoneType extends AbstractType implements ChoiceLoaderInterface { /** - * Stores the available timezone choices. + * Timezone loaded choice list. * - * @var array + * The choices are generated from the ICU function \DateTimeZone::listIdentifiers(). + * + * @var ArrayChoiceList */ - private static $timezones; + private $choiceList; /** * {@inheritdoc} @@ -29,7 +33,7 @@ class TimezoneType extends AbstractType public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(array( - 'choices' => self::getTimezones(), + 'choice_loader' => $this, 'choice_translation_domain' => false, )); } @@ -51,38 +55,79 @@ class TimezoneType extends AbstractType } /** - * Returns the timezone choices. - * - * The choices are generated from the ICU function - * \DateTimeZone::listIdentifiers(). They are cached during a single request, - * so multiple timezone fields on the same page don't lead to unnecessary - * overhead. + * {@inheritdoc} + */ + public function loadChoiceList($value = null) + { + if (null !== $this->choiceList) { + return $this->choiceList; + } + + return $this->choiceList = new ArrayChoiceList($this->getTimezones(), $value); + } + + /** + * {@inheritdoc} + */ + public function loadChoicesForValues(array $values, $value = null) + { + // Optimize + 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 + 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); + } + + /** + * Returns a normalized array of timezone choices. * * @return array The timezone choices */ private static function getTimezones() { - if (null === self::$timezones) { - self::$timezones = array(); + $timezones = array(); - foreach (\DateTimeZone::listIdentifiers() as $timezone) { - $parts = explode('/', $timezone); + foreach (\DateTimeZone::listIdentifiers() as $timezone) { + $parts = explode('/', $timezone); - if (count($parts) > 2) { - $region = $parts[0]; - $name = $parts[1].' - '.$parts[2]; - } elseif (count($parts) > 1) { - $region = $parts[0]; - $name = $parts[1]; - } else { - $region = 'Other'; - $name = $parts[0]; - } - - self::$timezones[$region][str_replace('_', ' ', $name)] = $timezone; + if (count($parts) > 2) { + $region = $parts[0]; + $name = $parts[1].' - '.$parts[2]; + } elseif (count($parts) > 1) { + $region = $parts[0]; + $name = $parts[1]; + } else { + $region = 'Other'; + $name = $parts[0]; } + + $timezones[$region][str_replace('_', ' ', $name)] = $timezone; } - return self::$timezones; + return $timezones; } }