[Form] Fixed expanded choice field to be marked invalid when unknown choices are submitted
This commit is contained in:
parent
30aa1de8dc
commit
ed837522af
@ -49,15 +49,11 @@ class BooleanToStringTransformer implements DataTransformerInterface
|
|||||||
*/
|
*/
|
||||||
public function transform($value)
|
public function transform($value)
|
||||||
{
|
{
|
||||||
if (null === $value) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_bool($value)) {
|
if (!is_bool($value)) {
|
||||||
throw new TransformationFailedException('Expected a Boolean.');
|
throw new TransformationFailedException('Expected a Boolean.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return true === $value ? $this->trueValue : null;
|
return $value ? $this->trueValue : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Form\Extension\Core\EventListener;
|
namespace Symfony\Component\Form\Extension\Core\EventListener;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\Exception\TransformationFailedException;
|
||||||
use Symfony\Component\Form\FormEvents;
|
use Symfony\Component\Form\FormEvents;
|
||||||
use Symfony\Component\Form\FormEvent;
|
use Symfony\Component\Form\FormEvent;
|
||||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||||
@ -38,10 +39,43 @@ class FixCheckboxInputListener implements EventSubscriberInterface
|
|||||||
|
|
||||||
public function preBind(FormEvent $event)
|
public function preBind(FormEvent $event)
|
||||||
{
|
{
|
||||||
$values = (array) $event->getData();
|
$data = $event->getData();
|
||||||
$indices = $this->choiceList->getIndicesForValues($values);
|
|
||||||
|
|
||||||
$event->setData(count($indices) > 0 ? array_combine($indices, $values) : array());
|
if (is_array($data)) {
|
||||||
|
// Flip the submitted values for faster lookup
|
||||||
|
// It's better to flip this array than $existingValues because
|
||||||
|
// $submittedValues is generally smaller.
|
||||||
|
$submittedValues = array_flip($data);
|
||||||
|
|
||||||
|
// Since expanded choice fields are completely loaded anyway, we
|
||||||
|
// can just as well get the values again without losing performance.
|
||||||
|
$existingValues = $this->choiceList->getValues();
|
||||||
|
|
||||||
|
// Clear the data array and fill it with correct indices
|
||||||
|
$data = array();
|
||||||
|
|
||||||
|
foreach ($existingValues as $index => $value) {
|
||||||
|
if (isset($submittedValues[$value])) {
|
||||||
|
// Value was submitted
|
||||||
|
$data[$index] = $value;
|
||||||
|
unset($submittedValues[$value]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($submittedValues) > 0) {
|
||||||
|
throw new TransformationFailedException(sprintf(
|
||||||
|
'The following choices were not found: "%s"',
|
||||||
|
implode('", "', array_keys($submittedValues))
|
||||||
|
));
|
||||||
|
}
|
||||||
|
} elseif ('' === $data || null === $data) {
|
||||||
|
// Empty values are always accepted.
|
||||||
|
$data = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Else leave the data unchanged to provoke an error during submission
|
||||||
|
|
||||||
|
$event->setData($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getSubscribedEvents()
|
public static function getSubscribedEvents()
|
||||||
|
@ -38,10 +38,22 @@ class FixRadioInputListener implements EventSubscriberInterface
|
|||||||
|
|
||||||
public function preBind(FormEvent $event)
|
public function preBind(FormEvent $event)
|
||||||
{
|
{
|
||||||
$value = $event->getData();
|
$data = $event->getData();
|
||||||
$index = current($this->choiceList->getIndicesForValues(array($value)));
|
|
||||||
|
|
||||||
$event->setData(false !== $index ? array($index => $value) : array());
|
// Since expanded choice fields are completely loaded anyway, we
|
||||||
|
// can just as well get the values again without losing performance.
|
||||||
|
$existingValues = $this->choiceList->getValues();
|
||||||
|
|
||||||
|
if (false !== ($index = array_search($data, $existingValues, true))) {
|
||||||
|
$data = array($index => $data);
|
||||||
|
} elseif ('' === $data || null === $data) {
|
||||||
|
// Empty values are always accepted.
|
||||||
|
$data = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Else leave the data unchanged to provoke an error during submission
|
||||||
|
|
||||||
|
$event->setData($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getSubscribedEvents()
|
public static function getSubscribedEvents()
|
||||||
|
@ -25,9 +25,14 @@ class CheckboxType extends AbstractType
|
|||||||
*/
|
*/
|
||||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
{
|
{
|
||||||
$builder
|
// Unlike in other types, where the data is NULL by default, it
|
||||||
->addViewTransformer(new BooleanToStringTransformer($options['value']))
|
// needs to be a Boolean here. setData(null) is not acceptable
|
||||||
;
|
// for checkboxes and radio buttons (unless a custom model
|
||||||
|
// transformer handles this case).
|
||||||
|
// We cannot solve this case via overriding the "data" option, because
|
||||||
|
// doing so also calls setDataLocked(true).
|
||||||
|
$builder->setData(isset($options['data']) ? $options['data'] : false);
|
||||||
|
$builder->addViewTransformer(new BooleanToStringTransformer($options['value']));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -46,8 +51,8 @@ class CheckboxType extends AbstractType
|
|||||||
*/
|
*/
|
||||||
public function setDefaultOptions(OptionsResolverInterface $resolver)
|
public function setDefaultOptions(OptionsResolverInterface $resolver)
|
||||||
{
|
{
|
||||||
$emptyData = function (FormInterface $form, $clientData) {
|
$emptyData = function (FormInterface $form, $viewData) {
|
||||||
return $clientData;
|
return $viewData;
|
||||||
};
|
};
|
||||||
|
|
||||||
$resolver->setDefaults(array(
|
$resolver->setDefaults(array(
|
||||||
|
@ -531,6 +531,11 @@ class Form implements \IteratorAggregate, FormInterface
|
|||||||
|
|
||||||
$dispatcher = $this->config->getEventDispatcher();
|
$dispatcher = $this->config->getEventDispatcher();
|
||||||
|
|
||||||
|
$modelData = null;
|
||||||
|
$normData = null;
|
||||||
|
$viewData = null;
|
||||||
|
|
||||||
|
try {
|
||||||
// Hook to change content of the data bound by the browser
|
// Hook to change content of the data bound by the browser
|
||||||
if ($dispatcher->hasListeners(FormEvents::PRE_BIND) || $dispatcher->hasListeners(FormEvents::BIND_CLIENT_DATA)) {
|
if ($dispatcher->hasListeners(FormEvents::PRE_BIND) || $dispatcher->hasListeners(FormEvents::BIND_CLIENT_DATA)) {
|
||||||
$event = new FormEvent($this, $submittedData);
|
$event = new FormEvent($this, $submittedData);
|
||||||
@ -548,10 +553,14 @@ class Form implements \IteratorAggregate, FormInterface
|
|||||||
// since forms without children may also be compound.
|
// since forms without children may also be compound.
|
||||||
// (think of empty collection forms)
|
// (think of empty collection forms)
|
||||||
if ($this->config->getCompound()) {
|
if ($this->config->getCompound()) {
|
||||||
if (!is_array($submittedData)) {
|
if (null === $submittedData) {
|
||||||
$submittedData = array();
|
$submittedData = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!is_array($submittedData)) {
|
||||||
|
throw new TransformationFailedException('Compound forms expect an array or NULL on submission.');
|
||||||
|
}
|
||||||
|
|
||||||
for (reset($this->children); false !== current($this->children); next($this->children)) {
|
for (reset($this->children); false !== current($this->children); next($this->children)) {
|
||||||
$child = current($this->children);
|
$child = current($this->children);
|
||||||
$name = key($this->children);
|
$name = key($this->children);
|
||||||
@ -589,10 +598,6 @@ class Form implements \IteratorAggregate, FormInterface
|
|||||||
$this->config->getDataMapper()->mapFormsToData($this->children, $viewData);
|
$this->config->getDataMapper()->mapFormsToData($this->children, $viewData);
|
||||||
}
|
}
|
||||||
|
|
||||||
$modelData = null;
|
|
||||||
$normData = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Normalize data to unified representation
|
// Normalize data to unified representation
|
||||||
$normData = $this->viewToNorm($viewData);
|
$normData = $this->viewToNorm($viewData);
|
||||||
|
|
||||||
@ -614,6 +619,12 @@ class Form implements \IteratorAggregate, FormInterface
|
|||||||
$viewData = $this->normToView($normData);
|
$viewData = $this->normToView($normData);
|
||||||
} catch (TransformationFailedException $e) {
|
} catch (TransformationFailedException $e) {
|
||||||
$this->synchronized = false;
|
$this->synchronized = false;
|
||||||
|
|
||||||
|
// If $viewData was not yet set, set it to $submittedData so that
|
||||||
|
// the erroneous data is accessible on the form.
|
||||||
|
if (null === $viewData) {
|
||||||
|
$viewData = $submittedData;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->bound = true;
|
$this->bound = true;
|
||||||
|
@ -17,6 +17,9 @@ class BooleanToStringTransformerTest extends \PHPUnit_Framework_TestCase
|
|||||||
{
|
{
|
||||||
const TRUE_VALUE = '1';
|
const TRUE_VALUE = '1';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var BooleanToStringTransformer
|
||||||
|
*/
|
||||||
protected $transformer;
|
protected $transformer;
|
||||||
|
|
||||||
protected function setUp()
|
protected function setUp()
|
||||||
@ -33,20 +36,29 @@ class BooleanToStringTransformerTest extends \PHPUnit_Framework_TestCase
|
|||||||
{
|
{
|
||||||
$this->assertEquals(self::TRUE_VALUE, $this->transformer->transform(true));
|
$this->assertEquals(self::TRUE_VALUE, $this->transformer->transform(true));
|
||||||
$this->assertNull($this->transformer->transform(false));
|
$this->assertNull($this->transformer->transform(false));
|
||||||
$this->assertNull($this->transformer->transform(null));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testTransformExpectsBoolean()
|
/**
|
||||||
|
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
|
||||||
|
*/
|
||||||
|
public function testTransformFailsIfNull()
|
||||||
{
|
{
|
||||||
$this->setExpectedException('Symfony\Component\Form\Exception\TransformationFailedException');
|
$this->transformer->transform(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
|
||||||
|
*/
|
||||||
|
public function testTransformFailsIfString()
|
||||||
|
{
|
||||||
$this->transformer->transform('1');
|
$this->transformer->transform('1');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testReverseTransformExpectsString()
|
/**
|
||||||
|
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
|
||||||
|
*/
|
||||||
|
public function testReverseTransformFailsIfInteger()
|
||||||
{
|
{
|
||||||
$this->setExpectedException('Symfony\Component\Form\Exception\TransformationFailedException');
|
|
||||||
|
|
||||||
$this->transformer->reverseTransform(1);
|
$this->transformer->reverseTransform(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,15 @@ use Symfony\Component\Form\CallbackTransformer;
|
|||||||
|
|
||||||
class CheckboxTypeTest extends TypeTestCase
|
class CheckboxTypeTest extends TypeTestCase
|
||||||
{
|
{
|
||||||
|
public function testDataIsFalseByDefault()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create('checkbox');
|
||||||
|
|
||||||
|
$this->assertFalse($form->getData());
|
||||||
|
$this->assertFalse($form->getNormData());
|
||||||
|
$this->assertNull($form->getViewData());
|
||||||
|
}
|
||||||
|
|
||||||
public function testPassValueToView()
|
public function testPassValueToView()
|
||||||
{
|
{
|
||||||
$form = $this->factory->create('checkbox', null, array('value' => 'foobar'));
|
$form = $this->factory->create('checkbox', null, array('value' => 'foobar'));
|
||||||
@ -106,35 +115,37 @@ class CheckboxTypeTest extends TypeTestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider provideTransformedData
|
* @dataProvider provideCustomModelTransformerData
|
||||||
*/
|
*/
|
||||||
public function testTransformedData($data, $expected)
|
public function testCustomModelTransformer($data, $checked)
|
||||||
{
|
{
|
||||||
// present a binary status field as a checkbox
|
// present a binary status field as a checkbox
|
||||||
$transformer = new CallbackTransformer(
|
$transformer = new CallbackTransformer(
|
||||||
function ($value) {
|
function ($value) {
|
||||||
return 'expedited' == $value;
|
return 'checked' == $value;
|
||||||
},
|
},
|
||||||
function ($value) {
|
function ($value) {
|
||||||
return $value ? 'expedited' : 'standard';
|
return $value ? 'checked' : 'unchecked';
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
$form = $this->builder
|
$form = $this->factory->createBuilder('checkbox')
|
||||||
->create('expedited_shipping', 'checkbox')
|
|
||||||
->addModelTransformer($transformer)
|
->addModelTransformer($transformer)
|
||||||
->getForm();
|
->getForm();
|
||||||
|
|
||||||
$form->setData($data);
|
$form->setData($data);
|
||||||
$view = $form->createView();
|
$view = $form->createView();
|
||||||
|
|
||||||
$this->assertEquals($expected, $view->vars['checked']);
|
$this->assertSame($data, $form->getData());
|
||||||
|
$this->assertSame($checked, $form->getNormData());
|
||||||
|
$this->assertEquals($checked, $view->vars['checked']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideTransformedData()
|
public function provideCustomModelTransformerData()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
array('expedited', true),
|
array('checked', true),
|
||||||
array('standard', false),
|
array('unchecked', false),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,6 +177,21 @@ class ChoiceTypeTest extends TypeTestCase
|
|||||||
$this->assertEquals('b', $form->getViewData());
|
$this->assertEquals('b', $form->getViewData());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testBindSingleNonExpandedInvalidChoice()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create('choice', null, array(
|
||||||
|
'multiple' => false,
|
||||||
|
'expanded' => false,
|
||||||
|
'choices' => $this->choices,
|
||||||
|
));
|
||||||
|
|
||||||
|
$form->bind('foobar');
|
||||||
|
|
||||||
|
$this->assertNull($form->getData());
|
||||||
|
$this->assertEquals('foobar', $form->getViewData());
|
||||||
|
$this->assertFalse($form->isSynchronized());
|
||||||
|
}
|
||||||
|
|
||||||
public function testBindSingleNonExpandedObjectChoices()
|
public function testBindSingleNonExpandedObjectChoices()
|
||||||
{
|
{
|
||||||
$form = $this->factory->create('choice', null, array(
|
$form = $this->factory->create('choice', null, array(
|
||||||
@ -214,6 +229,36 @@ class ChoiceTypeTest extends TypeTestCase
|
|||||||
$this->assertEquals(array('a', 'b'), $form->getViewData());
|
$this->assertEquals(array('a', 'b'), $form->getViewData());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testBindMultipleNonExpandedInvalidScalarChoice()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create('choice', null, array(
|
||||||
|
'multiple' => true,
|
||||||
|
'expanded' => false,
|
||||||
|
'choices' => $this->choices,
|
||||||
|
));
|
||||||
|
|
||||||
|
$form->bind('foobar');
|
||||||
|
|
||||||
|
$this->assertNull($form->getData());
|
||||||
|
$this->assertEquals('foobar', $form->getViewData());
|
||||||
|
$this->assertFalse($form->isSynchronized());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testBindMultipleNonExpandedInvalidArrayChoice()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create('choice', null, array(
|
||||||
|
'multiple' => true,
|
||||||
|
'expanded' => false,
|
||||||
|
'choices' => $this->choices,
|
||||||
|
));
|
||||||
|
|
||||||
|
$form->bind(array('a', 'foobar'));
|
||||||
|
|
||||||
|
$this->assertNull($form->getData());
|
||||||
|
$this->assertEquals(array('a', 'foobar'), $form->getViewData());
|
||||||
|
$this->assertFalse($form->isSynchronized());
|
||||||
|
}
|
||||||
|
|
||||||
public function testBindMultipleNonExpandedObjectChoices()
|
public function testBindMultipleNonExpandedObjectChoices()
|
||||||
{
|
{
|
||||||
$form = $this->factory->create('choice', null, array(
|
$form = $this->factory->create('choice', null, array(
|
||||||
@ -236,17 +281,28 @@ class ChoiceTypeTest extends TypeTestCase
|
|||||||
$this->assertEquals(array('2', '3'), $form->getViewData());
|
$this->assertEquals(array('2', '3'), $form->getViewData());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testBindSingleExpanded()
|
public function testBindSingleExpandedRequired()
|
||||||
{
|
{
|
||||||
$form = $this->factory->create('choice', null, array(
|
$form = $this->factory->create('choice', null, array(
|
||||||
'multiple' => false,
|
'multiple' => false,
|
||||||
'expanded' => true,
|
'expanded' => true,
|
||||||
|
'required' => true,
|
||||||
'choices' => $this->choices,
|
'choices' => $this->choices,
|
||||||
));
|
));
|
||||||
|
|
||||||
$form->bind('b');
|
$form->bind('b');
|
||||||
|
|
||||||
$this->assertSame('b', $form->getData());
|
$this->assertSame('b', $form->getData());
|
||||||
|
$this->assertSame(array(
|
||||||
|
0 => false,
|
||||||
|
1 => true,
|
||||||
|
2 => false,
|
||||||
|
3 => false,
|
||||||
|
4 => false,
|
||||||
|
), $form->getViewData());
|
||||||
|
$this->assertEmpty($form->getExtraData());
|
||||||
|
$this->assertTrue($form->isSynchronized());
|
||||||
|
|
||||||
$this->assertFalse($form[0]->getData());
|
$this->assertFalse($form[0]->getData());
|
||||||
$this->assertTrue($form[1]->getData());
|
$this->assertTrue($form[1]->getData());
|
||||||
$this->assertFalse($form[2]->getData());
|
$this->assertFalse($form[2]->getData());
|
||||||
@ -259,17 +315,22 @@ class ChoiceTypeTest extends TypeTestCase
|
|||||||
$this->assertNull($form[4]->getViewData());
|
$this->assertNull($form[4]->getViewData());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testBindSingleExpandedNothingChecked()
|
public function testBindSingleExpandedRequiredInvalidChoice()
|
||||||
{
|
{
|
||||||
$form = $this->factory->create('choice', null, array(
|
$form = $this->factory->create('choice', null, array(
|
||||||
'multiple' => false,
|
'multiple' => false,
|
||||||
'expanded' => true,
|
'expanded' => true,
|
||||||
|
'required' => true,
|
||||||
'choices' => $this->choices,
|
'choices' => $this->choices,
|
||||||
));
|
));
|
||||||
|
|
||||||
$form->bind(null);
|
$form->bind('foobar');
|
||||||
|
|
||||||
|
$this->assertSame(null, $form->getData());
|
||||||
|
$this->assertSame('foobar', $form->getViewData());
|
||||||
|
$this->assertEmpty($form->getExtraData());
|
||||||
|
$this->assertFalse($form->isSynchronized());
|
||||||
|
|
||||||
$this->assertNull($form->getData());
|
|
||||||
$this->assertFalse($form[0]->getData());
|
$this->assertFalse($form[0]->getData());
|
||||||
$this->assertFalse($form[1]->getData());
|
$this->assertFalse($form[1]->getData());
|
||||||
$this->assertFalse($form[2]->getData());
|
$this->assertFalse($form[2]->getData());
|
||||||
@ -282,7 +343,7 @@ class ChoiceTypeTest extends TypeTestCase
|
|||||||
$this->assertNull($form[4]->getViewData());
|
$this->assertNull($form[4]->getViewData());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testBindSingleExpandedWithFalseDoesNotHaveExtraChildren()
|
public function testBindSingleExpandedNonRequired()
|
||||||
{
|
{
|
||||||
$form = $this->factory->create('choice', null, array(
|
$form = $this->factory->create('choice', null, array(
|
||||||
'multiple' => false,
|
'multiple' => false,
|
||||||
@ -290,10 +351,259 @@ class ChoiceTypeTest extends TypeTestCase
|
|||||||
'choices' => $this->choices,
|
'choices' => $this->choices,
|
||||||
));
|
));
|
||||||
|
|
||||||
|
$form->bind('b');
|
||||||
|
|
||||||
|
$this->assertSame('b', $form->getData());
|
||||||
|
$this->assertSame(array(
|
||||||
|
0 => false,
|
||||||
|
1 => true,
|
||||||
|
2 => false,
|
||||||
|
3 => false,
|
||||||
|
4 => false,
|
||||||
|
), $form->getViewData());
|
||||||
|
$this->assertEmpty($form->getExtraData());
|
||||||
|
$this->assertTrue($form->isSynchronized());
|
||||||
|
|
||||||
|
$this->assertFalse($form[0]->getData());
|
||||||
|
$this->assertTrue($form[1]->getData());
|
||||||
|
$this->assertFalse($form[2]->getData());
|
||||||
|
$this->assertFalse($form[3]->getData());
|
||||||
|
$this->assertFalse($form[4]->getData());
|
||||||
|
$this->assertNull($form[0]->getViewData());
|
||||||
|
$this->assertSame('b', $form[1]->getViewData());
|
||||||
|
$this->assertNull($form[2]->getViewData());
|
||||||
|
$this->assertNull($form[3]->getViewData());
|
||||||
|
$this->assertNull($form[4]->getViewData());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testBindSingleExpandedNonRequiredInvalidChoice()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create('choice', null, array(
|
||||||
|
'multiple' => false,
|
||||||
|
'expanded' => true,
|
||||||
|
'required' => false,
|
||||||
|
'choices' => $this->choices,
|
||||||
|
));
|
||||||
|
|
||||||
|
$form->bind('foobar');
|
||||||
|
|
||||||
|
$this->assertSame(null, $form->getData());
|
||||||
|
$this->assertSame('foobar', $form->getViewData());
|
||||||
|
$this->assertEmpty($form->getExtraData());
|
||||||
|
$this->assertFalse($form->isSynchronized());
|
||||||
|
|
||||||
|
$this->assertFalse($form[0]->getData());
|
||||||
|
$this->assertFalse($form[1]->getData());
|
||||||
|
$this->assertFalse($form[2]->getData());
|
||||||
|
$this->assertFalse($form[3]->getData());
|
||||||
|
$this->assertFalse($form[4]->getData());
|
||||||
|
$this->assertNull($form[0]->getViewData());
|
||||||
|
$this->assertNull($form[1]->getViewData());
|
||||||
|
$this->assertNull($form[2]->getViewData());
|
||||||
|
$this->assertNull($form[3]->getViewData());
|
||||||
|
$this->assertNull($form[4]->getViewData());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testBindSingleExpandedRequiredNull()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create('choice', null, array(
|
||||||
|
'multiple' => false,
|
||||||
|
'expanded' => true,
|
||||||
|
'choices' => $this->choices,
|
||||||
|
));
|
||||||
|
|
||||||
|
$form->bind(null);
|
||||||
|
|
||||||
|
$this->assertNull($form->getData());
|
||||||
|
$this->assertSame(array(
|
||||||
|
0 => false,
|
||||||
|
1 => false,
|
||||||
|
2 => false,
|
||||||
|
3 => false,
|
||||||
|
4 => false,
|
||||||
|
), $form->getViewData());
|
||||||
|
$this->assertEmpty($form->getExtraData());
|
||||||
|
$this->assertTrue($form->isSynchronized());
|
||||||
|
|
||||||
|
$this->assertFalse($form[0]->getData());
|
||||||
|
$this->assertFalse($form[1]->getData());
|
||||||
|
$this->assertFalse($form[2]->getData());
|
||||||
|
$this->assertFalse($form[3]->getData());
|
||||||
|
$this->assertFalse($form[4]->getData());
|
||||||
|
$this->assertNull($form[0]->getViewData());
|
||||||
|
$this->assertNull($form[1]->getViewData());
|
||||||
|
$this->assertNull($form[2]->getViewData());
|
||||||
|
$this->assertNull($form[3]->getViewData());
|
||||||
|
$this->assertNull($form[4]->getViewData());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testBindSingleExpandedRequiredEmpty()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create('choice', null, array(
|
||||||
|
'multiple' => false,
|
||||||
|
'expanded' => true,
|
||||||
|
'required' => true,
|
||||||
|
'choices' => $this->choices,
|
||||||
|
));
|
||||||
|
|
||||||
|
$form->bind('');
|
||||||
|
|
||||||
|
$this->assertNull($form->getData());
|
||||||
|
$this->assertSame(array(
|
||||||
|
0 => false,
|
||||||
|
1 => false,
|
||||||
|
2 => false,
|
||||||
|
3 => false,
|
||||||
|
4 => false,
|
||||||
|
), $form->getViewData());
|
||||||
|
$this->assertEmpty($form->getExtraData());
|
||||||
|
$this->assertTrue($form->isSynchronized());
|
||||||
|
|
||||||
|
$this->assertFalse($form[0]->getData());
|
||||||
|
$this->assertFalse($form[1]->getData());
|
||||||
|
$this->assertFalse($form[2]->getData());
|
||||||
|
$this->assertFalse($form[3]->getData());
|
||||||
|
$this->assertFalse($form[4]->getData());
|
||||||
|
$this->assertNull($form[0]->getViewData());
|
||||||
|
$this->assertNull($form[1]->getViewData());
|
||||||
|
$this->assertNull($form[2]->getViewData());
|
||||||
|
$this->assertNull($form[3]->getViewData());
|
||||||
|
$this->assertNull($form[4]->getViewData());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testBindSingleExpandedRequiredFalse()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create('choice', null, array(
|
||||||
|
'multiple' => false,
|
||||||
|
'expanded' => true,
|
||||||
|
'required' => true,
|
||||||
|
'choices' => $this->choices,
|
||||||
|
));
|
||||||
|
|
||||||
$form->bind(false);
|
$form->bind(false);
|
||||||
|
|
||||||
$this->assertEmpty($form->getExtraData());
|
|
||||||
$this->assertNull($form->getData());
|
$this->assertNull($form->getData());
|
||||||
|
$this->assertSame(array(
|
||||||
|
0 => false,
|
||||||
|
1 => false,
|
||||||
|
2 => false,
|
||||||
|
3 => false,
|
||||||
|
4 => false,
|
||||||
|
), $form->getViewData());
|
||||||
|
$this->assertEmpty($form->getExtraData());
|
||||||
|
$this->assertTrue($form->isSynchronized());
|
||||||
|
|
||||||
|
$this->assertFalse($form[0]->getData());
|
||||||
|
$this->assertFalse($form[1]->getData());
|
||||||
|
$this->assertFalse($form[2]->getData());
|
||||||
|
$this->assertFalse($form[3]->getData());
|
||||||
|
$this->assertFalse($form[4]->getData());
|
||||||
|
$this->assertNull($form[0]->getViewData());
|
||||||
|
$this->assertNull($form[1]->getViewData());
|
||||||
|
$this->assertNull($form[2]->getViewData());
|
||||||
|
$this->assertNull($form[3]->getViewData());
|
||||||
|
$this->assertNull($form[4]->getViewData());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testBindSingleExpandedNonRequiredNull()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create('choice', null, array(
|
||||||
|
'multiple' => false,
|
||||||
|
'expanded' => true,
|
||||||
|
'choices' => $this->choices,
|
||||||
|
));
|
||||||
|
|
||||||
|
$form->bind(null);
|
||||||
|
|
||||||
|
$this->assertNull($form->getData());
|
||||||
|
$this->assertSame(array(
|
||||||
|
0 => false,
|
||||||
|
1 => false,
|
||||||
|
2 => false,
|
||||||
|
3 => false,
|
||||||
|
4 => false,
|
||||||
|
), $form->getViewData());
|
||||||
|
$this->assertEmpty($form->getExtraData());
|
||||||
|
$this->assertTrue($form->isSynchronized());
|
||||||
|
|
||||||
|
$this->assertFalse($form[0]->getData());
|
||||||
|
$this->assertFalse($form[1]->getData());
|
||||||
|
$this->assertFalse($form[2]->getData());
|
||||||
|
$this->assertFalse($form[3]->getData());
|
||||||
|
$this->assertFalse($form[4]->getData());
|
||||||
|
$this->assertNull($form[0]->getViewData());
|
||||||
|
$this->assertNull($form[1]->getViewData());
|
||||||
|
$this->assertNull($form[2]->getViewData());
|
||||||
|
$this->assertNull($form[3]->getViewData());
|
||||||
|
$this->assertNull($form[4]->getViewData());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testBindSingleExpandedNonRequiredEmpty()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create('choice', null, array(
|
||||||
|
'multiple' => false,
|
||||||
|
'expanded' => true,
|
||||||
|
'required' => false,
|
||||||
|
'choices' => $this->choices,
|
||||||
|
));
|
||||||
|
|
||||||
|
$form->bind('');
|
||||||
|
|
||||||
|
$this->assertNull($form->getData());
|
||||||
|
$this->assertSame(array(
|
||||||
|
0 => false,
|
||||||
|
1 => false,
|
||||||
|
2 => false,
|
||||||
|
3 => false,
|
||||||
|
4 => false,
|
||||||
|
), $form->getViewData());
|
||||||
|
$this->assertEmpty($form->getExtraData());
|
||||||
|
$this->assertTrue($form->isSynchronized());
|
||||||
|
|
||||||
|
$this->assertFalse($form[0]->getData());
|
||||||
|
$this->assertFalse($form[1]->getData());
|
||||||
|
$this->assertFalse($form[2]->getData());
|
||||||
|
$this->assertFalse($form[3]->getData());
|
||||||
|
$this->assertFalse($form[4]->getData());
|
||||||
|
$this->assertNull($form[0]->getViewData());
|
||||||
|
$this->assertNull($form[1]->getViewData());
|
||||||
|
$this->assertNull($form[2]->getViewData());
|
||||||
|
$this->assertNull($form[3]->getViewData());
|
||||||
|
$this->assertNull($form[4]->getViewData());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testBindSingleExpandedNonRequiredFalse()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create('choice', null, array(
|
||||||
|
'multiple' => false,
|
||||||
|
'expanded' => true,
|
||||||
|
'required' => false,
|
||||||
|
'choices' => $this->choices,
|
||||||
|
));
|
||||||
|
|
||||||
|
$form->bind(false);
|
||||||
|
|
||||||
|
$this->assertNull($form->getData());
|
||||||
|
$this->assertSame(array(
|
||||||
|
0 => false,
|
||||||
|
1 => false,
|
||||||
|
2 => false,
|
||||||
|
3 => false,
|
||||||
|
4 => false,
|
||||||
|
), $form->getViewData());
|
||||||
|
$this->assertEmpty($form->getExtraData());
|
||||||
|
$this->assertTrue($form->isSynchronized());
|
||||||
|
|
||||||
|
$this->assertFalse($form[0]->getData());
|
||||||
|
$this->assertFalse($form[1]->getData());
|
||||||
|
$this->assertFalse($form[2]->getData());
|
||||||
|
$this->assertFalse($form[3]->getData());
|
||||||
|
$this->assertFalse($form[4]->getData());
|
||||||
|
$this->assertNull($form[0]->getViewData());
|
||||||
|
$this->assertNull($form[1]->getViewData());
|
||||||
|
$this->assertNull($form[2]->getViewData());
|
||||||
|
$this->assertNull($form[3]->getViewData());
|
||||||
|
$this->assertNull($form[4]->getViewData());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testBindSingleExpandedWithEmptyChild()
|
public function testBindSingleExpandedWithEmptyChild()
|
||||||
@ -381,6 +691,16 @@ class ChoiceTypeTest extends TypeTestCase
|
|||||||
$form->bind(array('a', 'c'));
|
$form->bind(array('a', 'c'));
|
||||||
|
|
||||||
$this->assertSame(array('a', 'c'), $form->getData());
|
$this->assertSame(array('a', 'c'), $form->getData());
|
||||||
|
$this->assertSame(array(
|
||||||
|
0 => true,
|
||||||
|
1 => false,
|
||||||
|
2 => true,
|
||||||
|
3 => false,
|
||||||
|
4 => false,
|
||||||
|
), $form->getViewData());
|
||||||
|
$this->assertEmpty($form->getExtraData());
|
||||||
|
$this->assertTrue($form->isSynchronized());
|
||||||
|
|
||||||
$this->assertTrue($form[0]->getData());
|
$this->assertTrue($form[0]->getData());
|
||||||
$this->assertFalse($form[1]->getData());
|
$this->assertFalse($form[1]->getData());
|
||||||
$this->assertTrue($form[2]->getData());
|
$this->assertTrue($form[2]->getData());
|
||||||
@ -393,6 +713,60 @@ class ChoiceTypeTest extends TypeTestCase
|
|||||||
$this->assertNull($form[4]->getViewData());
|
$this->assertNull($form[4]->getViewData());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testBindMultipleExpandedInvalidScalarChoice()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create('choice', null, array(
|
||||||
|
'multiple' => true,
|
||||||
|
'expanded' => true,
|
||||||
|
'choices' => $this->choices,
|
||||||
|
));
|
||||||
|
|
||||||
|
$form->bind('foobar');
|
||||||
|
|
||||||
|
$this->assertNull($form->getData());
|
||||||
|
$this->assertSame('foobar', $form->getViewData());
|
||||||
|
$this->assertEmpty($form->getExtraData());
|
||||||
|
$this->assertFalse($form->isSynchronized());
|
||||||
|
|
||||||
|
$this->assertFalse($form[0]->getData());
|
||||||
|
$this->assertFalse($form[1]->getData());
|
||||||
|
$this->assertFalse($form[2]->getData());
|
||||||
|
$this->assertFalse($form[3]->getData());
|
||||||
|
$this->assertFalse($form[4]->getData());
|
||||||
|
$this->assertNull($form[0]->getViewData());
|
||||||
|
$this->assertNull($form[1]->getViewData());
|
||||||
|
$this->assertNull($form[2]->getViewData());
|
||||||
|
$this->assertNull($form[3]->getViewData());
|
||||||
|
$this->assertNull($form[4]->getViewData());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testBindMultipleExpandedInvalidArrayChoice()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create('choice', null, array(
|
||||||
|
'multiple' => true,
|
||||||
|
'expanded' => true,
|
||||||
|
'choices' => $this->choices,
|
||||||
|
));
|
||||||
|
|
||||||
|
$form->bind(array('a', 'foobar'));
|
||||||
|
|
||||||
|
$this->assertNull($form->getData());
|
||||||
|
$this->assertSame(array('a', 'foobar'), $form->getViewData());
|
||||||
|
$this->assertEmpty($form->getExtraData());
|
||||||
|
$this->assertFalse($form->isSynchronized());
|
||||||
|
|
||||||
|
$this->assertFalse($form[0]->getData());
|
||||||
|
$this->assertFalse($form[1]->getData());
|
||||||
|
$this->assertFalse($form[2]->getData());
|
||||||
|
$this->assertFalse($form[3]->getData());
|
||||||
|
$this->assertFalse($form[4]->getData());
|
||||||
|
$this->assertNull($form[0]->getViewData());
|
||||||
|
$this->assertNull($form[1]->getViewData());
|
||||||
|
$this->assertNull($form[2]->getViewData());
|
||||||
|
$this->assertNull($form[3]->getViewData());
|
||||||
|
$this->assertNull($form[4]->getViewData());
|
||||||
|
}
|
||||||
|
|
||||||
public function testBindMultipleExpandedEmpty()
|
public function testBindMultipleExpandedEmpty()
|
||||||
{
|
{
|
||||||
$form = $this->factory->create('choice', null, array(
|
$form = $this->factory->create('choice', null, array(
|
||||||
|
Reference in New Issue
Block a user