Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Bug fix for Zend\Form\Element\Collection::extract() #5220

Closed
wants to merge 1 commit into
from

Conversation

Projects
None yet
3 participants
Contributor

dhensen commented Oct 3, 2013

When a Traversable is encountered it is converted to an array.
By default this is done recursively, so that the Traversable becomes an array representation.
The result of that is saved in $this->object.
In the Collection::extract method when iterating over $this->object there are two branches:

  1. If there is a hydrator, its extract method is called which expects $value as an object.
  2. If $value is an instance of the targetElement, eventualy setObject($value) is called on a fieldset, which also expects an object. Also the targetElement object is set to $value.

In both cases an object is expected, but because of recursive iteratorToArray call it will never be an object.

The fix is to not do it recursively, this way it still gives a key => value array representation of the traversable,
but still gives model objects that can be used by a hydrator or set as targetElement object.

Member

Maks3w commented Oct 3, 2013

Two things:

  • Add a test case
  • That method could be replaced with iterator_to_array native function for this case
Bug fix:
When a Traversable is encountered it is converted to an array.
By default this is done recursively, so that the Traversable becomes an array representation.
The result of that is saved in $this->object.
In the Colletion::extract method when iterating over $this->object there are two branches:
1. If there is a hydrator, its extract method is called which expects $value as an object.
2. If $value is an instance of the targetElement, eventualy setObject($value) is called on a fieldset, which also expects an object. Also the targetElement object is set to $value.

In both cases an object is expected, but because of recursive iteratorToArray call it will never be an object.

The fix is to not do it recursively, this way it still gives a key => value array representation of the traversable,
but still gives model objects that can be used by a hydrator or set as targetElement object.

The above problem occurs when an extended Traversable that implements the toArray method is being used in the ArrayUtils::iteratorToArray method.
Because it is recursive per default, it calls the toArray method on the traversable and in case this is implemented in a way that also calls toArray on all child elements, the whole traversable is converted to a scalar-only-array.
So now that there are no object, the Zend\Form\Element\Collection::extract method can not use the hydrator extract method on an array. Also the targetElement hydrator can not do it.
So the extract method fails even though there is probably an array containing a lot of nice values.

The solution chosen by me is to not recursively transform. That works as shown in the two added testcases.
Another fix would be to rewrite the way the extract method works. Or to better dictate how the traversable should be constrained to be transformed in a more controlled way.
Owner

dhensen commented on 2e848e8 Oct 5, 2013

Okay I amended the commit and force pushed. Now contains a two testcases and some stuff to support fixing the bug by non-recursive iteratorToArray transformation. If it is not OK please let me know.

@ghost ghost assigned weierophinney Oct 23, 2013

weierophinney added a commit that referenced this pull request Oct 23, 2013

Merge pull request #5220 from dhensen/form-collection-extract-bug
Bug fix for Zend\Form\Element\Collection::extract()

Conflicts:
	tests/ZendTest/Form/Element/CollectionTest.php

weierophinney added a commit that referenced this pull request Oct 23, 2013

[#5220] CS fixes
- EOF ending

weierophinney added a commit that referenced this pull request Oct 23, 2013

Contributor

dhensen commented Oct 24, 2013

Thanks for merging into dev. I hope all is good.

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