merged branch hason/formbuilder (PR #3249)

Commits
-------

7cecb4e [Form] added support for parent of FormBuilder

Discussion
----------

[Form] added support for parent of FormBuilder

Bug fix: no
Feature addition: yes
Backwards compatibility break: no
Symfony2 tests pass: yes
Fixes the following tickets: -
Todo: -

In some cases of building forms, it is good to know the attributes of the parent builder. In my case I want to automaticaly add the subscriber to the fields, whose parent builder has a concrete attribute.

Replace #2882
This commit is contained in:
Fabien Potencier 2012-02-02 10:13:41 +01:00
commit 569b6dbd13
5 changed files with 138 additions and 35 deletions

View File

@ -113,6 +113,12 @@ class FormBuilder
private $currentLoadingType;
/**
* The parent of this builder
* @var FormBuilder
*/
private $parent;
/**
* Constructor.
*
@ -532,6 +538,7 @@ class FormBuilder
public function add($child, $type = null, array $options = array())
{
if ($child instanceof self) {
$child->setParent($this);
$this->children[$child->getName()] = $child;
return $this;
@ -573,10 +580,10 @@ class FormBuilder
}
if (null !== $type) {
return $this->getFormFactory()->createNamedBuilder($type, $name, null, $options);
return $this->getFormFactory()->createNamedBuilder($type, $name, null, $options, $this);
}
return $this->getFormFactory()->createBuilderForProperty($this->dataClass, $name, null, $options);
return $this->getFormFactory()->createBuilderForProperty($this->dataClass, $name, null, $options, $this);
}
/**
@ -615,6 +622,9 @@ class FormBuilder
public function remove($name)
{
if (isset($this->children[$name])) {
if ($this->children[$name] instanceof self) {
$this->children[$name]->setParent(null);
}
unset($this->children[$name]);
}
@ -671,6 +681,30 @@ class FormBuilder
$this->currentLoadingType = $type;
}
/**
* Returns the parent builder.
*
* @return FormBuilder The parent builder
*/
public function getParent()
{
return $this->parent;
}
/**
* Sets the parent builder.
*
* @param FormBuilder $parent The parent builder
*
* @return FormBuilder The current builder
*/
public function setParent(FormBuilder $parent = null)
{
$this->parent = $parent;
return $this;
}
/**
* Returns the event dispatcher.
*

View File

@ -128,14 +128,15 @@ class FormFactory implements FormFactoryInterface
* @param string|FormTypeInterface $type The type of the form
* @param mixed $data The initial data
* @param array $options The options
* @param FormBuilder $parent The parent builder
*
* @return Form The form named after the type
*
* @throws FormException if any given option is not applicable to the given type
*/
public function create($type, $data = null, array $options = array())
public function create($type, $data = null, array $options = array(), FormBuilder $parent = null)
{
return $this->createBuilder($type, $data, $options)->getForm();
return $this->createBuilder($type, $data, $options, $parent)->getForm();
}
/**
@ -147,14 +148,15 @@ class FormFactory implements FormFactoryInterface
* @param string $name The name of the form
* @param mixed $data The initial data
* @param array $options The options
* @param FormBuilder $parent The parent builder
*
* @return Form The form
*
* @throws FormException if any given option is not applicable to the given type
*/
public function createNamed($type, $name, $data = null, array $options = array())
public function createNamed($type, $name, $data = null, array $options = array(), FormBuilder $parent = null)
{
return $this->createNamedBuilder($type, $name, $data, $options)->getForm();
return $this->createNamedBuilder($type, $name, $data, $options, $parent)->getForm();
}
/**
@ -162,18 +164,19 @@ class FormFactory implements FormFactoryInterface
*
* @see createBuilderForProperty()
*
* @param string $class The fully qualified class name
* @param string $property The name of the property to guess for
* @param mixed $data The initial data
* @param array $options The options for the builder
* @param string $class The fully qualified class name
* @param string $property The name of the property to guess for
* @param mixed $data The initial data
* @param array $options The options for the builder
* @param FormBuilder $parent The parent builder
*
* @return Form The form named after the property
*
* @throws FormException if any given option is not applicable to the form type
*/
public function createForProperty($class, $property, $data = null, array $options = array())
public function createForProperty($class, $property, $data = null, array $options = array(), FormBuilder $parent = null)
{
return $this->createBuilderForProperty($class, $property, $data, $options)->getForm();
return $this->createBuilderForProperty($class, $property, $data, $options, $parent)->getForm();
}
/**
@ -182,16 +185,17 @@ class FormFactory implements FormFactoryInterface
* @param string|FormTypeInterface $type The type of the form
* @param mixed $data The initial data
* @param array $options The options
* @param FormBuilder $parent The parent builder
*
* @return FormBuilder The form builder
*
* @throws FormException if any given option is not applicable to the given type
*/
public function createBuilder($type, $data = null, array $options = array())
public function createBuilder($type, $data = null, array $options = array(), FormBuilder $parent = null)
{
$name = is_object($type) ? $type->getName() : $type;
return $this->createNamedBuilder($type, $name, $data, $options);
return $this->createNamedBuilder($type, $name, $data, $options, $parent);
}
/**
@ -201,12 +205,13 @@ class FormFactory implements FormFactoryInterface
* @param string $name The name of the form
* @param mixed $data The initial data
* @param array $options The options
* @param FormBuilder $parent The parent builder
*
* @return FormBuilder The form builder
*
* @throws FormException if any given option is not applicable to the given type
*/
public function createNamedBuilder($type, $name, $data = null, array $options = array())
public function createNamedBuilder($type, $name, $data = null, array $options = array(), FormBuilder $parent = null)
{
$builder = null;
$types = array();
@ -278,6 +283,7 @@ class FormFactory implements FormFactoryInterface
$builder->setTypes($types);
$builder->setCurrentLoadingType($type->getName());
$builder->setParent($parent);
foreach ($types as $type) {
$type->buildForm($builder, $options);
@ -297,16 +303,17 @@ class FormFactory implements FormFactoryInterface
* If any of the 'max_length', 'required' and type options can be guessed,
* and are not provided in the options argument, the guessed value is used.
*
* @param string $class The fully qualified class name
* @param string $property The name of the property to guess for
* @param mixed $data The initial data
* @param array $options The options for the builder
* @param string $class The fully qualified class name
* @param string $property The name of the property to guess for
* @param mixed $data The initial data
* @param array $options The options for the builder
* @param FormBuilder $parent The parent builder
*
* @return FormBuilder The form builder named after the property
*
* @throws FormException if any given option is not applicable to the form type
*/
public function createBuilderForProperty($class, $property, $data = null, array $options = array())
public function createBuilderForProperty($class, $property, $data = null, array $options = array(), FormBuilder $parent = null)
{
if (!$this->guesser) {
$this->loadGuesser();
@ -340,7 +347,7 @@ class FormFactory implements FormFactoryInterface
$options = array_merge($typeGuess->getOptions(), $options);
}
return $this->createNamedBuilder($type, $property, $data, $options);
return $this->createNamedBuilder($type, $property, $data, $options, $parent);
}
/**

View File

@ -21,12 +21,13 @@ interface FormFactoryInterface
* @param string|FormTypeInterface $type The type of the form
* @param mixed $data The initial data
* @param array $options The options
* @param FormBuilder $parent The parent builder
*
* @return Form The form named after the type
*
* @throws FormException if any given option is not applicable to the given type
*/
function create($type, $data = null, array $options = array());
function create($type, $data = null, array $options = array(), FormBuilder $parent = null);
/**
* Returns a form.
@ -35,26 +36,28 @@ interface FormFactoryInterface
* @param string $name The name of the form
* @param mixed $data The initial data
* @param array $options The options
* @param FormBuilder $parent The parent builder
*
* @return Form The form
*
* @throws FormException if any given option is not applicable to the given type
*/
function createNamed($type, $name, $data = null, array $options = array());
function createNamed($type, $name, $data = null, array $options = array(), FormBuilder $parent = null);
/**
* Returns a form for a property of a class.
*
* @param string $class The fully qualified class name
* @param string $property The name of the property to guess for
* @param mixed $data The initial data
* @param array $options The options for the builder
* @param string $class The fully qualified class name
* @param string $property The name of the property to guess for
* @param mixed $data The initial data
* @param array $options The options for the builder
* @param FormBuilder $parent The parent builder
*
* @return Form The form named after the property
*
* @throws FormException if any given option is not applicable to the form type
*/
function createForProperty($class, $property, $data = null, array $options = array());
function createForProperty($class, $property, $data = null, array $options = array(), FormBuilder $parent = null);
/**
* Returns a form builder
@ -62,12 +65,13 @@ interface FormFactoryInterface
* @param string|FormTypeInterface $type The type of the form
* @param mixed $data The initial data
* @param array $options The options
* @param FormBuilder $parent The parent builder
*
* @return FormBuilder The form builder
*
* @throws FormException if any given option is not applicable to the given type
*/
function createBuilder($type, $data = null, array $options = array());
function createBuilder($type, $data = null, array $options = array(), FormBuilder $parent = null);
/**
* Returns a form builder.
@ -76,12 +80,13 @@ interface FormFactoryInterface
* @param string $name The name of the form
* @param mixed $data The initial data
* @param array $options The options
* @param FormBuilder $parent The parent builder
*
* @return FormBuilder The form builder
*
* @throws FormException if any given option is not applicable to the given type
*/
function createNamedBuilder($type, $name, $data = null, array $options = array());
function createNamedBuilder($type, $name, $data = null, array $options = array(), FormBuilder $parent = null);
/**
* Returns a form builder for a property of a class.
@ -89,16 +94,17 @@ interface FormFactoryInterface
* If any of the 'max_length', 'required' and type options can be guessed,
* and are not provided in the options argument, the guessed value is used.
*
* @param string $class The fully qualified class name
* @param string $property The name of the property to guess for
* @param mixed $data The initial data
* @param array $options The options for the builder
* @param string $class The fully qualified class name
* @param string $property The name of the property to guess for
* @param mixed $data The initial data
* @param array $options The options for the builder
* @param FormBuilder $parent The parent builder
*
* @return FormBuilder The form builder named after the property
*
* @throws FormException if any given option is not applicable to the form type
*/
function createBuilderForProperty($class, $property, $data = null, array $options = array());
function createBuilderForProperty($class, $property, $data = null, array $options = array(), FormBuilder $parent = null);
function getType($name);

View File

@ -180,6 +180,45 @@ class FormBuilderTest extends \PHPUnit_Framework_TestCase
$this->assertNotSame($builder, $this->builder);
}
public function testGetParent()
{
$this->assertNull($this->builder->getParent());
}
public function testGetParentForAddedBuilder()
{
$builder = new FormBuilder('name', $this->factory, $this->dispatcher);
$this->builder->add($builder);
$this->assertSame($this->builder, $builder->getParent());
}
public function testGetParentForRemovedBuilder()
{
$builder = new FormBuilder('name', $this->factory, $this->dispatcher);
$this->builder->add($builder);
$this->builder->remove('name');
$this->assertNull($builder->getParent());
}
public function testGetParentForCreatedBuilder()
{
$this->builder = new FormBuilder('name', $this->factory, $this->dispatcher, 'stdClass');
$this->factory
->expects($this->once())
->method('createNamedBuilder')
->with('text', 'bar', null, array(), $this->builder)
;
$this->factory
->expects($this->once())
->method('createBuilderForProperty')
->with('stdClass', 'foo', null, array(), $this->builder)
;
$this->builder->create('foo');
$this->builder->create('bar', 'text');
}
private function getFormBuilder()
{
return $this->getMockBuilder('Symfony\Component\Form\FormBuilder')

View File

@ -116,6 +116,7 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($builder instanceof FormBuilder);
$this->assertEquals('bar', $builder->getName());
$this->assertEquals(null, $builder->getParent());
}
public function testCreateNamedBuilderCallsBuildFormMethods()
@ -484,6 +485,22 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('builderInstance', $builder);
}
public function testCreateNamedBuilderFromParentBuilder()
{
$type = new FooType();
$this->extension1->addType($type);
$parentBuilder = $this->getMockBuilder('Symfony\Component\Form\FormBuilder')
->setConstructorArgs(array('name', $this->factory, $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface')))
->getMock()
;
$builder = $this->factory->createNamedBuilder('foo', 'bar', null, array(), $parentBuilder);
$this->assertNotEquals($builder, $builder->getParent());
$this->assertEquals($parentBuilder, $builder->getParent());
}
public function testUnknownOptions()
{
$type = new \Symfony\Component\Form\Extension\Core\Type\TextType();