浏览代码

[Form] Fixed: The data in a CollectionField is resized down if fields are removed

Bernhard Schussek 14 年之前
父节点
当前提交
e80aa9a5ab

+ 19 - 1
src/Symfony/Component/Form/CollectionField.php

@@ -25,6 +25,12 @@ class CollectionField extends FieldGroup
      */
     protected $prototype;
 
+    /**
+     * Remembers which fields were removed upon binding
+     * @var array
+     */
+    protected $removedFields = array();
+
     /**
      * Repeats the given field twice to verify the user's input
      *
@@ -72,6 +78,8 @@ class CollectionField extends FieldGroup
 
     public function bind($taintedData)
     {
+        $this->removedFields = array();
+
         if (null === $taintedData) {
             $taintedData = array();
         }
@@ -79,6 +87,7 @@ class CollectionField extends FieldGroup
         foreach ($this as $name => $field) {
             if (!isset($taintedData[$name]) && $this->getOption('modifiable') && $name != '$$key$$') {
                 $this->remove($name);
+                $this->removedFields[] = $name;
             }
         }
 
@@ -88,7 +97,16 @@ class CollectionField extends FieldGroup
             }
         }
 
-        return parent::bind($taintedData);
+        parent::bind($taintedData);
+    }
+
+    protected function updateObject(&$objectOrArray)
+    {
+        parent::updateObject($objectOrArray);
+
+        foreach ($this->removedFields as $name) {
+            unset($objectOrArray[$name]);
+        }
     }
 
     protected function newField($key, $propertyPath)

+ 16 - 1
tests/Symfony/Tests/Component/Form/CollectionFieldTest.php

@@ -109,7 +109,7 @@ class CollectionFieldTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals('foo@foo.com', $field[0]->getData());
     }
 
-    public function testResizedIfBoundWithExtraDataAndModifiable()
+    public function testResizedUpIfBoundWithExtraDataAndModifiable()
     {
         $field = new CollectionField(new TestField('emails'), array(
             'modifiable' => true,
@@ -121,5 +121,20 @@ class CollectionFieldTest extends \PHPUnit_Framework_TestCase
         $this->assertTrue($field->has('1'));
         $this->assertEquals('foo@foo.com', $field[0]->getData());
         $this->assertEquals('bar@bar.com', $field[1]->getData());
+        $this->assertEquals(array('foo@foo.com', 'bar@bar.com'), $field->getData());
+    }
+
+    public function testResizedDownIfBoundWithLessDataAndModifiable()
+    {
+        $field = new CollectionField(new TestField('emails'), array(
+            'modifiable' => true,
+        ));
+        $field->setData(array('foo@bar.com', 'bar@bar.com'));
+        $field->bind(array('foo@foo.com'));
+
+        $this->assertTrue($field->has('0'));
+        $this->assertFalse($field->has('1'));
+        $this->assertEquals('foo@foo.com', $field[0]->getData());
+        $this->assertEquals(array('foo@foo.com'), $field->getData());
     }
 }