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!

6
  • What do you do to add the sorting? Jun 11, 2014 at 15:29
  • Nothing, that's the default Magento code only.
    – Kalpesh
    Jun 11, 2014 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". Jun 12, 2014 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, 2014 at 20:36
  • maybe has to do with data reindexing? Jun 17, 2014 at 7:21

1 Answer 1

4

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.

1
  • 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, 2014 at 15:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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