diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml index dd6b841f3f..907d9bb0a8 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml @@ -21,7 +21,7 @@ @@ -148,6 +148,12 @@ + + + + + + diff --git a/src/Symfony/Component/Form/Extension/Core/Type/FieldType.php b/src/Symfony/Component/Form/Extension/Core/Type/FieldType.php index c6957e577d..c698d13f00 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/FieldType.php +++ b/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(); }; diff --git a/src/Symfony/Component/Form/Extension/Core/Type/FileType.php b/src/Symfony/Component/Form/Extension/Core/Type/FileType.php index eb3b8c8c79..e948da3c27 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/FileType.php +++ b/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'); diff --git a/src/Symfony/Component/Form/FormBuilder.php b/src/Symfony/Component/Form/FormBuilder.php index f5158b0925..c41415e0a0 100644 --- a/src/Symfony/Component/Form/FormBuilder.php +++ b/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(); diff --git a/src/Symfony/Component/Form/FormFactory.php b/src/Symfony/Component/Form/FormFactory.php index 7df19e501a..7127df3431 100644 --- a/src/Symfony/Component/Form/FormFactory.php +++ b/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; } diff --git a/src/Symfony/Component/HttpFoundation/File/Exception/FileNotFoundException.php b/src/Symfony/Component/HttpFoundation/File/Exception/FileNotFoundException.php index 60ba964745..946c1d50ab 100644 --- a/src/Symfony/Component/HttpFoundation/File/Exception/FileNotFoundException.php +++ b/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)); } } \ No newline at end of file diff --git a/src/Symfony/Component/HttpFoundation/File/TemporaryStorage.php b/src/Symfony/Component/HttpFoundation/File/TemporaryStorage.php index 71f931eb90..a583465022 100644 --- a/src/Symfony/Component/HttpFoundation/File/TemporaryStorage.php +++ b/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; } diff --git a/tests/Symfony/Tests/Component/Form/FormBuilderTest.php b/tests/Symfony/Tests/Component/Form/FormBuilderTest.php index 9c7349df87..e90f3e0383 100644 --- a/tests/Symfony/Tests/Component/Form/FormBuilderTest.php +++ b/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()