[Form] ChoiceField now accepts closures in the 'choices' option
This commit is contained in:
parent
9e6e95d7e4
commit
ce61baf717
@ -40,6 +40,13 @@ class ChoiceField extends HybridField
|
||||
*/
|
||||
protected $preferredChoices = array();
|
||||
|
||||
/**
|
||||
* Stores the choices
|
||||
* You should only access this property through getInitializedChoices()
|
||||
* @var array
|
||||
*/
|
||||
protected $initializedChoices = array();
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->addRequiredOption('choices');
|
||||
@ -47,8 +54,12 @@ class ChoiceField extends HybridField
|
||||
$this->addOption('multiple', false);
|
||||
$this->addOption('expanded', false);
|
||||
|
||||
if (!is_array($this->getOption('choices'))) {
|
||||
throw new InvalidOptionsException('The choices option must be an array', array('choices'));
|
||||
parent::configure();
|
||||
|
||||
$choices = $this->getOption('choices');
|
||||
|
||||
if (!is_array($choices) && !$choices instanceof \Closure) {
|
||||
throw new InvalidOptionsException('The choices option must be an array or a closure', array('choices'));
|
||||
}
|
||||
|
||||
if (!is_array($this->getOption('preferred_choices'))) {
|
||||
@ -62,7 +73,7 @@ class ChoiceField extends HybridField
|
||||
if ($this->isExpanded()) {
|
||||
$this->setFieldMode(self::GROUP);
|
||||
|
||||
$choices = $this->getOption('choices');
|
||||
$choices = $this->getInitializedChoices();
|
||||
|
||||
foreach ($this->preferredChoices as $choice => $_) {
|
||||
$this->add($this->newChoiceField($choice, $choices[$choice]));
|
||||
@ -76,8 +87,6 @@ class ChoiceField extends HybridField
|
||||
} else {
|
||||
$this->setFieldMode(self::FIELD);
|
||||
}
|
||||
|
||||
parent::configure();
|
||||
}
|
||||
|
||||
public function getName()
|
||||
@ -95,19 +104,52 @@ class ChoiceField extends HybridField
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the choices
|
||||
*
|
||||
* If the choices were given as a closure, the closure is executed now.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function initializeChoices()
|
||||
{
|
||||
$this->initializedChoices = $this->getOption('choices');
|
||||
|
||||
if ($this->initializedChoices instanceof \Closure) {
|
||||
$this->initializedChoices = $this->initializedChoices->__invoke();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the choices
|
||||
*
|
||||
* If the choices were given as a closure, the closure is executed on
|
||||
* the first call of this method.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getInitializedChoices()
|
||||
{
|
||||
if (!$this->initializedChoices) {
|
||||
$this->initializeChoices();
|
||||
}
|
||||
|
||||
return $this->initializedChoices;
|
||||
}
|
||||
|
||||
public function getPreferredChoices()
|
||||
{
|
||||
return array_intersect_key($this->getOption('choices'), $this->preferredChoices);
|
||||
return array_intersect_key($this->getInitializedChoices(), $this->preferredChoices);
|
||||
}
|
||||
|
||||
public function getOtherChoices()
|
||||
{
|
||||
return array_diff_key($this->getOption('choices'), $this->preferredChoices);
|
||||
return array_diff_key($this->getInitializedChoices(), $this->preferredChoices);
|
||||
}
|
||||
|
||||
public function getLabel($choice)
|
||||
{
|
||||
$choices = $this->getOption('choices');
|
||||
$choices = $this->getInitializedChoices();
|
||||
|
||||
return isset($choices[$choice]) ? $choices[$choice] : null;
|
||||
}
|
||||
@ -183,7 +225,7 @@ class ChoiceField extends HybridField
|
||||
{
|
||||
if ($this->isExpanded()) {
|
||||
$value = parent::transform($value);
|
||||
$choices = $this->getOption('choices');
|
||||
$choices = $this->getInitializedChoices();
|
||||
|
||||
foreach ($choices as $choice => $_) {
|
||||
$choices[$choice] = $this->isMultipleChoice()
|
||||
|
@ -67,12 +67,35 @@ class ChoiceFieldTest extends \PHPUnit_Framework_TestCase
|
||||
));
|
||||
}
|
||||
|
||||
public function testBindSingleNonExpanded()
|
||||
public function getChoicesVariants()
|
||||
{
|
||||
$choices = $this->choices;
|
||||
|
||||
return array(
|
||||
array($choices),
|
||||
array(function () use ($choices) { return $choices; }),
|
||||
);
|
||||
}
|
||||
|
||||
public function getNumericChoicesVariants()
|
||||
{
|
||||
$choices = $this->numericChoices;
|
||||
|
||||
return array(
|
||||
array($choices),
|
||||
array(function () use ($choices) { return $choices; }),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getChoicesVariants
|
||||
*/
|
||||
public function testBindSingleNonExpanded($choices)
|
||||
{
|
||||
$field = new ChoiceField('name', array(
|
||||
'multiple' => false,
|
||||
'expanded' => false,
|
||||
'choices' => $this->choices,
|
||||
'choices' => $choices,
|
||||
));
|
||||
|
||||
$field->bind('b');
|
||||
@ -81,12 +104,15 @@ class ChoiceFieldTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals('b', $field->getDisplayedData());
|
||||
}
|
||||
|
||||
public function testBindMultipleNonExpanded()
|
||||
/**
|
||||
* @dataProvider getChoicesVariants
|
||||
*/
|
||||
public function testBindMultipleNonExpanded($choices)
|
||||
{
|
||||
$field = new ChoiceField('name', array(
|
||||
'multiple' => true,
|
||||
'expanded' => false,
|
||||
'choices' => $this->choices,
|
||||
'choices' => $choices,
|
||||
));
|
||||
|
||||
$field->bind(array('a', 'b'));
|
||||
@ -95,12 +121,15 @@ class ChoiceFieldTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals(array('a', 'b'), $field->getDisplayedData());
|
||||
}
|
||||
|
||||
public function testBindSingleExpanded()
|
||||
/**
|
||||
* @dataProvider getChoicesVariants
|
||||
*/
|
||||
public function testBindSingleExpanded($choices)
|
||||
{
|
||||
$field = new ChoiceField('name', array(
|
||||
'multiple' => false,
|
||||
'expanded' => true,
|
||||
'choices' => $this->choices,
|
||||
'choices' => $choices,
|
||||
));
|
||||
|
||||
$field->bind('b');
|
||||
@ -119,12 +148,15 @@ class ChoiceFieldTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertSame(array('a' => '', 'b' => '1', 'c' => '', 'd' => '', 'e' => ''), $field->getDisplayedData());
|
||||
}
|
||||
|
||||
public function testBindSingleExpandedNumericChoices()
|
||||
/**
|
||||
* @dataProvider getNumericChoicesVariants
|
||||
*/
|
||||
public function testBindSingleExpandedNumericChoices($choices)
|
||||
{
|
||||
$field = new ChoiceField('name', array(
|
||||
'multiple' => false,
|
||||
'expanded' => true,
|
||||
'choices' => $this->numericChoices,
|
||||
'choices' => $choices,
|
||||
));
|
||||
|
||||
$field->bind('1');
|
||||
@ -143,12 +175,15 @@ class ChoiceFieldTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertSame(array(0 => '', 1 => '1', 2 => '', 3 => '', 4 => ''), $field->getDisplayedData());
|
||||
}
|
||||
|
||||
public function testBindMultipleExpanded()
|
||||
/**
|
||||
* @dataProvider getChoicesVariants
|
||||
*/
|
||||
public function testBindMultipleExpanded($choices)
|
||||
{
|
||||
$field = new ChoiceField('name', array(
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
'choices' => $this->choices,
|
||||
'choices' => $choices,
|
||||
));
|
||||
|
||||
$field->bind(array('a' => 'a', 'b' => 'b'));
|
||||
@ -167,12 +202,15 @@ class ChoiceFieldTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertSame(array('a' => '1', 'b' => '1', 'c' => '', 'd' => '', 'e' => ''), $field->getDisplayedData());
|
||||
}
|
||||
|
||||
public function testBindMultipleExpandedNumericChoices()
|
||||
/**
|
||||
* @dataProvider getNumericChoicesVariants
|
||||
*/
|
||||
public function testBindMultipleExpandedNumericChoices($choices)
|
||||
{
|
||||
$field = new ChoiceField('name', array(
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
'choices' => $this->numericChoices,
|
||||
'choices' => $choices,
|
||||
));
|
||||
|
||||
$field->bind(array(1 => 1, 2 => 2));
|
||||
|
Reference in New Issue
Block a user