Overriding Magento blocks, models, helpers and controllers

worker

There is no project that uses framework as is. Every now and then there is a need to change something, to add something new or to override something already written. Due to many reasons it’s a bad habit and bad programming if core files are modified and it’s not recommended at all. Therefore Magento brought in an excellent way how to override/overwrite those files.

We already wrote how to override magento model classes, but there’s a need to modify helpers, blocks and controllers too, both on frontend and in admin.

Overriding Magento Blocks

Let’s start with overriding core tag blocks. Suppose that in Mage_Tag_Block_Product_List class some changes have to be done. What we would like to have here is to add our own file that will extend the original file with all of its methods. All the job that has to be done is to add the code below in the current module’s config.xml:

<config>
	<global>
		<blocks>
			<tag>
				<rewrite>
					<product_list>Inchoo_Tag_Block_Product_List</product_list>
				</rewrite>
			</tag>
		</blocks>
	</global>
</config>

As the class name says, a file has to be created in app/code/local/Inchoo/Tag/Block/Product/List.php and a class has to be defined:

class Inchoo_Tag_Block_Product_List extends Mage_Tag_Block_Product_List
{
// some code
}

Equivalent to the example above, the same rule can be applied for the blocks in adminhtml where we want to override Mage_Adminhtml_Block_Tag_Edit class.

<config>
	<global>
		<blocks>
			<adminhtml>
				<rewrite>
					<tag_edit>Inchoo_Tag_Block_Adminhtml_Tag_Edit</tag_edit>
				</rewrite>
			</adminhtml>
		</blocks>
	</global>
</config>

With the code above in config.xml an app/code/local/Inchoo/Tag/Block/Adminhtml/Tag/Edit.php file has to be created with the class definition:

class Inchoo_Tag_Block_Adminhtml_Tag_Edit extends Mage_Adminhtml_Block_Tag_Edit
{
// some code
}

Overriding Magento Helpers

Following the same principles magento helpers can be easiliy overriden too. Code for config.xml:

<config>
	<global>
		<helpers>
			<tag>
				<rewrite>
					<data>Inchoo_Tag_Helper_Data</data>
				</rewrite>
			</tag>
		</helpers>
	</global>
</config>

Next we have to create an app/code/local/Inchoo/Tag/Helper/Data.php file and to define the class:

class Inchoo_Tag_Helper_Data extends Mage_Tag_Helper_Data
{
// some code
}

Overriding Magento Models

We already wrote about overriding magento models, but what’s with resource and collection files? The same as core model file, resource and collection files can be overriden similary as other files. Files we are going to extend:

Mage_Tag_Model_Tag
Mage_Tag_Model_Resource_Tag
Mage_Tag_Model_Resource_Tag_Collection

Config.xml code:

<config>
	<global>
		<models>
			<tag>
				<rewrite>
					<!-- Model -->
					<tag>Inchoo_Tag_Model_Tag</tag>
				</rewrite>
			</tag>
			<tag_resource>
				<rewrite>
					<!-- Resource -->
					<tag>Inchoo_Tag_Model_Resource_Tag</tag>
					<!-- Collection -->
					<tag_collection>Inchoo_Tag_Model_Resource_Tag_Collection</tag_collection>
				</rewrite>
			</tag_resource>
		</models>
	</global>
</config>

Next we have to create those files:

app/code/local/Inchoo/Tag/Model/Tag.php
app/code/local/Inchoo/Tag/Model/Resource/Tag.php
app/code/local/Inchoo/Tag/Model/Resource/Tag/Collection.php.

Note: This is just an example with all three overrides in one place for easier presentation. In your own projects rewrite only those files (classes) that you need.

Overriding Magento Controllers

Overriding controllers in Magento is a bit different than the rest of the examples above where they don’t quite follow magento rewrite rules as we have seen in the previous examples. How woud it go if we would like to override controllers in Mage_Tag? Let’s take a look at the code that goes into the config.xml:

<config>
	<frontend>
		<routers>
			<tag>
				<args>
					<modules>
						<inchoo_tag before="Mage_Tag">Inchoo_Tag</inchoo_tag>
					</modules>
				</args>
			</tag>
		</routers>
	</frontend>
</config>

In the config node its child has to define whether we are changing the frontend or admin file and we define router node that will override core tag module with its arguments. In the bottom node goes the current module frontend name (inchoo_tag in my example) with the “before” or “after” attribute name with the value of which module is being overriden (Mage_Tag) and our own module name inside the tags (Inchoo_Tag).

If you noticed, there are no strict files defined. With this we have defined only the path that will look for the controller files by their names. So if we would like to override app/code/core/Mage/Tag/controllers/TagController.php a file with the same name will have to be created (app/code/local/Inchoo/Tag/controllers/TagController.php).

Class definition inside our new file:

require_once(Mage::getModuleDir('controllers','Mage_Tag').DS.'TagController.php');
 
class Inchoo_Tag_TagController extends Mage_Tag_TagController
{
// some code
}

Similar thing goes for adminhtml controllers. Config.xml code:

<config>
	<admin>
		<routers>
			<adminhtml>
				<args>
					<modules>
						<inchoo_tag before="Mage_Adminhtml">Inchoo_Tag_Adminhtml</inchoo_tag>
					</modules>
				</args>
			</adminhtml>
		</routers>
	</admin>
</config>

Create a file in app/code/local/Inchoo/Tag/controllers/Adminhtml/TagController.php and define the class:

require_once(Mage::getModuleDir('controllers','Mage_Adminhtml').DS.'TagController.php');
 
class Inchoo_Tag_Adminhtml_TagController extends Mage_Adminhtml_TagController
{
// some code
}

Now when we went through some magento rewrites it’s on you to write some astonishing code.
Happy coding!


About Damir Korpar

Backend Developer

Damir is working his way through Magento by being a Backend Developer. He loves to experience new cities and cultures, so he seizes every opportunity for a getaway.

Read more posts by Damir / Visit Damir's profile

41 comments

  1. Hello, can u help me with a grid? i try to override
    Enterprise_UrlRewrite_Block_Adminhtml_UrlRedirect_Grid
    and i use

    $current = "
    
        <global>
            <blocks>
                <urlrewrite>
                    <rewrite>
                        <urlredirect_grid>Zyx_UrlRewrite_Block_Adminhtml_UrlRedirect_Grid</urlredirect_grid>
                    </rewrite>
                </urlrewrite>
            </blocks>
        </global>
    ";

    But not working. Can u help me please?

  2. HI i hope someone can help me with the following:

    I’m trying to extend a Model class: TIG_PostNL_Model_Adminhtml_Observer_OrderGrid.

    this is my config.xml:

        <global>
            <models>
                <postnl_adminhtml>
                    <rewrite>
                        <!-- OrderGrid -->
                        <observer_ordergrid>Company_PostnlExtraOptions_Model_Adminhtml_Observer_OrderGrid</observer_ordergrid>
                    </rewrite>
                </postnl_adminhtml>
            </models>
        </global>

    This is my modules Company_PostnlExtraOptions_Model_Adminhtml_Observer_OrderGrid

    <?php
    
    class Company_PostnlExtraOptions_Model_Adminhtml_Observer_OrderGrid extends TIG_PostNL_Model_Adminhtml_Observer_OrderGrid
    {
    // functions and stuff
    }

    but the problem is that it’s not working. What am I doing wrong?

    1. try this in your config.xml .. it worked for me:

      <global>
              <models>
                  <postnl>
                      <rewrite>
                          <!-- OrderGrid -->
                          <adminhtml_observer_ordergrid>Company_PostnlExtraOptions_Model_Adminhtml_Observer_OrderGrid</adminhtml_observer_ordergrid>
                      </rewrite>
                  </postnl>
              </models>
          </global>

      ..i think it is wrong in this tutorial 🙁

    2. Hi Agona,

      That also didn’t fix the problem.
      I have found the solution myself.

      This did the trick:

      <adminhtml_observer_orderGrid>Company_PostnlExtraOptions_Model_Adminhtml_Observer_OrderGrid</adminhtml_observer_orderGrid>

      reason:
      The Class that is extended is using uppercase like: OrderGrid

      <adminhtml_observer_ordergrid>

      makes: TIG_PostNL_Model_Adminhtml_Observer_Ordergrid

      <adminhtml_observer_orderGrid>

      makes: TIG_PostNL_Model_Adminhtml_Observer_OrderGrid

      I hope someone will have use to this tip.

  3. hi,
    i want to upload the images in alphabetical order from csv files and store into databases so is there any solution to upload the images in alphabetical order ..help would be highly appreciated ………..thanks

  4. Great tuto….
    Even if I have followed your post, my case does not work.
    Here my case:

    ========= My controller =================
    require_once(Mage::getModuleDir('controllers','Mage_Adminhtml').DS.'Sales'.DS.'Order'.DS.'ShipmentController.php');
    class MyNamespace_MyModule_Adminhtml_Sales_Order_ShipmentController extends Mage_Adminhtml_Sales_Order_ShipmentController
    {
              public function saveAction(){ echo "Hello";}
    }
    ========== my config.xml ======================
        <admin>
            <routers>
                <adminhtml>
                    <args>
                        <modules>
                            <MyNamespace_MyModule after="Mage_Adminhtml">MyNamespace_MyModule_Adminhtml</MyNamespace_MyModule>
                        </modules>
                    </args>
                </adminhtml>		
            </routers>
        </admin>

    but the former method (Mage_Adminhtml_Sales_Order_ShipmentController::saveAction) is still called instead of the new one (MyNamespace_MyModule_Adminhtml_Sales_Order_ShipmentController::saveAction).

    Do you have any idea of what could be the trouble ?

    1. I could be wrong, but instead of after=”Mage_Adminhtml” it should be before=”Mage_Adminhtml”

  5. Great article. I have a question.
    What if multiple custom modules are overriding same base class which class would get executed and how does the Magento decides the priority.

    1. It depends on implementation, but those situations should be avoided. If needed, classes have to be modified to inherit one from another.

  6. Hi Damir, thank you for a great article. I have one question. How do I check if the overwritten method from a controller is loaded?

    class Inchoo_Tag_TagController extends Mage_Tag_TagController
    {
    // -> here I copied the old method and tweaked it
    }

  7. Probably one of the best tutorials I’ve ever read about Magento. Would urge any beginner to follow this ! Thanks for this article.

  8. Hello !

    I’ve been trying to overide “Mage/Customer/controllers/AccountController.php” from Magento 1.4.1.1
    I did what you’ve done in your tutorial, but the former class is still called instead of the new.

    Do you have any idea of what could be the trouble ?

  9. Hi,

    Great tutorial. I’m a newbie to Magento and have installed Magento 1.9.1 (open source) and have oauth working. I was thinking of using REST APIs to interact with the system but it looks like I need to run hacks on ‘guest’ if I don’t follow what you’ve done here. Is that true ?

    1. One solution is to search a project for “extends Name_Of_The_Controller_Class” or if your IDE provides you with an option to navigate through the hierarchy of methods and classes.

  10. Something confused me in this post, I think that the block class definition is wrong:

    class Inchoo_Tag_Block_Product_List extends Mage_Tag_Block_Product_List

    I think should be

    class Inchoo_Tag_Block_Product_List extends Mage_Core_Block_Template

    as Mage_Core_Block_Template is the parent of Mage_Tag_Block_Product_List

    1. If Mage_Core_Block_Template is extended than all the methods from Mage_Tag_Block_Product_List would have to be copied into your class, which is a bad practice (but in specific situations necessary). Therefore, for minor changes only the final class is extended, overriding only the methods you need to.

  11. hi
    i want to know that how can i rewrite the app/code/core/mage/checkout/onepage/abstract.php.
    i rewrite app/code/core/mage/checkout/onepage/shipping.php and its working properly… but abstract not working…. and u may see how i rewrite shipping.php file

    <?xml version="1.0"?>
    <config>
    	<global>
    	   <blocks>
    		  <checkout>
    			<rewrite>
    			   <onepage_shipping>LikiextCheckout_Checkout_Block_Onepage_Shipping</onepage_shipping>
    			 </rewrite>
    		  </checkout>
    	   </blocks>
    	</global>
    </config>

    thanks
    regards

    1. use this code to rewrite ‘app/code/core/mage/checkout/onepage/abstract.php’

      LikiextCheckout_Checkout_Block_Onepage_Abstract

    2. also add at top of file
      include(‘Mage_Checkout_Block_Onepage_Abstract.php’);

  12. hi
    i want to know that how can i rewrite the app/code/core/mage/checkout/onepage/abstract.php.
    i rewrite app/code/core/mage/checkout/onepage/shipping.php and its working properly… but abstract not working…. and u may see how i rewrite shipping.php file

    LikiextCheckout_Checkout_Block_Onepage_Shipping

    thanks
    regards

  13. Is there a way to override an altray overridden block?

    Let’s say that a “local installed” extension X rewrites a core block, I would like to rewrite the block myself without modifying extension X.

  14. Hi!
    My problem is that I have three different themes in the same magento system and as usual, some themes overwrites core files on Mage/local directly.

    Now my problem is that one theme is overriding Mage/Catalog and Mage/Checkout on Mage/local folder and another theme is overriding the same in Mage/Community folder.

    Is there anyway to have both working? I tried everything, so please, I need your help!

    Many thanks!!

  15. I am trying to override the class Product.php(Mage_Catalog_Model_Product).
    My module name is First_Module.
    below is my module activation xml file(/app/etc/modules):

    true
    local

    below if my module config file(\app\code\local\First\Module\etc):

    First_Module_Model_Product

    Below is my Product.php(app\code\local\First\Module\Model)
    —————————————————————-
    <?php
    class First_Module_Model_Product extends Mage_Catalog_Model_Product
    {
    public function getName(){
    $name = parent::getName();
    return strtoupper($name);

    }
    }
    (this will put all the product names to uppercase)
    but when i am trying to test from the below test php file,i am not getting the desired result.
    test.php
    —————-
    load(3);
    var_dump($object->getName());
    echo get_class($object);
    ?>

    ———————————————————-
    could someone please tell me where i am going wrong?i am trying to fix this for long time but couldnot find any solution……so desperately looking for help.
    many thanks in advance….

  16. Hello. Thank you for this post.
    Could you explain how to rewrite the Mage Cms IndexController please?

  17. These kind of posts are not just useful for Magento newbies, but for more long term developers who can never be bothered learning the syntax, and for sanity checks!

  18. first of all, your post is good i have query that whether magento having any way to extend the admin class in frontend for ex. i want grid view in frontend to display sales order history

  19. Is it really

    class Inchoo_Tag_Helper_Data extends Inchoo_Tag_Helper_Data

    as that seems not right to extend it’s self?

  20. You should mention that it is required to explicitly include the parent class definition when overriding controllers, as controller class definitions cannot be autoloaded.

    require_once(Mage::getModuleDir('controllers','Mage_Adminhtml').DS.'TagController.php');

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