Pārlūkot izejas kodu

[Form] Made and parameter in the constructor optional

Bernhard Schussek 14 gadi atpakaļ
vecāks
revīzija
7c557d0d6e

+ 16 - 2
src/Symfony/Component/Form/Form.php

@@ -12,6 +12,7 @@ namespace Symfony\Component\Form;
  */
 
 use Symfony\Component\Validator\ValidatorInterface;
+use Symfony\Component\Form\Exception\FormException;
 
 /**
  * Form represents a form.
@@ -43,11 +44,14 @@ class Form extends FieldGroup
      * @param ValidatorInterface $validator
      * @param array $options
      */
-    public function __construct($name, $data, ValidatorInterface $validator, array $options = array())
+    public function __construct($name, $data = null, ValidatorInterface $validator = null, array $options = array())
     {
         $this->validator = $validator;
 
-        $this->setData($data);
+        // Prefill the form with the given data
+        if ($data !== null) {
+            $this->setData($data);
+        }
 
         if (FormConfiguration::isDefaultCsrfProtectionEnabled()) {
             $this->enableCsrfProtection();
@@ -58,6 +62,12 @@ class Form extends FieldGroup
         }
 
         parent::__construct($name, $options);
+
+        // If data is passed to this constructor, objects from parent forms
+        // should be ignored
+        if ($data !== null) {
+            $this->setPropertyPath(null);
+        }
     }
 
     /**
@@ -109,6 +119,10 @@ class Form extends FieldGroup
         $this->doBind(self::deepArrayUnion($taintedValues, $taintedFiles));
 
         if ($this->getParent() === null) {
+            if ($this->validator === null) {
+                throw new FormException('A validator is required for binding. Forgot to pass it to the constructor of the form?');
+            }
+
             if ($violations = $this->validator->validate($this, $this->getValidationGroups())) {
                 // TODO: test me
                 foreach ($violations as $violation) {

+ 63 - 0
tests/Symfony/Tests/Component/Form/FormTest.php

@@ -214,6 +214,18 @@ class FormTest extends \PHPUnit_Framework_TestCase
         $form->bind(array()); // irrelevant
     }
 
+    public function testBindThrowsExceptionIfNoValidatorIsSet()
+    {
+        $field = $this->createMockField('firstName');
+        $form = new Form('author', new Author());
+        $form->add($field);
+        $form->setValidationGroups('group');
+
+        $this->setExpectedException('Symfony\Component\Form\Exception\FormException');
+
+        $form->bind(array()); // irrelevant
+    }
+
     public function testMultipartFormsWithoutParentsRequireFiles()
     {
         $form = new Form('author', new Author(), $this->validator);
@@ -236,6 +248,57 @@ class FormTest extends \PHPUnit_Framework_TestCase
         $form->bind(array('file' => 'test.txt'));
     }
 
+    public function testUpdateFromPropertyIsIgnoredIfFormHasObject()
+    {
+        $author = new Author();
+        $author->child = new Author();
+        $standaloneChild = new Author();
+
+        $form = new Form('child', $standaloneChild);
+        $form->updateFromProperty($author);
+
+        // should not be $author->child!!
+        $this->assertSame($standaloneChild, $form->getData());
+    }
+
+    public function testUpdateFromPropertyIsNotIgnoredIfFormHasNoObject()
+    {
+        $author = new Author();
+        $author->child = new Author();
+
+        $form = new Form('child');
+        $form->updateFromProperty($author);
+
+        // should not be $author->child!!
+        $this->assertSame($author->child, $form->getData());
+    }
+
+    public function testUpdatePropertyIsIgnoredIfFormHasObject()
+    {
+        $author = new Author();
+        $author->child = $child = new Author();
+        $standaloneChild = new Author();
+
+        $form = new Form('child', $standaloneChild);
+        $form->updateProperty($author);
+
+        // $author->child was not modified
+        $this->assertSame($child, $author->child);
+    }
+
+    public function testUpdatePropertyIsNotIgnoredIfFormHasNoObject()
+    {
+        $author = new Author();
+        $child = new Author();
+
+        $form = new Form('child');
+        $form->setData($child);
+        $form->updateProperty($author);
+
+        // $author->child was set
+        $this->assertSame($child, $author->child);
+    }
+
     protected function createMockField($key)
     {
         $field = $this->getMock(