Skip to content

Commit

Permalink
[Form] added support for parent of FormBuilder
Browse files Browse the repository at this point in the history
  • Loading branch information
Martin Hasoň authored and hason committed Feb 2, 2012
1 parent 1c3e6c2 commit 7cecb4e
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 35 deletions.
38 changes: 36 additions & 2 deletions src/Symfony/Component/Form/FormBuilder.php
Expand Up @@ -113,6 +113,12 @@ class FormBuilder

private $currentLoadingType;

/**
* The parent of this builder
* @var FormBuilder
*/
private $parent;

/**
* Constructor.
*
Expand Down Expand Up @@ -532,6 +538,7 @@ public function getEmptyData()
public function add($child, $type = null, array $options = array())
{
if ($child instanceof self) {
$child->setParent($this);
$this->children[$child->getName()] = $child;

return $this;
Expand Down Expand Up @@ -573,10 +580,10 @@ public function create($name, $type = null, array $options = array())
}

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);
}

/**
Expand Down Expand Up @@ -615,6 +622,9 @@ public function get($name)
public function remove($name)
{
if (isset($this->children[$name])) {
if ($this->children[$name] instanceof self) {
$this->children[$name]->setParent(null);
}
unset($this->children[$name]);
}

Expand Down Expand Up @@ -671,6 +681,30 @@ public function setCurrentLoadingType($type)
$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.
*
Expand Down
45 changes: 26 additions & 19 deletions src/Symfony/Component/Form/FormFactory.php
Expand Up @@ -128,14 +128,15 @@ public function getType($name)
* @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();
}

/**
Expand All @@ -147,33 +148,35 @@ public function create($type, $data = null, array $options = array())
* @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();
}

/**
* Returns a form for a property of a class.
*
* @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();
}

/**
Expand All @@ -182,16 +185,17 @@ public function createForProperty($class, $property, $data = null, array $option
* @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);
}

/**
Expand All @@ -201,12 +205,13 @@ public function createBuilder($type, $data = null, array $options = array())
* @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();
Expand Down Expand Up @@ -278,6 +283,7 @@ public function createNamedBuilder($type, $name, $data = null, array $options =

$builder->setTypes($types);
$builder->setCurrentLoadingType($type->getName());
$builder->setParent($parent);

foreach ($types as $type) {
$type->buildForm($builder, $options);
Expand All @@ -297,16 +303,17 @@ public function createNamedBuilder($type, $name, $data = null, array $options =
* 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();
Expand Down Expand Up @@ -340,7 +347,7 @@ public function createBuilderForProperty($class, $property, $data = null, array
$options = array_merge($typeGuess->getOptions(), $options);
}

return $this->createNamedBuilder($type, $property, $data, $options);
return $this->createNamedBuilder($type, $property, $data, $options, $parent);
}

/**
Expand Down
34 changes: 20 additions & 14 deletions src/Symfony/Component/Form/FormFactoryInterface.php
Expand Up @@ -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.
Expand All @@ -35,39 +36,42 @@ function create($type, $data = null, array $options = array());
* @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
*
* @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.
Expand All @@ -76,29 +80,31 @@ function createBuilder($type, $data = null, array $options = array());
* @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.
*
* 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);

Expand Down
39 changes: 39 additions & 0 deletions tests/Symfony/Tests/Component/Form/FormBuilderTest.php
Expand Up @@ -180,6 +180,45 @@ public function testGetGuessed()
$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')
Expand Down
17 changes: 17 additions & 0 deletions tests/Symfony/Tests/Component/Form/FormFactoryTest.php
Expand Up @@ -116,6 +116,7 @@ public function testCreateNamedBuilder()

$this->assertTrue($builder instanceof FormBuilder);
$this->assertEquals('bar', $builder->getName());
$this->assertEquals(null, $builder->getParent());
}

public function testCreateNamedBuilderCallsBuildFormMethods()
Expand Down Expand Up @@ -484,6 +485,22 @@ public function testCreateBuilderUsesRequiredSettingWithHighestConfidence()
$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();
Expand Down

0 comments on commit 7cecb4e

Please sign in to comment.