Magento – Wrong sort order in category product collection

category-productsenterprise-1.13position;product-collection

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 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.

Related Topic