Make ObjectIterator compatible with Doctrine Collections #775
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
PR to deprecate
ONGR\ElasticsearchBundle\Collection\Collection
in favor of using doctrine/collections.doctrine/collections ~1.4
v1.4
of doctrine/collections introduced theArrayCollection::createFrom()
method, which is used internally for immutable actions when new collections are created. This ensures that common collection projection functions (likemap
,filter
, etc.) can be used when subclassingArrayCollection
to add additional constructor arguments.Converter::isCollection
Converter::isCollection()
will check for an instance of theDoctrine\Common\Collections\Collection
interface, which makes the converter much more flexible in being able to support any object that can act as a collection.Collection
is the combination of the interfacesCountable, IteratorAggregate, ArrayAccess
, so even a custom variation would work with the converter.Introduces
ObjectCallbackIterator
( Internal )Doctrine's
Collection
implementsIteratorAggregate
instead ofIterator
, so some logic needed to be moved into a customIterator
class thatObjectIterator
can use forforeach()
.Since
ObjectIterator
converts arrays to objects on-demand, theObjectCallbackIterator
returned byObjectIterator::getIterator()
gets instantiated with a callback that can do the document conversion and keep the$rawObjects
list inObjectIterator
up-to-date. This same logic gets applied whenObjectIterator::offsetGet()
is called, which is whyoffsetGet()
needs to be overridden inObjectIterator
as well.ObjectCallbackIterator
could be marked INTERNAL to make it clear it's not meant to be used on its own.Room for Improvement
If it's not strictly necessary for
ObjectIterator
to hydrate documents one-at-a-time, then this implementation could possibly be replaced by extending AbstractLazyCollection instead of ArrayCollection, and converting the documents when the collection is initialized, which is (sort of) what Doctrine's PersistentCollection does in the ORM.Given that document hydration is tricky at best, I thought it better to leave the implementation working as-is for now. Type hinting for
Collection
instead ofArrayCollection
, as I have done inConverter::isCollection()
, would allowObjectIterator
to change transparently later on.Closes #774