Skip to content
This repository has been archived by the owner on Jan 30, 2020. It is now read-only.

Commit

Permalink
Fix collection hydration problem
Browse files Browse the repository at this point in the history
  • Loading branch information
svycka committed Jun 2, 2016
1 parent c9c0287 commit 82b0cdc
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 13 deletions.
15 changes: 11 additions & 4 deletions src/Fieldset.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

use Traversable;
use Zend\Code\Reflection\ClassReflection;
use Zend\Form\Element\Collection;
use Zend\Hydrator;
use Zend\Hydrator\HydratorAwareInterface;
use Zend\Hydrator\HydratorInterface;
Expand Down Expand Up @@ -564,12 +565,18 @@ public function bindValues(array $values = [])
$hydrator = $this->getHydrator();
$hydratableData = [];

foreach ($values as $name => $value) {
if (!$this->has($name)) {
continue;
foreach ($this->iterator as $element) {
$name = $element->getName();

if (!array_key_exists($name, $values)) {
if (!($element instanceof Collection)) {
continue;
}

$values[$name] = [];
}

$element = $this->iterator->get($name);
$value = $values[$name];

if ($element instanceof FieldsetInterface && $element->allowValueBinding()) {
$value = $element->bindValues($value);
Expand Down
8 changes: 4 additions & 4 deletions test/Element/CollectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -527,17 +527,17 @@ public function testAddingCollectionElementAfterBind()
*/
public function testDoesNotCreateNewObjectsWhenUsingNestedCollections()
{
$addressesFieldeset = new \ZendTest\Form\TestAsset\AddressFieldset();
$addressesFieldeset->setHydrator(new \Zend\Hydrator\ClassMethods());
$addressesFieldeset->remove('city');
$addressesFieldset = new \ZendTest\Form\TestAsset\AddressFieldset();
$addressesFieldset->setHydrator(new \Zend\Hydrator\ClassMethods());
$addressesFieldset->remove('city');

$form = new Form();
$form->setHydrator(new ObjectPropertyHydrator());
$form->add([
'name' => 'addresses',
'type' => 'Collection',
'options' => [
'target_element' => $addressesFieldeset,
'target_element' => $addressesFieldset,
'count' => 1
],
]);
Expand Down
43 changes: 39 additions & 4 deletions test/FormTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -377,10 +377,10 @@ public function testCanAddFileEnctypeFromCollectionAttribute()

$fileCollection = new Element\Collection('collection');
$fileCollection->setOptions([
'count' => 2,
'allow_add' => false,
'allow_remove' => false,
'target_element' => $file,
'count' => 2,
'allow_add' => false,
'allow_remove' => false,
'target_element' => $file,
]);
$this->form->add($fileCollection);

Expand Down Expand Up @@ -2158,4 +2158,39 @@ public function testGetInputFilterInjectsFormInputFilterFactoryInstanceWhenObjec
$inputFilter = $this->form->getInputFilter();
$this->assertSame($inputFilterFactory, $inputFilter->getFactory());
}

public function testShouldHydrateEmptyCollection()
{
$fieldset = new Fieldset('example');
$fieldset->add([
'type' => 'Zend\Form\Element\Collection',
'name' => 'foo',
'options' => [
'label' => 'InputFilterProviderFieldset',
'count' => 1,
'target_element' => [
'type' => 'text'
]
],
]);

$this->form->add($fieldset);
$this->form->setBaseFieldset($fieldset);
$this->form->setHydrator(new \Zend\Hydrator\ObjectProperty());

$object = new Entity\SimplePublicProperty();
$object->foo = ['item 1', 'item 2'];

$this->form->bind($object);

$this->form->setData([
'submit' => 'Confirm',
'example' => [
//'foo' => [] // $_POST does't have this if collection is empty
]
]);

$this->assertTrue($this->form->isValid());
$this->assertEquals([], $this->form->getObject()->foo);
}
}
12 changes: 11 additions & 1 deletion test/TestAsset/PhoneFieldset.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@
use Zend\Form\Fieldset;
use Zend\Form\Element;
use Zend\Hydrator\ClassMethods as ClassMethodsHydrator;
use Zend\InputFilter\InputFilterProviderInterface;
use ZendTest\Form\TestAsset\Entity\Phone;

class PhoneFieldset extends Fieldset
class PhoneFieldset extends Fieldset implements InputFilterProviderInterface
{
public function __construct()
{
Expand All @@ -31,4 +32,13 @@ public function __construct()
->setAttribute('class', 'form-control');
$this->add($number);
}

public function getInputFilterSpecification()
{
return [
'number' => [
'required' => true,
]
];
}
}

0 comments on commit 82b0cdc

Please sign in to comment.