Преглед изворни кода

Merge remote branch 'bschussek/form'

* bschussek/form:
  [Form] Automatically setting "data_class" option if objects are passed at the creation of a form
  [Form] Improved the way passed data is handled in FormFactory
  [Form] Simplified FileType code
  [HttpFoundation] TemporaryStorage automatically creates the directory if it doesn't exist yet
  [Form] Changed FormBuilder::build() to FormBuilder::create(). You hvae to pass the resulting builder to FormBuilder::add() manually now
  [Form] Added FieldTypeValidatorExtension and fixed FQCN of DelegatingValidator
Fabien Potencier пре 14 година
родитељ
комит
2f3ddb88ef

+ 7 - 1
src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml

@@ -21,7 +21,7 @@
                 <!--
                 We don't need to be able to add more extensions.
                  * more types can be registered with the form.type tag
-                 * more type_guessers can be registered with the form.type.type_guesser tag 
+                 * more type_guessers can be registered with the form.type.type_guesser tag
                 -->
                 <argument type="service" id="form.extension" />
             </argument>
@@ -148,6 +148,12 @@
             <tag name="form.type" alias="url" />
         </service>
 
+        <!-- FieldTypeValidatorExtension -->
+        <service id="form.type_extension.field" class="Symfony\Component\Form\Extension\Validator\Type\FieldTypeValidatorExtension">
+            <tag name="form.type_extension" alias="field" />
+            <argument type="service" id="validator" />
+        </service>
+
         <!-- CsrfExtension -->
         <service id="form.type.csrf" class="Symfony\Component\Form\Extension\Csrf\Type\CsrfType">
             <tag name="form.type" alias="csrf" />

+ 9 - 2
src/Symfony/Component/Form/Extension/Core/Type/FieldType.php

@@ -101,8 +101,15 @@ class FieldType extends AbstractType
             'label' => null,
         );
 
-        if (!empty($options['data_class'])) {
-            $class = $options['data_class'];
+        $class = isset($options['data_class']) ? $options['data_class'] : null;
+
+        // If no data class is set explicitely and an object is passed as data,
+        // use the class of that object as data class
+        if (!$class && isset($options['data']) && is_object($options['data'])) {
+            $defaultOptions['data_class'] = $class = get_class($options['data']);
+        }
+
+        if ($class) {
             $defaultOptions['empty_data'] = function () use ($class) {
                 return new $class();
             };

+ 6 - 7
src/Symfony/Component/Form/Extension/Core/Type/FileType.php

@@ -35,15 +35,14 @@ class FileType extends AbstractType
     public function buildForm(FormBuilder $builder, array $options)
     {
         if ($options['type'] === 'string') {
-            $builder->appendNormTransformer(new DataTransformerChain(array(
-                new ReversedTransformer(new FileToStringTransformer()),
-                new FileToArrayTransformer(),
-            )));
-        } else {
-            $builder->appendNormTransformer(new FileToArrayTransformer());
+            $builder->appendNormTransformer(
+                new ReversedTransformer(new FileToStringTransformer())
+            );
         }
 
-        $builder->addEventSubscriber(new FixFileUploadListener($this->storage), 10)
+        $builder
+            ->appendNormTransformer(new FileToArrayTransformer())
+            ->addEventSubscriber(new FixFileUploadListener($this->storage), 10)
             ->add('file', 'field')
             ->add('token', 'hidden')
             ->add('name', 'hidden');

+ 17 - 39
src/Symfony/Component/Form/FormBuilder.php

@@ -40,8 +40,6 @@ class FormBuilder
 
     private $types = array();
 
-    private $parent;
-
     private $dataClass;
 
     private $children = array();
@@ -70,23 +68,6 @@ class FormBuilder
         return $this->name;
     }
 
-    public function setParent(FormBuilder $builder)
-    {
-        $this->parent = $builder;
-
-        return $this;
-    }
-
-    public function getParent()
-    {
-        return $this->parent;
-    }
-
-    public function end()
-    {
-        return $this->parent;
-    }
-
     public function setData($data)
     {
         $this->data = $data;
@@ -341,17 +322,23 @@ class FormBuilder
      * @param array                    $options
      * @return FormInterface
      */
-    public function add($name, $type = null, array $options = array())
+    public function add($child, $type = null, array $options = array())
     {
-        if (!is_string($name)) {
-            throw new UnexpectedTypeException($name, 'string');
+        if ($child instanceof self) {
+            $this->children[$child->getName()] = $child;
+
+            return $this;
+        }
+
+        if (!is_string($child)) {
+            throw new UnexpectedTypeException($child, 'string or Symfony\Component\Form\FormBuilder');
         }
 
         if (null !== $type && !is_string($type) && !$type instanceof FormTypeInterface) {
             throw new UnexpectedTypeException($type, 'string or Symfony\Component\Form\FormTypeInterface');
         }
 
-        $this->children[$name] = array(
+        $this->children[$child] = array(
             'type' => $type,
             'options' => $options,
         );
@@ -359,7 +346,7 @@ class FormBuilder
         return $this;
     }
 
-    public function build($name, $type = null, array $options = array())
+    public function create($name, $type = null, array $options = array())
     {
         if (null !== $type) {
             $builder = $this->getFormFactory()->createNamedBuilder(
@@ -381,10 +368,6 @@ class FormBuilder
             );
         }
 
-        $this->children[$name] = $builder;
-
-        $builder->setParent($this);
-
         return $builder;
     }
 
@@ -394,13 +377,13 @@ class FormBuilder
             throw new FormException(sprintf('The field "%s" does not exist', $name));
         }
 
-        $child = $this->children[$name];
-
-        if ($child instanceof FormBuilder) {
-            return $child;
+        if (!$this->children[$name] instanceof FormBuilder) {
+            $this->children[$name] = $this->create($name,
+                $this->children[$name]['type'],
+                $this->children[$name]['options']);
         }
 
-        return $this->build($name, $child['type'], $child['options']);
+        return $this->children[$name];
     }
 
     /**
@@ -411,11 +394,6 @@ class FormBuilder
     public function remove($name)
     {
         if (isset($this->children[$name])) {
-            // field might still be lazy
-            if ($this->children[$name] instanceof FormInterface) {
-                $this->children[$name]->setParent(null);
-            }
-
             unset($this->children[$name]);
         }
     }
@@ -442,7 +420,7 @@ class FormBuilder
 
         foreach ($this->children as $name => $builder) {
             if (!$builder instanceof FormBuilder) {
-                $builder = $this->build($name, $builder['type'], $builder['options']);
+                $builder = $this->create($name, $builder['type'], $builder['options']);
             }
 
             $children[$builder->getName()] = $builder->getForm();

+ 4 - 4
src/Symfony/Component/Form/FormFactory.php

@@ -123,6 +123,10 @@ class FormFactory implements FormFactoryInterface
         $knownOptions = array();
         $passedOptions = array_keys($options);
 
+        if (!array_key_exists('data', $options)) {
+            $options['data'] = $data;
+        }
+
         while (null !== $type) {
             $type = $this->getType($type);
 
@@ -160,10 +164,6 @@ class FormFactory implements FormFactoryInterface
             }
         }
 
-        if (null !== $data) {
-            $builder->setData($data);
-        }
-
         return $builder;
     }
 

+ 1 - 1
src/Symfony/Component/HttpFoundation/File/Exception/FileNotFoundException.php

@@ -25,6 +25,6 @@ class FileNotFoundException extends FileException
      */
     public function __construct($path)
     {
-        parent::__construct(sprintf('The file %s does not exist', $path));
+        parent::__construct(sprintf('The file "%s" does not exist', $path));
     }
 }

+ 4 - 0
src/Symfony/Component/HttpFoundation/File/TemporaryStorage.php

@@ -24,6 +24,10 @@ class TemporaryStorage
 
     public function __construct($secret, $directory)
     {
+        if (!file_exists($directory)) {
+            mkdir($directory, 0777, true);
+        }
+
         $this->directory = realpath($directory);
         $this->secret = $secret;
     }

+ 2 - 2
tests/Symfony/Tests/Component/Form/FormBuilderTest.php

@@ -95,10 +95,10 @@ class FormBuilderTest extends \PHPUnit_Framework_TestCase
         $this->assertFalse($this->builder->has('foo'));
     }
 
-    public function testBuildNoTypeNoDataClass()
+    public function testCreateNoTypeNoDataClass()
     {
         $this->setExpectedException('Symfony\Component\Form\Exception\FormException', 'The data class must be set to automatically create children');
-        $this->builder->build('foo');
+        $this->builder->create('foo');
     }
 
     public function testGetUnknown()