bug #10269 [Form] Revert "Fix "Array was modified outside object" in ResizeFormListener." (norzechowicz)

This PR was merged into the 2.3 branch.

Discussion
----------

[Form] Revert "Fix "Array was modified outside object" in ResizeFormListener."

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #10256, #10263
| License       | MIT
| Doc PR        |

Unseting key on iterator is not an solution because in php "Array assignment always involves value copying. " So if \IteratorAggregate implementation create new iterator from array (just like [Doctrine ArrayCollection](https://github.com/doctrine/common/blob/2.3/lib/Doctrine/Common/Collections/ArrayCollection.php#L362) does)  such operation will not affect original data.

I'm just not sure if it's good to use Doctirn ArrayCollection in this test case or maybe its better to create own implementation of such Collection as a fixture.

Commits
-------

f62e30d Revert "Fix "Array was modified outside object" in ResizeFormListener."
462b7af Added failing test
This commit is contained in:
Fabien Potencier 2014-02-17 20:52:05 +01:00
commit c4ffe02100
2 changed files with 17 additions and 15 deletions

View File

@ -139,21 +139,9 @@ class ResizeFormListener implements EventSubscriberInterface
// The data mapper only adds, but does not remove items, so do this
// here
if ($this->allowDelete) {
if ($data instanceof \IteratorAggregate) {
$iter = $data->getIterator();
while ($iter->valid()) {
$name = $iter->key();
if ($form->has($name)) {
$iter->next();
} else {
$iter->offsetUnset($name);
}
}
} else {
foreach ($data as $name => $child) {
if (!$form->has($name)) {
unset($data[$name]);
}
foreach ($data as $name => $child) {
if (!$form->has($name)) {
unset($data[$name]);
}
}
}

View File

@ -11,6 +11,7 @@
namespace Symfony\Component\Form\Tests\Extension\Core\EventListener;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Form\Extension\Core\EventListener\ResizeFormListener;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormEvent;
@ -252,4 +253,17 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(array(), $event->getData());
}
public function testOnSubmitDealsWithIteratorAggregate()
{
$this->form->add($this->getForm('1'));
$data = new ArrayCollection(array(0 => 'first', 1 => 'second', 2 => 'third'));
$event = new FormEvent($this->form, $data);
$listener = new ResizeFormListener('text', array(), false, true);
$listener->onSubmit($event);
$this->assertArrayNotHasKey(0, $event->getData());
$this->assertArrayNotHasKey(2, $event->getData());
}
}