Skip to content

Loading…

Hotfix/multiple nested collection test #5495

Closed
wants to merge 6 commits into from

4 participants

@fabiocarneiro

Tests for making sure we can bind objects to multiple fieldsets and collections

@Maks3w Maks3w commented on an outdated diff
tests/ZendTest/Form/Element/CollectionTest.php
@@ -549,6 +549,65 @@ public function testCanBindObjectAndPopulateAndExtractNestedFieldsets()
$this->assertEquals($_price, $form->get('collection')->get($_k)->get('product')->get('price')->getValue());
}
}
+
+ public function testCanBindObjectMultipleNestedFieldsets()
+ {
+
+ $productFieldset = new \ZendTest\Form\TestAsset\ProductFieldset();
@Maks3w Zend Framework member
Maks3w added a note

please import the classes using use statements.

I've copied it from the function above. The class is full of that.

@Maks3w There it is!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@thestanislav thestanislav commented on an outdated diff
tests/ZendTest/Form/Element/CollectionTest.php
((37 lines not shown))
+ $market = new stdClass();
+
+ $prices = array(100, 200);
+
+ $products[0] = new Product();
+ $products[0]->setPrice($prices[0]);
+ $products[1] = new Product();
+ $products[1]->setPrice($prices[1]);
+
+ $shop[0] = new stdClass();
+ $shop[0]->products = $products;
+
+ $shop[1] = new stdClass();
+ $shop[1]->products = $products;
+
+ $market->collection = $shop;

I do no see any element named "collection" in the form

You're right!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@thestanislav thestanislav commented on the diff
tests/ZendTest/Form/Element/CollectionTest.php
((7 lines not shown))
+
+ $productFieldset = new ProductFieldset();
+ $productFieldset->setHydrator(new ClassMethods());
+
+ $nestedFieldset = new Fieldset('nested');
+ $nestedFieldset->setHydrator(new ClassMethods());
+ $nestedFieldset->add(array(
+ 'name' => 'products',
+ 'type' => 'Collection',
+ 'options' => array(
+ 'target_element' => $productFieldset,
+ 'count' => 2
+ ),
+ ));
+
+ $mainFieldset = new Fieldset('main');

And once again, $mainFieldset should be Collection according to the object. You've mixed up with fieldsets and binding object

Form has a mainFieldset, that has a collection of nestedFieldset, that has a collection of productFieldset. the missing part is useasbasefieldset.

Should be something like this

$form = new Form();
$form->setHydrator(new ObjectPropertyHydrator());

$form->add(array(
            'name' => 'main',
            'type' => 'Collection',
            'options' => array(
                'target_element' => $nestedFieldset,
                'count' => 2
            ),
));

Assume this:
Fieldset = object
Collection = array/Traversable
Element = object property/class method

$market -> $form
$shop -> "main" fieldset but should be a collection
????? -> "nested" collection
.....

I want to achieve two levels of collections.
Form
--> Fieldset
--> --> Collection
--> --> --> Fieldset
--> --> --> --> Collection
--> --> --> --> --> Fieldset

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@thestanislav

I think i understand your issue.
As I know you should always bind an empty objects to your fieldsets. Look this https://github.com/zendframework/zf2/blob/master/tests/ZendTest/Form/TestAsset/ProductFieldset.php#L23

So you should do something like these

$nestedFieldset = new Fieldset('nested');
$nestedFieldset = new Fieldset('nested');
$nestedFieldset->setHydrator(new ClassMethods());
$nestedFieldset->setObject(new Stdclass()); // or what ever you object is

....
....
....
$mainFieldset = new Fieldset('main');
$mainFieldset->setHydrator(new ClassMethods());
$mainFieldset->setObject(new Stdclass()); // or what ever you object is

Otherwise nested objects would not bound to appropriate fieldsets

@fabiocarneiro

I'm not doing it in the test, but i am doing in my actual code. If you could test it, it would be really awesome. I know its a bit too much to ask, but i'm on that issue for more than one week and i really need it working to move ahead.
https://github.com/fabiocarneiro/FhcsFormTest

I'ts a really simplified use case with only the necessary things.

Nested objects should be bound to the appropriate fieldsets, if its not doing it right now, it should be fixed, and i've been working hard to fix that, with no success.

@weierophinney
Zend Framework member

@fabiocarneiro Have you been able to investigate this any further? Perhaps ping Bakura in #zftalk.dev on Freenode IRC to see if he can assist.

@weierophinney weierophinney added a commit that referenced this pull request
@weierophinney weierophinney [#5502] Added test from #5495
- Unit test passes now, meaning we can close both issues.
efb0b4c
@weierophinney weierophinney added a commit that closed this pull request
@weierophinney weierophinney Merge branch 'hotfix/5502'
Close #5502
Fixes #5495
1bca5ca
@weierophinney weierophinney added this to the 2.2.6 milestone
@weierophinney weierophinney self-assigned this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Showing with 81 additions and 14 deletions.
  1. +81 −14 tests/ZendTest/Form/Element/CollectionTest.php
View
95 tests/ZendTest/Form/Element/CollectionTest.php
@@ -21,6 +21,10 @@
use Zend\Stdlib\Hydrator\ArraySerializable;
use ZendTest\Form\TestAsset\CustomCollection;
use ZendTest\Form\TestAsset\ArrayModel;
+use ZendTest\Form\TestAsset\FormCollection;
+use ZendTest\Form\TestAsset\ProductFieldset;
+use Zend\Stdlib\Hydrator\ClassMethods;
+use ZendTest\Form\TestAsset\Entity\Category;
class CollectionTest extends TestCase
{
@@ -29,8 +33,8 @@ class CollectionTest extends TestCase
public function setUp()
{
- $this->form = new \ZendTest\Form\TestAsset\FormCollection();
- $this->productFieldset = new \ZendTest\Form\TestAsset\ProductFieldset();
+ $this->form = new FormCollection();
+ $this->productFieldset = new ProductFieldset();
parent::setUp();
}
@@ -252,7 +256,7 @@ public function testGetTargetElement()
public function testExtractFromObjectDoesntTouchOriginalObject()
{
$form = new \Zend\Form\Form();
- $form->setHydrator(new \Zend\Stdlib\Hydrator\ClassMethods());
+ $form->setHydrator(new ClassMethods());
$this->productFieldset->setUseAsBaseFieldset(true);
$form->add($this->productFieldset);
@@ -261,9 +265,9 @@ public function testExtractFromObjectDoesntTouchOriginalObject()
$product = new Product();
$product->setName("foo");
$product->setPrice(42);
- $cat1 = new \ZendTest\Form\TestAsset\Entity\Category();
+ $cat1 = new Category();
$cat1->setName("bar");
- $cat2 = new \ZendTest\Form\TestAsset\Entity\Category();
+ $cat2 = new Category();
$cat2->setName("bar2");
$product->setCategories(array($cat1,$cat2));
@@ -296,16 +300,16 @@ public function testDoesNotCreateNewObjects()
}
$form = new \Zend\Form\Form();
- $form->setHydrator(new \Zend\Stdlib\Hydrator\ClassMethods());
+ $form->setHydrator(new ClassMethods());
$this->productFieldset->setUseAsBaseFieldset(true);
$form->add($this->productFieldset);
$product = new Product();
$product->setName("foo");
$product->setPrice(42);
- $cat1 = new \ZendTest\Form\TestAsset\Entity\Category();
+ $cat1 = new Category();
$cat1->setName("bar");
- $cat2 = new \ZendTest\Form\TestAsset\Entity\Category();
+ $cat2 = new Category();
$cat2->setName("bar2");
$product->setCategories(array($cat1,$cat2));
@@ -345,15 +349,15 @@ public function testCreatesNewObjectsIfSpecified()
));
$form = new \Zend\Form\Form();
- $form->setHydrator(new \Zend\Stdlib\Hydrator\ClassMethods());
+ $form->setHydrator(new ClassMethods());
$form->add($this->productFieldset);
$product = new Product();
$product->setName("foo");
$product->setPrice(42);
- $cat1 = new \ZendTest\Form\TestAsset\Entity\Category();
+ $cat1 = new Category();
$cat1->setName("bar");
- $cat2 = new \ZendTest\Form\TestAsset\Entity\Category();
+ $cat2 = new Category();
$cat2->setName("bar2");
$product->setCategories(array($cat1,$cat2));
@@ -505,11 +509,11 @@ protected function prepareForExtract($collection)
public function testCanBindObjectAndPopulateAndExtractNestedFieldsets()
{
- $productFieldset = new \ZendTest\Form\TestAsset\ProductFieldset();
- $productFieldset->setHydrator(new \Zend\Stdlib\Hydrator\ClassMethods());
+ $productFieldset = new ProductFieldset();
+ $productFieldset->setHydrator(new ClassMethods());
$mainFieldset = new Fieldset('shop');
- $mainFieldset->setHydrator(new \Zend\Stdlib\Hydrator\ClassMethods());
+ $mainFieldset->setHydrator(new ClassMethods());
$mainFieldset->add($productFieldset);
$form = new Form();
@@ -549,6 +553,69 @@ public function testCanBindObjectAndPopulateAndExtractNestedFieldsets()
$this->assertEquals($_price, $form->get('collection')->get($_k)->get('product')->get('price')->getValue());
}
}
+
+ public function testCanBindObjectMultipleNestedFieldsets()
+ {
+
+ $productFieldset = new ProductFieldset();
+ $productFieldset->setHydrator(new ClassMethods());
+ $productFieldset->setObject(new Product())
+
+ $nestedFieldset = new Fieldset('nested');
+ $nestedFieldset->setHydrator(new ClassMethods());
+ $nestedFieldset->setObject(new stdClass());
+ $nestedFieldset->add(array(
+ 'name' => 'products',
+ 'type' => 'Collection',
+ 'options' => array(
+ 'target_element' => $productFieldset,
+ 'count' => 2
+ ),
+ ));
+
+ $mainFieldset = new Fieldset('main');

And once again, $mainFieldset should be Collection according to the object. You've mixed up with fieldsets and binding object

Form has a mainFieldset, that has a collection of nestedFieldset, that has a collection of productFieldset. the missing part is useasbasefieldset.

Should be something like this

$form = new Form();
$form->setHydrator(new ObjectPropertyHydrator());

$form->add(array(
            'name' => 'main',
            'type' => 'Collection',
            'options' => array(
                'target_element' => $nestedFieldset,
                'count' => 2
            ),
));

Assume this:
Fieldset = object
Collection = array/Traversable
Element = object property/class method

$market -> $form
$shop -> "main" fieldset but should be a collection
????? -> "nested" collection
.....

I want to achieve two levels of collections.
Form
--> Fieldset
--> --> Collection
--> --> --> Fieldset
--> --> --> --> Collection
--> --> --> --> --> Fieldset

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ $mainFieldset->setUseAsBaseFieldset(true);
+ $mainFieldset->setHydrator(new ClassMethods());
+ $mainFieldset->setObject(new stdClass());
+ $mainFieldset->add(array(
+ 'name' => 'nested',
+ 'type' => 'Collection',
+ 'options' => array(
+ 'target_element' => $nestedFieldset,
+ 'count' => 2
+ ),
+ ));
+
+ $form = new Form();
+ $form->setHydrator(new ObjectPropertyHydrator());
+ $form->add($mainFieldset);
+
+ $market = new stdClass();
+
+ $prices = array(100, 200);
+
+ $products[0] = new Product();
+ $products[0]->setPrice($prices[0]);
+ $products[1] = new Product();
+ $products[1]->setPrice($prices[1]);
+
+ $shop[0] = new stdClass();
+ $shop[0]->products = $products;
+
+ $shop[1] = new stdClass();
+ $shop[1]->products = $products;
+
+ $market->main = $shop;
+ $form->bind($market);
+
+ //test for object binding
+ foreach ($form->get('main')->getFieldsets() as $_fieldset) {
+ foreach($_fieldset->getFieldsets() as $_nestedfieldset) {
+ $this->assertInstanceOf('ZendTest\Form\TestAsset\Entity\Product', $_nestedfieldset->get('products')->getObject());
+ }
+ };
+
+ }
public function testExtractFromTraversableImplementingToArrayThroughCollectionHydrator()
{
Something went wrong with that request. Please try again.