Changing default category sort direction in Magento

sorting-01

While Magento offers a lot of power when you want to customize category pages and their impressions on your users, there are still some options that are not provided but would come in handy. One common desire is to promote expensive products and ability to reverse sort direction of products in category is a simple way to achieve that.

Functionality like that will require some custom coding, but no fear – it is rather straightforward. 🙂
Prerequisites: Magento module creation, setup scripts, block rewrites.

First step is adding attribute to categories which we will later use to “simulate” user clicking on descending arrow in frontend with setup(install) script like:

$installer = $this;
 
$installer->startSetup();
 
$installer->addAttribute(Mage_Catalog_Model_Category::ENTITY, 'reverse_sort', [
    'group'         => 'Display Settings',
    'input'         => 'select',
    'type'          => 'int',
    'label'         => 'Reverse sort',
    'source'        => 'eav/entity_attribute_source_boolean',
    'global'        => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE,
    'visible'       => true,
    'required'      => false,
    'user_defined'  => false,
    'sort_order'    => 50
]);
 
$installer->endSetup();

Which will add attribute that can be changed in magento admin interface, under Catalog -> Manage Categories, on tab “Display settings”.

Reverse sort screenshot

 

Second step is rewriting toolbar block used on category page. It controls by which criteria we sort products in listing (reacts to user changing “Sort By” in frontend or clicking direction change arrows “ASC/DESC”). We are going to extend that functionality and make it react also to reverse_sort attribute we just made, if it is set to “Yes“.

Class/method that we are extending is:

Mage_Catalog_Block_Product_List_Toolbar->getCurrentDirection()

In your config.xml, inside <frontend> or <global> node, declare block rewrite so Magento knows we are doing something funky with product_list_toolbar block.

For example:

<global>
    <blocks>
        <inchoo_reversesort>
            <class>Inchoo_ReverseSort_Block</class>
        </inchoo_reversesort>
        <catalog>
            <rewrite>
                <product_list_toolbar>Inchoo_ReverseSort_Block_Product_List_Toolbar</product_list_toolbar>
            </rewrite>
        </catalog>
    </blocks>
</global>

And final piece of functionality that we need to help us with market penetration, alter how getCurrentDirection() works:

class Inchoo_ReverseSort_Block_Product_List_Toolbar extends  Mage_Catalog_Block_Product_List_Toolbar {
    /**
     * Retrieve current direction
     *
     * @return string
     */
    public function getCurrentDirection()
    {
        $dir = $this->_getData('_current_grid_direction');
        if ($dir) {
            return $dir;
        }
 
        $directions = array('asc', 'desc');
        $dir = strtolower($this->getRequest()->getParam($this->getDirectionVarName()));
        if ($dir && in_array($dir, $directions)) {
            if ($dir == $this->_direction) {
                Mage::getSingleton('catalog/session')->unsSortDirection();
            } else {
                $this->_memorizeParam('sort_direction', $dir);
            }
        //MOD
        } elseif($cat = Mage::registry('current_category')) {
            $direction = $cat->getReverseSort();
            if($direction) {
                $dir = 'desc';
            } else {
                $dir = Mage::getSingleton('catalog/session')->getSortDirection();
            }
        //ENDMOD
        } else {
            $dir = Mage::getSingleton('catalog/session')->getSortDirection();
        }
        // validate direction
        if (!$dir || !in_array($dir, $directions)) {
            $dir = $this->_direction;
        }
        $this->setData('_current_grid_direction', $dir);
        return $dir;
    }
}

And we are done.

Thought exercise for a bored reader: how would you change getCurrentDirection() to reduce cyclomatic complexity and improve readability? 🙂


About Marin Grizelj

Backend Developer

Marin works as a Backend Developer, a position that matches his specialities - databases, network protocols and feeling for code organisation. His biggest wish is to buy a bus, gather his friends and travel the world.

Read more posts by Marin / Visit Marin's profile

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <blockquote cite=""> <code> <del datetime=""> <em> <s> <strike> <strong>. You may use following syntax for source code: <pre><code>$current = "Inchoo";</code></pre>.