3

I want to sort catalog products by name in natural order. In order to achieve it i created a custom module and overwrote Mage_Catalog_Block_Product_List_Toolbar.

   public function setCollection($collection)
    {
        $this->_collection = $collection;

        $this->_collection->setCurPage($this->getCurrentPage());

        // we need to set pagination only if passed value integer and more that 0
        $limit = (int)$this->getLimit();
        if ($limit) {
            $this->_collection->setPageSize($limit);
        }
        if ($this->getCurrentOrder() == 'name') {           
            //i'm assigning the custom sorted collection
            $this->_collection = $this->_naturalsort($this->_collection);
            //printing the collection to check whether it's in proper order
             $this->_test($this->_collection);
        }else if ($this->getCurrentOrder()) {
            $this->_collection->setOrder($this->getCurrentOrder(), $this->getCurrentDirection());
        }        
        return $this;
    }

    protected function _naturalsort($collection){
        $prodarr = $collection->exportToArray(); 
        usort($prodarr, function($a, $b) {          
            return strnatcmp($a['name'], $b['name']);
        });
        $collectionsorted = new Varien_Data_Collection();
        foreach($prodarr as $item)
        {
            $varienObject = new Varien_Object();
            $varienObject->setData($item);
            $collectionsorted->addItem($varienObject);

        }         
        return $collectionsorted;
    }
    protected function _test($collection){
       foreach($collection as $item2)
        {
            Mage::log($item2['name']);
        }        
    }

When logging the collection using my _test method the products are in correct order. Still it doesn't affect the frontend view. The frontend displays a non sorted collection. What am i doing wrong?

3

You replaced the collection in the toolbar block, but the list block which is used to display the products still contains the original collection.

Since the toolbar adds the sort order, changing the order there seems like the right choice. But you don't have access to the list block at that point, so another change will be necessary after the call to $toolbar->setCollection()

There is an event, catalog_block_product_list_collection but unfortunately the only parameter is the collection itself, so you can modify it, but not replace it.

My suggestion is to rewrite Mage_Catalog_Block_Product_List::_beforeToHtml() like this:

protected function _beforeToHtml()
{
    parent::_beforeToHtml();
    if ($this->getCurrentOrder() == 'name')
    {
        $this->_collection = $this->_naturalsort($this->_collection);
    }
}

and move _naturalsort() there. The rewrite of Mage_Catalog_Block_Product_List_Toolbar::setCollection() is not necessary anymore then.

  • Thanks for the answer. I will try this out and mark it as correct – Lakshin Karunaratne Jun 13 '16 at 0:39
  • I rewrote Mage_Catalog_Block_Product_List::_beforeToHtml() like above. But unfortunately $this->getCurrentOrder() is empty – Lakshin Karunaratne Jun 13 '16 at 16:19
  • Use $this->getToolbar()->getCurrentOrder() instead – Fabian Schmengler Jun 13 '16 at 16:24
  • I get Fatal error: Call to a member function getCurrentOrder() on a non-object – Lakshin Karunaratne Jun 13 '16 at 16:26
  • Ah, sorry, it's $this->getChild('toolbar')->getCurrentOrder () – Fabian Schmengler Jun 13 '16 at 16:31

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.