0

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!

  • What do you do to add the sorting? – Tim Wachter Jun 11 '14 at 15:29
  • Nothing, that's the default Magento code only. – Kalpesh Jun 11 '14 at 16:04
  • That's probably because you're not accessing the same stuff, if you debug $_productCollection you'll see tons of stuff and a huge array called "data". – Julien Lachal Jun 12 '14 at 8:24
  • @JulienLachal Could be, but I am just looping it over as we do for any other collection. foreach($_productCollection as $_product). Actually it did got auto-fixed but not sure whether this problem will start again or not. – Kalpesh Jun 16 '14 at 20:36
  • maybe has to do with data reindexing? – Julien Lachal Jun 17 '14 at 7:21
3

Looking at the files which are relevant for this, I can identify Varien_Data_Collection which is the base class and implements IteratorAggregate, so you can loop over collections using foreach($_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 class Varien_Data_Collection_Db.

This class implements the method getData() as follows:

public function getData()
{
    if ($this->_data === null) {
        $this->_renderFilters()
             ->_renderOrders()
             ->_renderLimit();
        $this->_data = $this->_fetchAll($this->_select);
        $this->_afterLoadData();
    }
    return $this->_data;
}

It explicitly uses the _renderOrders() method which adds an order clause to the select statement. This is why getData() will use your given order, but the default iteration will not.

  • Nice to know, so is there any way I can get collection object to use my sort order? I tried adding "ORDER BY" clause without any luck on collection. It does show in query but not when I loop through the object. – Kalpesh Jun 12 '14 at 15:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.