I am trying to get the product collection based on the position (defined in Category Products in admin) in the category, but it doesn't work with product collection object whereas works correctly with product collection array (getData())
E.g. in Admin > Manage Categories > Category > Category Products
(Is Anchor = true but no sub-categories)
Product | Position
Prod A | 1
Prod B | 2
When I loop through product collection $_productCollection
in catalog/product/list.phtml file, the product's order comes Prod B and then Prod A, whereas if I use $_productCollection->getData()
and loop through it, it gives products in correct order.
foreach($_productCollection as $_product) //gives Prod B and then Prod A, which is not expected
foreach($_productCollection->getData() as $_product) //gives Prod A and then Prod B, which is correct
Any ideas why it would behave differently when accessing it as an object and as an array, on the same collection?
Thanks!
Best Answer
Looking at the files which are relevant for this, I can identify
Varien_Data_Collection
which is the base class and implementsIteratorAggregate
, so you can loop over collections usingforeach($_productCollection as $product)
.It does so via the method getIterator() which mainly returns new
ArrayIterator($this->_items);
In contrast, a level further up extending from
Varien_Data_Collection
there is the classVarien_Data_Collection_Db
.This class implements the method getData() as follows:
It explicitly uses the
_renderOrders()
method which adds an order clause to the select statement. This is whygetData()
will use your given order, but the default iteration will not.