Magento: Overriding Core Files (Blocks, Models, Resources, Controllers)

Magento Icon

When building custom modules for Magento, one of the most common needs is to override Magento’s core files, most commonly Blocks, Models, Resources, and Controllers. And, by the way, when I say “override”, that is also synonymous with “rewrite” or “extend”.

I wanted to write this up for my own reference, but I hope this ends up helping you to. At the time of writing this, all of these methods have been tested on 1.4.0. This post assumes you to have familiarity with writing Magento modules. And remember, you only need to include functions in your file that you are modifying. Leave all untouched functions out of your file.

Also, the reason I haven’t included much for examples of the actual block/model code is that 90% of getting a rewrite to work correctly is just getting your config.xml correct. It matters way less of where you put your files in your module (though it’s good to keep it organized and clean).


Overriding Core Blocks

One of the more simple and straight-forward things to override in Magento. Let’s say that you want to override the following class: Mage_Catalog_Block_Product_View.

The first step is to copy the file into your own module’s Block folder. It can be anywhere you want within that folder, it really doesn’t matter. But, for organizational purposes, it’s always best, in my opinion, to keep a similar folder/file structure as Magento does. In this case, I would put this file in My/Module/Block/Catalog/Product/View.php. Of course, you’ll need to rename the class, and have it extend Mage_Catalog_Block_Product_View.

Here is how the ‘blocks’ tag in your config.xml should look:

<blocks>
    <my_module>
        <class>My_Module_Block</class>
    </my_module>
    <catalog>
        <rewrite>
            <product_view>My_Module_Block_Catalog_Product_View</product_view>
        </rewrite>
    </catalog>
</blocks>

As you can see, we’ve got the rewrite xml inside of the ‘catalog’ tag. This refers to app/code/core/Mage/Catalog/. Then the ‘rewrite’ tag tells Magento that we are going to override a block (since we are within the ‘blocks’ tag) under Mage/Catalog/. The ‘product_view’ tag points to Mage/Catalog/Block/Product/View.php, and within that tag is the name of the class that we are using to override the core block.

As another example, if you wanted to override Mage/Catalog/Block/Product/View/Type/Simple.php, the tag under ‘rewrite’ would be ‘product_view_type_simple’.


Overriding Core Models

Overriding models (but not resource models, which are anything declared in config.xml as ‘resourceModel’, which are typically files within a Mysql4 directory) is basically the same as blocks (above). So, I will give an example, but leave out much of the explanation.

Lets say that I want to modify the model for the items on an order invoice (Mage_Sales_Model_Order_Invoice_Item). I will copy that file to My/Module/Model/Sales/Order/Invoice/Item.php, rename the class, and extend Mage_Sales_Model_Order_Invoice_Item.

The config.xml ‘models’ will look something like this:

<models>
    <my_module>
        <class>My_Module_Model</class>
    </my_module>
    <sales>
        <rewrite>
            <order_invoice_item>My_Module_Block_Sales_Order_Invoice_Item</order_invoice_item>
        </rewrite>
    </sales>
</models>

Overriding Core Resource Models

I found out the hard way once, and wasted a couple hours, that resource models have a different way of overriding them. All of the concepts are the same, with the exception of the syntax in your config.xml file. A resource model is typically going to be models that reside within a ‘Mysql4′ folder. The resource model folder is typically defined in the config.xml file using the tag ‘resourceModel’.

I was putting together a dependent filter module, and I needed to override this class: Mage_Catalog_Model_Resource_Eav_Mysql4_Attribute. Just as the above examples, I created this file: My/Module/Model/Catalog/Resource/Eav/Mysql4/Attribute.php, renamed the class, and extended Mage_Catalog_Model_Resource_Eav_Mysql4_Attribute.

As I said above, the xml syntax changes for resource models. Instead of defining just the ‘catalog’ tag right before the ‘rewrite’, you actually have to define all the way down to the mysql4 folder. Here is an example for the above model:

<models>
    <my_module>
        <class>My_Module_Model</class>
    </my_module>
    <catalog_resource_eav_mysql4>
        <rewrite>
            <attribute>My_Module_Model_Catalog_Resource_Eav_Mysql4_Attribute</attribute>
        </rewrite>
    </catalog_resource_eav_mysql4>
</models>

Overriding Admin Core Controllers

I have seen numerous methods on how to do this, but the method I will describe seems to be the current ‘standard’.

Lets say that I need to override the adminhtml attribute controller: Mage_Adminhtml_Catalog_Product_AttributeController. First thing is to create the controller in your module. I would put mine in My/Module/controllers/Catalog/Product/AtttributeController.php. An important key to note here is that with controllers, Magento does not autoload them like it does with blocks and models. So, we’ll need to include the file of the controller that we want to override. Here is an example of how my controller would look:

<?php
include_once("Mage/Adminhtml/controllers/Catalog/Product/AttributeController.php");
class My_Module_Catalog_Product_AttributeController extends Mage_Adminhtml_Catalog_Product_AttributeController
{
...

The config.xml file is key now. Unlike models and blocks, you don’t need to define exactly which/where controller you are needing to override. You just need to define whether it is an ‘admin’ or ‘frontend’ controller, which module has the controller(s) you are overriding, and which module you are overriding it with (your own, obviously).

Here is the example for the above controller:

<config>
    <admin>
        <routers>
            <adminhtml>
                <args>
                    <modules>
                        <my_Module before="Mage_Adminhtml">My_Module</my_Module>
                    </modules>
                </args>
            </adminhtml>
        </routers>
    </admin>
</config>

Overriding Frontend Core Controllers

Lets override the Onepage Checkout controller: Mage_Checkout_OnepageController. First thing is to create the controller in your module. I would put mine in My/Module/controllers/Checkout/OnepageController.php. An important key to note here is that with controllers, Magento does not autoload them like it does with blocks and models. So, we’ll need to include the file of the controller that we want to override. Here is an example of how my controller would look:

<?php
include_once('Mage/Checkout/controllers/OnepageController.php');
class My_Module_Checkout_OnepageController extends Mage_Checkout_OnepageController
{
...

The config.xml file is key now. Unlike models and blocks, you don’t need to define exactly which/where controller you are needing to override. Unlink overriding an admin controller, here will will put our router info inside the ‘frontend’ tags.

Here is the example for the above controller:

<config>
    <frontend>
        <routers>
            <checkout>
                <args>
                    <modules>
                         <My_Module before="Mage_Checkout">My_Module_Checkout</My_Module>
                    </modules>
                </args>
            </checkout>
        </routers>
    </frontend>
</config>

Please feel free to ask questions or provide feedback on this post. If there are any errors or better ways to do any of this, please let me know.

This entry was posted in Magento. Bookmark the permalink.

70 Responses to Magento: Overriding Core Files (Blocks, Models, Resources, Controllers)

  1. Omer Sabic says:

    Hi,
    for 1.9.0.1 the resource overload that worked is this
    <catalog_resource>
    <rewrite>
    <eav_mysql4_attribute>My_Module_Model_Catalog_Resource_Eav_Mysql4_Attribute</eav_mysql4_attribute>
    </rewrite>
    </catalog_resource>

  2. Omer Sabic says:

    Hi,
    for 1.9.0.1 the resource overload that worked is this

    My_Module_Model_Catalog_Resource_Eav_Mysql4_Attribute

  3. Nandakumar says:

    Hi,
    I I Would like to override Community adminhtml controllers in my localpool but it is not overriding. Show me how to override the community adminhtml controllers.?
    Thanks

  4. Pingback: Ask Experts » magento – customizing calcTaxAmount by overriding Tax_Calculation model

  5. Amit says:

    I want to override Mage/Page/Block/Html/Pager.php

    it is my app/code/local/Amit/Page/etc/config.xml

    0.0.1

    Amit_Page_Block_Html_Pager

    And here is my app/etc/modules/Amit_Page.xml

    true
    local

    and here is my app\code\local\Amit\Page\Block\Html\Pager.php

    class Amit_Page_Block_Html_Pager extends Mage_Page_Block_Html_Pager
    {}

    can someone help me.

    thanks in advance

  6. I am using Magento 1.8.1 and found that if we copy the model files to local folder and it works.

    So lets say if I just wanted to add a new function, It is the right way to copy in local folder.

    • Josh Pratt says:

      Chintan – You are correct in that it “works”, but it is most definitely not the proper way to be overriding functions. I would never recommend to anyone to copy core files into local/Mage. Very bad practice..

  7. Nandu says:

    Hi,
    Your override url looks like
    “My/Module/controllers/Checkout/OnepageController.php” and you are using
    My_Module_Checkout

    But i am using url My/Checkout/controller/OnepageControler.php and i am using
    My_Checkout

    Its not working.. Will please help how to override controller in my situation?

    thank you,
    Narendra

  8. jenny says:

    Hey Hi..I have overridden the blocks and models as per above post. BUt I have a doubt..When we copy that file in our module folder do we need to change the name of the class as we go in controller like My_Module_Checkout_Block_Onepage.php extends Mage_Checkout_Block_Onepage.php …

  9. Pingback: Overriding Magento Admin Controller, for Beginners - PHP Solutions - Developers Q & A

  10. guru says:

    Hi, great tutorial. How can we override a community module controller?

    Thanks

  11. Li Tao says:

    Your article saves me a lot of time, thank you for your good article

  12. Su says:

    Thanx a lot. This article is very interesting

  13. Pingback: Process and configuration of class overrides in Magento « Andrei Boar

  14. Merk says:

    Very nice info! Exactly what I was looking for ;)
    Keep up the good work.
    Thanks for sharing such a great knowledge with us.

    Happy coding :P

  15. manoj says:

    i want to override sales_order_track controller in core files so what changes i have to do
    please provide me set of solution i have made one custom module how can i override my controller with core.please provide me solution step by step i m new in magneto.
    also explain each step so i can easily understand.
    Thanks

    • Josh Pratt says:

      manoj – Part of learning how to do things if you are new, is to keep trying to figure out out and not rely on everyone just to give you the answer. My post here makes it pretty clear how to do it within a module.

  16. Ton says:

    very helpful!

  17. RvSing says:

    I want to show “Compatible with:” under product name on product view page. I want to do this with a module. How can I do this? Pls help me to fix this out.

  18. Miha says:

    Is there any way of overriding abstract classes?

    • Josh Pratt says:

      Miha – No. Abstract classes are only ever extended, not called/used directly. So, you need to find the functionality that extends the abstract class and override that.

  19. raghava says:

    I have done the same in config.xml file for overriding AccountController.php in Customer module. The core controller is being called rather than the extended controller. I don’t know the reason. Please help me

  20. tuba says:

    thanks for the tutorial!

    Helped me a lot to fix my code!

  21. Anthony Pascual says:

    Awesome post!!!! It’s my dream to have you as my senior programmer/developer… :)

  22. Matheus says:

    Nice post, do more, more, more!!!

  23. Pankaj Agrawal says:

    in Models rewrite there is error
    My_Module_Block_Sales_Order_Invoice_Item
    should be ( Block => Model)
    My_Module_Model_Sales_Order_Invoice_Item

    • Vijay says:

      I also found it and when I came to comment it, you already mentioned it. Good. Apart from small errors, Pratt has been doing a great job. I appreciate his posts :)

  24. Deven says:

    Hi,I need you help!!!
    This solutions is very good for me,but i have a another situation.it’s this:
    I just want use override file at use my specific custom modules,default situation,use default files not my override files.in fact,they are all use my override files.
    please help me,thank you very much!!!

  25. Thanks,
    worked like a charm for me (Magento 1.6.2)!

    Please note, that you will have to create a XML-File for the module in Folder /etc/modules to get your module running.

    Regards,
    Rafael Kutscha

  26. Pingback: Magento overwrite Controller init method • PHP Help Coding Programming

  27. Pingback: Magento Tips | Peter Zhou's Blog

  28. gopal says:

    hello i am overriding Admin Controller…..
    Mage_Adminhtml_Catalog_Product_Action_AttributeController class……
    but its not working…

    my controller code is as below and other xml code is same as written in your code….
    include_once(“Mage/Adminhtml/controllers/Catalog/Product/Action/AttributeController.php”);
    class My_Module_Catalog_Product_Action_AttributeController extends Mage_Adminhtml_Catalog_Product_Action_AttributeController
    {…..}

  29. Something wrong in Magento 1.6.1. Any Help?

  30. manu says:

    ref:Overriding Admin Core Controllers
    Due to your config.xml http://mywebsite.com/admin not working.
    how to fix it?

  31. brk aydn says:

    you make my day! thank you much….

  32. I noticed some people had problems in the comments here. I kept getting an error about the Class MyPackage_Catalog_Block….etc not being found in Layout.php – I found that this is due to the fact that you have to change the class name in the actual php file that you are editing. For instance with the Breadcrumbs.php example, I had to change “class Mage_Catalog_Block_Breadcrumbs extends Mage_Core_Block_Template” to “class MyPackage_Catalog_Block_Breadcrumbs extends Mage_Core_Block_Template” – this makes sense but is easy to overlook I think, even though this is indicated in the first thing that Pratt says in this article.

  33. Vishal Porwal says:

    Hi Josh,
    Your post is gr8. But I may have different idea as below and need your help.
    I want to fire one event when customer submit the add to cart button, I want to check a custom flag if its true then add product to cart otherwise throw an exception on cart page. How can I fire an event on core actions ? I dont want to touch addAction of core checkout cart controller?

    Thanks in advance!!

  34. Gajendra says:

    Hi Josh,

    Thank you to write this supportive articles. I have override invoice controller as per your guideline. But now I am unable to access admin panel.

    Can you please support me?

    Regards,
    Gajendra

  35. Daniel Watson says:

    Very useful blog.
    Thanks for share.

  36. Valentino says:

    Hi,
    by your tricks can I set $countOfSubscritions = 20 into app/code/core/Mage/Adminhtml/controllers/Newsletter/QueueController.php ?
    Thank You and Marry Christmas
    Valentino

  37. Surinder says:

    Hi,
    Its not working for me, i want to override newsletter/subscribercontroller.php.
    but always default controller run.
    config.xml:

    CustomCode_MyNewsletter_Mysubscriber

  38. Max says:

    Thanks! Thanks. I am new to magento and just doing my best to like you guys. Please don’t mind if i ask alot of question in future. I will like to override the customer template, that is, i want that if a customer login into his/her account, they should see a different design. Please help!

    keep your good work alive

    Best Regards
    Max

  39. Zoran says:

    Hey, thanks for this, it is the least painful solution of all out there, especially if you work with more extensions installed.

  40. Merk says:

    Thanks this is so simple after read your post.
    I found the best guideline here.
    Thanks for give me.

  41. Vijay says:

    Awesome Post, Thank you very much.

  42. kannan says:

    Hi,

    great work, this tutorial is very use full.

    Regards,

    P.Kannan

  43. prashant says:

    Thanks for the post. But do you know how do we override a “Base adminhtml controller” in magento. It is different like app\code\core\Mage\Adminhtml\Controller\Action.php i want to override Action.php ?

  44. Pingback: Dagblastit » Blog Archive » Fix core Magento in an upgrade-safe way - Rants from a Web developer, musician, dad

  45. I like your way to override frontend controllers, thanks!

    • Josh Pratt says:

      WebFlakeStudio – Well, as far as I’m concerned, it’s the only proper way to do it :)

      • Just a small correction about controllers overloading:
        it’s better to use Mage::getModuleDir method for including controllers.

        In your sample it will be like this:

        require_once Mage::getModuleDir('controllers', ‘Mage_Checkout’) . DS . 'OnepageController.php';

  46. Marcio says:

    Hi!
    I have a question about Overriding Admin Core Controllers.

    If not specified the name of Controller, as Magento know which class should override?

  47. techpop says:

    Great post. I’m trying to do this bit below:

    (Code didn’t come through…)

    unfortunately… when I use the above in my config.xml, the logout of the system breaks – using 1.4 – did you experience anything like that?

    • Josh Pratt says:

      techpop: I do this kind of stuff all the time, and I’ve never had any issues. All of this code was tested on 1.4 without issues.

    • Justin M says:

      techpop, I’m having the exact issue using Magento EE 1.9 and I cannot find the solution. I’ve been looking for a while now. Did you ever find a solution?

      Thanks,

      Justin

  48. david says:

    thx for this, very usefull: I keep coming back here :)
    just a small error, I think. In Overriding Core Models, in the rewrite tag you putMy_Module_Block_Sales_Order_Invoice_Itemwhen (i think) it should beMy_Module_Model_Sales_Order_Invoice_Itemie: Model instead of Block

  49. Pingback: kevinpaulconnor.com Project Blog › Overriding core files: the definitive guide

  50. Whippy says:

    Unfortunately there is almost always a lot more to overriding a controller. For example you need to ensure that all of the relevant page layout handles are updated to point at the originals and you need to deal with issues like the onepage controller quote coming up blank if you do a naive (but logical) specialisation of the class.

    It is these issues that really make the task of rewriting more complex than it should be.

    I would like to see a working specialisation of the onepage controller for example showing how the layouts and the quote are set up appropriately.

    • Josh Pratt says:

      Whippy – Perhaps you are not overriding the controllers properly then? I haven’t ever encountered the need to change all of the “relevant page layout handles”. The way Magento has set things up is fairly decent. I have overridden many core controllers too.

      • Jay says:

        i tried this, but no luck.

        Mycompany_Adminhtml

        • Josh Pratt says:

          Jay – I took all these examples from projects that I have done, and even re-tested the article (as I knew it was pretty important to get this one right). There has to be something that you didn’t setup quite right.

  51. Dave Carruth says:

    Thanks a ton, the part on controllers was very helpful.

  52. tuba says:

    Nice and helpful, another good magento blog. thanks!

  53. pablo says:

    Hi,

    Is it possible to override the way a specific attribute is presented in the admin?
    I have a multi-select attribute with 1K options so I can’t show the admin all of them at once. I want to show a small number of the options and let the admin load the rest with Ajax, similar to the product grid. Is it possible?

    Thanks

    • Josh Pratt says:

      pablo: This question is not really directly related to this post, but to answer your questions, almost anything is possible. The question is how difficult is it and how long will it take? You may want to reconsider what you are doing with your attributes, as 1k options for 1 attribute is pretty huge, but regardless, I can’t tell you how to do it, but I’m sure there’s a way you could refactor the output of multiselect attributes in the admin. I have never needed to try that, so I can’t tell you if/how possible it is.

  54. Hiral Vyas says:

    Hi,

    I want to override admin Catelog Product Controller for mass Action ..How can I? Can you provide example?

    Thanks in Advance

    • Josh Pratt says:

      Hiral,

      I spelled out the instructions on how to do it pretty clearly in my article. Try it out, play around with it for a while (and make sure the problem isn’t with something other than your overridden controller or config.xml file). If you still can’t get it, post pastebin links of your controller and config.xml file.

    • saurabh says:

      hi i am also facing such problem
      I want to override Checkout Onepage controller for all action ..How can I?

  55. Dan Shields says:

    Great resource for anyone getting started with Magento, I know that it took me forever find out how to do these and there was never a place that had all of them in one article.