[Form] implemented ChoiceLoaderInterface in children of ChoiceType

This commit is contained in:
Jules Pietri 2016-03-27 20:32:00 +02:00
parent afd7bf8d56
commit 8a4e164286
6 changed files with 326 additions and 36 deletions

View File

@ -5,6 +5,7 @@ CHANGELOG
----- -----
* added `CallbackChoiceLoader` * added `CallbackChoiceLoader`
* implemented `ChoiceLoaderInterface` in children of `ChoiceType`
3.1.0 3.1.0
----- -----

View File

@ -12,18 +12,31 @@
namespace Symfony\Component\Form\Extension\Core\Type; namespace Symfony\Component\Form\Extension\Core\Type;
use Symfony\Component\Form\AbstractType; 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\Intl\Intl;
use Symfony\Component\OptionsResolver\OptionsResolver; 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} * {@inheritdoc}
*/ */
public function configureOptions(OptionsResolver $resolver) public function configureOptions(OptionsResolver $resolver)
{ {
$resolver->setDefaults(array( $resolver->setDefaults(array(
'choices' => array_flip(Intl::getRegionBundle()->getCountryNames()), 'choice_loader' => $this,
'choice_translation_domain' => false, 'choice_translation_domain' => false,
)); ));
} }
@ -43,4 +56,52 @@ class CountryType extends AbstractType
{ {
return 'country'; 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);
}
} }

View File

@ -12,18 +12,31 @@
namespace Symfony\Component\Form\Extension\Core\Type; namespace Symfony\Component\Form\Extension\Core\Type;
use Symfony\Component\Form\AbstractType; 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\Intl\Intl;
use Symfony\Component\OptionsResolver\OptionsResolver; 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} * {@inheritdoc}
*/ */
public function configureOptions(OptionsResolver $resolver) public function configureOptions(OptionsResolver $resolver)
{ {
$resolver->setDefaults(array( $resolver->setDefaults(array(
'choices' => array_flip(Intl::getCurrencyBundle()->getCurrencyNames()), 'choice_loader' => $this,
'choice_translation_domain' => false, 'choice_translation_domain' => false,
)); ));
} }
@ -43,4 +56,52 @@ class CurrencyType extends AbstractType
{ {
return 'currency'; 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);
}
} }

View File

@ -12,18 +12,31 @@
namespace Symfony\Component\Form\Extension\Core\Type; namespace Symfony\Component\Form\Extension\Core\Type;
use Symfony\Component\Form\AbstractType; 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\Intl\Intl;
use Symfony\Component\OptionsResolver\OptionsResolver; 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} * {@inheritdoc}
*/ */
public function configureOptions(OptionsResolver $resolver) public function configureOptions(OptionsResolver $resolver)
{ {
$resolver->setDefaults(array( $resolver->setDefaults(array(
'choices' => array_flip(Intl::getLanguageBundle()->getLanguageNames()), 'choice_loader' => $this,
'choice_translation_domain' => false, 'choice_translation_domain' => false,
)); ));
} }
@ -43,4 +56,52 @@ class LanguageType extends AbstractType
{ {
return 'language'; 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);
}
} }

View File

@ -12,18 +12,31 @@
namespace Symfony\Component\Form\Extension\Core\Type; namespace Symfony\Component\Form\Extension\Core\Type;
use Symfony\Component\Form\AbstractType; 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\Intl\Intl;
use Symfony\Component\OptionsResolver\OptionsResolver; 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} * {@inheritdoc}
*/ */
public function configureOptions(OptionsResolver $resolver) public function configureOptions(OptionsResolver $resolver)
{ {
$resolver->setDefaults(array( $resolver->setDefaults(array(
'choices' => array_flip(Intl::getLocaleBundle()->getLocaleNames()), 'choice_loader' => $this,
'choice_translation_domain' => false, 'choice_translation_domain' => false,
)); ));
} }
@ -43,4 +56,52 @@ class LocaleType extends AbstractType
{ {
return 'locale'; 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);
}
} }

View File

@ -12,16 +12,20 @@
namespace Symfony\Component\Form\Extension\Core\Type; namespace Symfony\Component\Form\Extension\Core\Type;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\ChoiceList\ArrayChoiceList;
use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver; 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} * {@inheritdoc}
@ -29,7 +33,7 @@ class TimezoneType extends AbstractType
public function configureOptions(OptionsResolver $resolver) public function configureOptions(OptionsResolver $resolver)
{ {
$resolver->setDefaults(array( $resolver->setDefaults(array(
'choices' => self::getTimezones(), 'choice_loader' => $this,
'choice_translation_domain' => false, 'choice_translation_domain' => false,
)); ));
} }
@ -51,38 +55,79 @@ class TimezoneType extends AbstractType
} }
/** /**
* Returns the timezone choices. * {@inheritdoc}
* */
* The choices are generated from the ICU function public function loadChoiceList($value = null)
* \DateTimeZone::listIdentifiers(). They are cached during a single request, {
* so multiple timezone fields on the same page don't lead to unnecessary if (null !== $this->choiceList) {
* overhead. 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 * @return array The timezone choices
*/ */
private static function getTimezones() private static function getTimezones()
{ {
if (null === self::$timezones) { $timezones = array();
self::$timezones = array();
foreach (\DateTimeZone::listIdentifiers() as $timezone) { foreach (\DateTimeZone::listIdentifiers() as $timezone) {
$parts = explode('/', $timezone); $parts = explode('/', $timezone);
if (count($parts) > 2) { if (count($parts) > 2) {
$region = $parts[0]; $region = $parts[0];
$name = $parts[1].' - '.$parts[2]; $name = $parts[1].' - '.$parts[2];
} elseif (count($parts) > 1) { } elseif (count($parts) > 1) {
$region = $parts[0]; $region = $parts[0];
$name = $parts[1]; $name = $parts[1];
} else { } else {
$region = 'Other'; $region = 'Other';
$name = $parts[0]; $name = $parts[0];
}
self::$timezones[$region][str_replace('_', ' ', $name)] = $timezone;
} }
$timezones[$region][str_replace('_', ' ', $name)] = $timezone;
} }
return self::$timezones; return $timezones;
} }
} }