Skip to content

Commit

Permalink
[Form] Adapted constructor of CollectionField to match the constructo…
Browse files Browse the repository at this point in the history
…rs of the other fields. The field prototype is now optional.
  • Loading branch information
Bernhard Schussek committed Feb 2, 2011
1 parent 265cdd1 commit c923af2
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 37 deletions.
48 changes: 21 additions & 27 deletions src/Symfony/Component/Form/CollectionField.php
Expand Up @@ -26,30 +26,12 @@
*/
class CollectionField extends Form
{
/**
* The prototype for the inner fields
* @var FieldInterface
*/
protected $prototype;

/**
* Remembers which fields were removed upon submitting
* @var array
*/
protected $removedFields = array();

/**
* Repeats the given field multiple times based in the internal collection.
*
* @param FieldInterface $innerField
*/
public function __construct(FieldInterface $innerField, array $options = array())
{
$this->prototype = $innerField;

parent::__construct($innerField->getKey(), $options);
}

/**
* Available options:
*
Expand All @@ -61,6 +43,7 @@ public function __construct(FieldInterface $innerField, array $options = array()
*/
protected function configure()
{
$this->addOption('prototype');
$this->addOption('modifiable', false);

if ($this->getOption('modifiable')) {
Expand Down Expand Up @@ -92,28 +75,28 @@ public function setData($collection)
parent::setData($collection);
}

public function submit($taintedData)
public function submit($data)
{
$this->removedFields = array();

if (null === $taintedData) {
$taintedData = array();
if (null === $data) {
$data = array();
}

foreach ($this as $name => $field) {
if (!isset($taintedData[$name]) && $this->getOption('modifiable') && '$$key$$' != $name) {
if (!isset($data[$name]) && $this->getOption('modifiable') && '$$key$$' != $name) {
$this->remove($name);
$this->removedFields[] = $name;
}
}

foreach ($taintedData as $name => $value) {
foreach ($data as $name => $value) {
if (!isset($this[$name]) && $this->getOption('modifiable')) {
$this->add($this->newField($name, $name));
}
}

parent::submit($taintedData);
parent::submit($data);
}

protected function writeObject(&$objectOrArray)
Expand All @@ -127,9 +110,20 @@ protected function writeObject(&$objectOrArray)

protected function newField($key, $propertyPath)
{
$field = clone $this->prototype;
$field->setKey($key);
$field->setPropertyPath(null === $propertyPath ? null : '['.$propertyPath.']');
if (null !== $propertyPath) {
$propertyPath = '['.$propertyPath.']';
}

if ($this->getOption('prototype')) {
$field = clone $this->getOption('prototype');
$field->setKey($key);
$field->setPropertyPath($propertyPath);
} else {
$field = new TextField($key, array(
'property_path' => $propertyPath,
));
}

return $field;
}
}
35 changes: 25 additions & 10 deletions tests/Symfony/Tests/Component/Form/CollectionFieldTest.php
Expand Up @@ -21,13 +21,17 @@ class CollectionFieldTest extends \PHPUnit_Framework_TestCase
{
public function testContainsNoFieldsByDefault()
{
$field = new CollectionField(new TestField('emails'));
$field = new CollectionField('emails', array(
'prototype' => new TestField(),
));
$this->assertEquals(0, count($field));
}

public function testSetDataAdjustsSize()
{
$field = new CollectionField(new TestField('emails'));
$field = new CollectionField('emails', array(
'prototype' => new TestField(),
));
$field->setData(array('foo@foo.com', 'foo@bar.com'));

$this->assertTrue($field[0] instanceof TestField);
Expand All @@ -45,7 +49,8 @@ public function testSetDataAdjustsSize()

public function testSetDataAdjustsSizeIfModifiable()
{
$field = new CollectionField(new TestField('emails'), array(
$field = new CollectionField('emails', array(
'prototype' => new TestField(),
'modifiable' => true,
));
$field->setData(array('foo@foo.com', 'foo@bar.com'));
Expand All @@ -64,14 +69,17 @@ public function testSetDataAdjustsSizeIfModifiable()

public function testThrowsExceptionIfObjectIsNotTraversable()
{
$field = new CollectionField(new TestField('emails'));
$field = new CollectionField('emails', array(
'prototype' => new TestField(),
));
$this->setExpectedException('Symfony\Component\Form\Exception\UnexpectedTypeException');
$field->setData(new \stdClass());
}

public function testModifiableCollectionsContainExtraField()
{
$field = new CollectionField(new TestField('emails'), array(
$field = new CollectionField('emails', array(
'prototype' => new TestField(),
'modifiable' => true,
));
$field->setData(array('foo@bar.com'));
Expand All @@ -83,7 +91,9 @@ public function testModifiableCollectionsContainExtraField()

public function testNotResizedIfSubmittedWithMissingData()
{
$field = new CollectionField(new TestField('emails'));
$field = new CollectionField('emails', array(
'prototype' => new TestField(),
));
$field->setData(array('foo@foo.com', 'bar@bar.com'));
$field->submit(array('foo@bar.com'));

Expand All @@ -95,7 +105,8 @@ public function testNotResizedIfSubmittedWithMissingData()

public function testResizedIfSubmittedWithMissingDataAndModifiable()
{
$field = new CollectionField(new TestField('emails'), array(
$field = new CollectionField('emails', array(
'prototype' => new TestField(),
'modifiable' => true,
));
$field->setData(array('foo@foo.com', 'bar@bar.com'));
Expand All @@ -108,7 +119,9 @@ public function testResizedIfSubmittedWithMissingDataAndModifiable()

public function testNotResizedIfSubmittedWithExtraData()
{
$field = new CollectionField(new TestField('emails'));
$field = new CollectionField('emails', array(
'prototype' => new TestField(),
));
$field->setData(array('foo@bar.com'));
$field->submit(array('foo@foo.com', 'bar@bar.com'));

Expand All @@ -119,7 +132,8 @@ public function testNotResizedIfSubmittedWithExtraData()

public function testResizedUpIfSubmittedWithExtraDataAndModifiable()
{
$field = new CollectionField(new TestField('emails'), array(
$field = new CollectionField('emails', array(
'prototype' => new TestField(),
'modifiable' => true,
));
$field->setData(array('foo@bar.com'));
Expand All @@ -134,7 +148,8 @@ public function testResizedUpIfSubmittedWithExtraDataAndModifiable()

public function testResizedDownIfSubmittedWithLessDataAndModifiable()
{
$field = new CollectionField(new TestField('emails'), array(
$field = new CollectionField('emails', array(
'prototype' => new TestField(),
'modifiable' => true,
));
$field->setData(array('foo@bar.com', 'bar@bar.com'));
Expand Down

0 comments on commit c923af2

Please sign in to comment.