-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Form] added CallbackChoiceLoader
and refactored ChoiceType's children
#18332
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* 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; | ||
|
||
use Symfony\Component\Form\ChoiceList\ArrayChoiceList; | ||
|
||
/** | ||
* Loads an {@link ArrayChoiceList} instance from a callable returning an array of choices. | ||
* | ||
* @author Jules Pietri <jules@heahprod.com> | ||
*/ | ||
class CallbackChoiceLoader implements ChoiceLoaderInterface | ||
{ | ||
private $callback; | ||
|
||
/** | ||
* The loaded choice list. | ||
* | ||
* @var ArrayChoiceList | ||
*/ | ||
private $choiceList; | ||
|
||
/** | ||
* @param callable $callback The callable returning an array of choices | ||
*/ | ||
public function __construct(callable $callback) | ||
{ | ||
$this->callback = $callback; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function loadChoiceList($value = null) | ||
{ | ||
if (null !== $this->choiceList) { | ||
return $this->choiceList; | ||
} | ||
|
||
return $this->choiceList = new ArrayChoiceList(call_user_func($this->callback), $value); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function loadChoicesForValues(array $values, $value = null) | ||
{ | ||
// Optimize | ||
if (empty($values)) { | ||
return array(); | ||
} | ||
|
||
return $this->loadChoiceList($value)->getChoicesForValues($values); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function loadValuesForChoices(array $choices, $value = null) | ||
{ | ||
// Optimize | ||
if (empty($choices)) { | ||
return array(); | ||
} | ||
|
||
return $this->loadChoiceList($value)->getValuesForChoices($choices); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 @@ public function getBlockPrefix() | |
{ | ||
return 'country'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why did you add this? The block prefix is "country" by default. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should switch in split view :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't understand what you're trying to say. The default return value of that method is "country". This method seems superfluous to me. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I mean you might be looking at the diff "unified", and should try "split", because this method is not changed at all :) |
||
} | ||
|
||
/** | ||
* {@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); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please add documentation about what the callable is expected to return (namely an array of choices)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@HeahDude You seemed to agree, but I don't see any documentation here. Can you add a phpdoc? I would then remove the doc on the property above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fabpot Sorry, I don't understand where you want me to add and remove things.
Back then I had changed the first phpdoc from
The callable used to load the choices.
toThe callable used to load the array of choices.
thinking that both phpdocs would be less confusing.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I was not very clear. Let me try again. It would be better to add a phpdoc to the constructor:
and remove the one on the private property:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright, makes sense. I will do it very soon.