Magento Rewrite Blocks, Helpers, Models and Controllers

As well as Magento giving us the ability to add custom blocks, helpers, models and controllers, we also have the ability to safely rewrite these existing classes without affecting the Magento upgrade process or security patches that may overwrite some of these files.

If you haven’t already read the article about adding custom blocks, helpers, models, and controllers, it is recommended to do so to familiarise yourself with how to name Magento’s class files.

Similar to how we add our custom blocks etc. to Magento through config.xml, rewrites also take place through this configuration file, albeit the syntax is a little different.

Let’s start with a block rewrite. First of all, let’s add our own module and add a module declaration file.

<?xml version="1.0"?>
<config>
    <modules>
        <Custom_Somemodule>
            <codePool>local</codePool>
            <active>true</active>
        </Custom_Somemodule>
    </modules>
</config>

Blocks

Let’s dive into the config.xml file, starting with a block rewrite. As an example, let’s rewrite Magento’s Mage_Page_Block_Html_Topmenu class.

<?xml version="1.0"?>
<config>
    <global>
        <blocks>
            <page>
                <rewrite>
                    <html_topmenu>Custom_Somemodule_Block_Page_Html_Topmenu</html_topmenu>
                </rewrite>
            </page>
        </blocks>
    </global>
</config>

Within the pair of blocks nodes, we first specify the module of the class we are attempting to rewrite. In our example, it is Magento’s Page module.

We then specify a pair or rewrite nodes that tell Magento we are attempting to perform a rewrite.

The rewrite nodes are checked for by Magento when using its factory methods.

The html_topmenu nodes are from the location of the class file we are attempting to rewrite within the Mage_Page module within its Block directory. The full path to the class is Mage/Page/Block/Html/Topmenu.php.

If we were rewriting the Breadcrumbs.php block file found in Mage/Page/Block/Html/Breadcrumbs.php, then the value within the rewrite nodes would become html_breadcrumbs.

The value within the html_topmenu is the class that we will use to rewrite the Topmenu.php class. With the class being called Custom_Somemodule_Block_Page_Html_Topmenu, you are telling Magento that the class will be located within the Custom/Somemodule/Block/Page/Html/Topmenu.php directory.

Now we can create the block class, ensuring that it extends from the original Topmenu.php class we are wanting to rewrite.

<?php
class Custom_Somemodule_Block_Page_Html_Topmenu extends Mage_Page_Block_Html_Topmenu {
    public function getHtml($outermostClass = '', $childrenWrapClass = '')
    {
        echo "Here is the override";
        // Some more code to follow
    }
}

You can override any method from the original block file by copying a method over to your custom block class, then editing it as you please.

Helpers

Helper rewrites are similar to blocks in terms of the syntax used on config.xml. Simply specify a helpers node and follow the same steps.

<?xml version="1.0"?>
<config>
    <global>
        ....
        <helpers>
            <tag>
                <rewrite>
                    <data>Custom_Somemodule_Helper_Data</data>
                </rewrite>
            </tag>
        </helpers>
    </global>
</config>

We can then add our helper class that will extend Mage_Tag_Helper_Data.

<?php
class Custom_Somemodule_Helper_Data extends Mage_Tag_Helper_Data {
    public function cleanTags(array $tagNamesArr)
    {
        echo "Here is an override";
        // Some more code below
    }
}

Models

Model rewrites are also similar to blocks and helpers in terms of the syntax used in config.xml. Simply specify a models node and follow the same steps.

<?xml version="1.0"?>
<config>
    <global>
        ....
        <models>
            <sales>
                <rewrite>
                    <order>Custom_Somemodule_Model_Sales_Order</order>
                </rewrite>
            </sales>
        </helpers>
    </global>
</config>

We can then add our model class that will extend Mage_Sales_Model_Order.

<?php
class Custom_Somemodule_Model_Sales_Order extends Mage_Sales_Model_Order {
    public function getTrackingNumbers()
    {
        echo "Here is an override";
        // Some more code below
    }
}

Controllers

Rewriting controllers is slightly different as routers belong in either a pair of frontend or admin nodes, and the fact that router syntax is different to block, helper and model syntax within config.xml anyway.

<?xml version="1.0"?>
<config>
    <frontend>
        <routers>
	    <customer>
	        <args>
		    <modules>
		        <custom_somemodule before="Mage_Customer">Custom_Somemodule</custom_somemodule>
		    </modules>
		</args>
	    </customer>
        </routers>
    </frontend>
</config>

The name of the module whose controller we are attempting to rewrite is names within the pair or routers nodes. In this example, it is customer as we’ll be rewriting a controller within the Mage_Customer module.

The custom_somemodule node name is just a unique alias given to our controller rewrite.

The before="Mage_Customer" attribute means that Magento should look for a controller firstly in our custom module controller before it looks in the Mage_Customer module. Because of this, we should ensure that the name of the controller that we are trying to rewrite matches the name of our custom controller. For this example, we will be rewriting the AccountController.php class therefore our controller name should be AccountController.php.

<?php
require_once(Mage::getModuleDir('controllers','Mage_Customer').DS.'AccountController.php');
class Custom_Somemodule_AccountController extends Mage_Customer_AccountController {
    public function loginPostAction() {
        echo "Test";
        exit();
    }
}

As controller classes are not included within the Magento autoload process, we have to explicitly require the original controller class file at the top of our custom controller class file.

If we now attempt to login to our customer account, we can see that the word Test has been printed out.

Magento Rewrite Blocks, Helpers, Models and Controllers

Note: This article is based on Magento Community/Open Source version 1.9.