Overriding Magento blocks, models, helpers and controllers

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. Now, we know how confusing all of this can be. But, we’re here to help you with Magento development. Feel free to drop us a line, we’d be glad to check out your site and create a detailed report on what to improve based on our technical audit!
In the meantime, happy coding!
41 comments
Hello, can u help me with a grid? i try to override
Enterprise_UrlRewrite_Block_Adminhtml_UrlRedirect_Grid
and i use
But not working. Can u help me please?
Solution: Don’t use magento
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:
This is my modules Company_PostnlExtraOptions_Model_Adminhtml_Observer_OrderGrid
but the problem is that it’s not working. What am I doing wrong?
try this in your config.xml .. it worked for me:
..i think it is wrong in this tutorial 🙁
Hi Agona,
That also didn’t fix the problem.
I have found the solution myself.
This did the trick:
reason:
The Class that is extended is using uppercase like: OrderGrid
makes: TIG_PostNL_Model_Adminhtml_Observer_Ordergrid
makes: TIG_PostNL_Model_Adminhtml_Observer_OrderGrid
I hope someone will have use to this tip.
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
Great tuto….
Even if I have followed your post, my case does not work.
Here my case:
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 ?
I could be wrong, but instead of after=”Mage_Adminhtml” it should be before=”Mage_Adminhtml”
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.
It depends on implementation, but those situations should be avoided. If needed, classes have to be modified to inherit one from another.
nice blog it contains useful information.
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
}
Probably one of the best tutorials I’ve ever read about Magento. Would urge any beginner to follow this ! Thanks for this article.
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 ?
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 ?
How to check controller is extend from core magento controller
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.
Can you please let me know how can I overwrite Magento email template?
In admin System > Transactional Emails, select a template, load it, do the changes and save it.
This is very useful artical…Thanks a lot
Thanks, very helpfull
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
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.
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
thanks
regards
use this code to rewrite ‘app/code/core/mage/checkout/onepage/abstract.php’
LikiextCheckout_Checkout_Block_Onepage_Abstract
also add at top of file
include(‘Mage_Checkout_Block_Onepage_Abstract.php’);
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
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.
Thanks Ben!
Maria, you should ask this over at http://magento.stackexchange.com/
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!!
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….
Hello. Thank you for this post.
Could you explain how to rewrite the Mage Cms IndexController please?
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!
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
Is it really
as that seems not right to extend it’s self?
Congrats Damir on your 1st post!!! Keep rolling 😉
Awesome post! I wish you done it a week prior, would have made cramming for magento certification a little easier 😉
You should mention that it is required to explicitly include the parent class definition when overriding controllers, as controller class definitions cannot be autoloaded.
Thanks Ben! Good eye. I have updated the post.