Przeglądaj źródła

[Form] Fixed: empty objects are only created upon binding forms with empty data

Bernhard Schussek 14 lat temu
rodzic
commit
cfaa03eeec

+ 9 - 8
src/Symfony/Component/Form/Form.php

@@ -257,14 +257,6 @@ class Form implements \IteratorAggregate, FormInterface
 
         // Fix data if empty
         if (!$this->clientTransformer) {
-            if (null === $appData && !$this->normTransformer) {
-                $appData = $this->emptyData;
-
-                if ($appData instanceof \Closure) {
-                    $appData = $appData->__invoke();
-                }
-            }
-
             // Treat data as strings unless a value transformer exists
             if (is_scalar($appData)) {
                 $appData = (string)$appData;
@@ -346,6 +338,15 @@ class Form implements \IteratorAggregate, FormInterface
             if ($this->dataMapper) {
                 $clientData = $this->getClientData();
 
+                // Create new structure to write the values into
+                if (null === $clientData || '' === $clientData) {
+                    $clientData = $this->emptyData;
+
+                    if ($clientData instanceof \Closure) {
+                        $clientData = $clientData->__invoke();
+                    }
+                }
+
                 $this->dataMapper->mapFormsToData($this->children, $clientData);
             }
         }

+ 21 - 10
tests/Symfony/Tests/Component/Form/Type/FormTypeTest.php

@@ -376,51 +376,62 @@ class FormTypeTest extends TestCase
         $form->setData(new Author());
     }
 
-    public function testSetDataToNullCreatesObjectIfClassAvailable()
+    public function testBindWithEmptyDataCreatesObjectIfClassAvailable()
     {
         $form = $this->factory->create('form', 'author', array(
             'data_class' => 'Symfony\Tests\Component\Form\Fixtures\Author',
         ));
+        $form->add($this->factory->create('field', 'firstName'));
 
-        $form->setData(null);
+        $form->bind(array('firstName' => 'Bernhard'));
+
+        $author = new Author();
+        $author->firstName = 'Bernhard';
 
-        $this->assertEquals(new Author(), $form->getData());
+        $this->assertEquals($author, $form->getData());
     }
 
     /*
      * We need something to write the field values into
      */
-    public function testSetDataToNullStoresArrayIfNoClassAvailable()
+    public function testBindWithEmptyDataStoresArrayIfNoClassAvailable()
     {
         $form = $this->factory->create('form', 'author');
+        $form->add($this->factory->create('field', 'firstName'));
 
-        $form->setData(null);
+        $form->bind(array('firstName' => 'Bernhard'));
 
-        $this->assertSame(array(), $form->getData());
+        $this->assertSame(array('firstName' => 'Bernhard'), $form->getData());
     }
 
-    public function testSetDataToNullUsesEmptyData()
+    public function testBindWithEmptyDataUsesEmptyData()
     {
         $author = new Author();
+
         $form = $this->factory->create('form', 'author', array(
             'empty_data' => $author,
         ));
+        $form->add($this->factory->create('field', 'firstName'));
 
-        $form->setData(null);
+        $form->bind(array('firstName' => 'Bernhard'));
 
         $this->assertSame($author, $form->getData());
+        $this->assertEquals('Bernhard', $author->firstName);
     }
 
-    public function testSetDataToNullAcceptsClosureEmptyData()
+    public function testBindWithEmptyDataAcceptsClosureEmptyData()
     {
         $author = new Author();
+
         $form = $this->factory->create('form', 'author', array(
             'empty_data' => function () use ($author) { return $author; },
         ));
+        $form->add($this->factory->create('field', 'firstName'));
 
-        $form->setData(null);
+        $form->bind(array('firstName' => 'Bernhard'));
 
         $this->assertSame($author, $form->getData());
+        $this->assertEquals('Bernhard', $author->firstName);
     }
 
     public function testSubmitUpdatesTransformedDataFromAllFields()