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

Extract and populate values for nested fieldsets in Collection elements #5093

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 24 additions & 0 deletions library/Zend/Form/Element/Collection.php
Expand Up @@ -519,6 +519,30 @@ public function extract()
}
}

// Recursively extract and populate values for nested fieldsets
foreach ($this->fieldsets as $fieldset) {
$name = $fieldset->getName();
if (isset($values[$name])) {
$object = $values[$name];

if ($fieldset->allowObjectBinding($object)) {
$fieldset->setObject($object);
$values[$name] = $fieldset->extract();
} else {
foreach ($fieldset->fieldsets as $childFieldset) {
$childName = $childFieldset->getName();
if (isset($object[$childName])) {
$childObject = $object[$childName];
if ($childFieldset->allowObjectBinding($childObject)) {
$fieldset->setObject($childObject);
$values[$name][$childName] = $fieldset->extract();
}
}
}
}
}
}

return $values;
}

Expand Down
48 changes: 48 additions & 0 deletions tests/ZendTest/Form/Element/CollectionTest.php
Expand Up @@ -489,4 +489,52 @@ protected function prepareForExtract($collection)
'obj3' => $obj3,
));
}

public function testCanBindObjectAndPopulateAndExtractNestedFieldsets()
{

$productFieldset = new \ZendTest\Form\TestAsset\ProductFieldset();
$productFieldset->setHydrator(new \Zend\Stdlib\Hydrator\ClassMethods());

$mainFieldset = new Fieldset('shop');
$mainFieldset->setHydrator(new \Zend\Stdlib\Hydrator\ClassMethods());
$mainFieldset->add($productFieldset);

$form = new Form();
$form->setHydrator(new ObjectPropertyHydrator());
$form->add(array(
'name' => 'collection',
'type' => 'Collection',
'options' => array(
'target_element' => $mainFieldset,
'count' => 2
),
));
$form->get('collection')->setHydrator(new ObjectPropertyHydrator());

$market = new stdClass();

$prices = array(100, 200);

$shop1 = new stdClass();
$shop1->product = new Product();
$shop1->product->setPrice($prices[0]);

$shop2 = new stdClass();
$shop2->product = new Product();
$shop2->product->setPrice($prices[1]);

$market->collection = array($shop1, $shop2);
$form->bind($market);

//test for object binding
foreach ($form->get('collection')->getFieldsets() as $_fieldset) {
$this->assertInstanceOf('ZendTest\Form\TestAsset\Entity\Product', $_fieldset->get('product')->getObject());
};

//test for correct extract and populate
foreach ($prices as $_k => $_price) {
$this->assertEquals($_price, $form->get('collection')->get($_k)->get('product')->get('price')->getValue());
}
}
}