How to extend Magento core controller?

How to extend Magento core controller?

Hi, today I’ll show you how to edit Magento’s core module without messing with core files themselves, or “the right way of doing things”. 😀

First of all, I chose Magento’s Customer module and its Account controller as an example. First, you need to find it in Magento’s Core folder (full path: “app/code/core/Mage/Customer/controllers/AccountController.php“).

First step is to create and place folders in your module that will override Magento’s core controller. On to that part:

  1. First, create this file in same folder structure: app/code/local/Inchoo/Coreextended/controllers/Frontend/Customer/AccountController.php. (of course, you can always replace Inchoo with desired namespace, and Coreextended with some other module name, but you’ll need to edit the rest accordingly).
  2. Then create xml for our module located here: app/code/local/Inchoo/Coreextended/etc/config.xml (same analogy as above applies)
  3. And finally, create this file app/etc/modules/Inchoo_Coreextended.xml.

Second step is to enter the data inside them:

1. The AccountController.php’s content:

< ?php
require_once Mage::getModuleDir('controllers', 'Mage_Customer').DS.'AccountController.php';
//we need to add this one since Magento wont recognize it automatically
 
class Inchoo_Coreextended_Frontend_Customer_AccountController
extends Mage_Customer_AccountController
{//here, you extended the core controller with our
 
public function indexAction()
{
parent::indexAction();
//you can always use default functionality
}
 
public function myactionAction()
{
//my code
//you can write your own methods / actions
}
 
public function mymethod()
{
//my code
//you can write your own methods
}
 
public function loginAction()
{
//finally you can write your code that will rewrite the whole core method
//and you can call for your own methods, as you have full control over core controller
}
}

2. The config xml content:

<!--?xml version="1.0"?-->
 
 
 
0.2.0
 
 
 
 
 
 
 
Inchoo_Coreextended_Frontend_Customer

3. And finally Inchoo_Coreextended.xml source:

< ?xml version="1.0"?>
<!--we need to enable this module as any other if-->
<!--you wish to do it as standalone module extension-->
 
 
 
true
local

And there you go. In this 3 steps (or 6 if you count the creation of files), you created an extension of Magento’s core controller. As I heard and same as I read, this is considered the best practice of extending Magento’s core controllers. It’s immune to upgrading as long as Magento (Varien) don’t change something drastically in their core files.

And that’s about it. I hope this helped someone. Bye!

Edit: special thanks to couple of colleagues here at Inchoo who pointed to me that my first version of config.xml wasn’t configured right. I rewrote this part of article. Also, thanks to all of you who commented article with some strong points. 😀

You made it all the way down here so you must have enjoyed this post! You may also like:

How To Connect Google Analytics 4 To Magento 2 Bojan Mareljic
Bojan Mareljic, | 36

How To Connect Google Analytics 4 To Magento 2

3 best open-source eCommerce platforms in 2021 Zrinka Antolovic
Zrinka Antolovic, | 8

3 best open-source eCommerce platforms in 2021

Layout of your custom controller in Magento? Vedran Subotic
Vedran Subotic, | 12

Layout of your custom controller in Magento?

51 comments

  1. Hello again,

    After some thinking and searching. Your post is not best practise either. Because the way you do it override core controller by file. Let imagination , you override a core controller in your module. But what do you think if there are another module wants override your controller. By use your way, it is impossible if your module take a higher priority.

    So the best solution. You can see : http://magento.stackexchange.com/questions/21784/rewriting-controller-vs-adding-a-new-controller-to-an-existing-module

    I hove it help someone, help the developer life easier.

  2. Just a note. I think you shoudl add depend module to Mage_Customer. Of course, in your case it is make sense because Mage_Customer is a part of core. But let, imagination portable component. Add depend module is a best practise.

  3. Hi

    I have added a mobile_number in customer registration form and i need help in making the mobile_number as unique field similar to email. so that no customer can register same mobile no twice(just same as email).
    Do you have any idea how can i get this done.
    By reading some blog i have made the mobile_number unique in
    select * from eav_attribute where is_unique=1;
    But this is not working.

  4. Hi Mladen, thanks for sharing how to do this the right way lol. It’s a little bit more work than other tutorials, but hey, who wants to mess with the core files?! I’m going to try this out.

  5. I have followed the steps from “http://www.opencart60s.com/magento/how-to-add-a-cancel-order-link-on-the-frontend-29330.html” site.
    but when click on the cancel order link it show the “404 page not found error”.
    What did I do wrong? Am I missing something?
    Please help me soon….

  6. Hi,
    i’ve developped a module to rewrite AccountController.php just to add a combo box with the group in registration form, this is my accountcontroller.php

    <?php
    require_once Mage::getModuleDir('controllers', 'Mage_Customer').DS.'AccountController.php';  
    class Blumango_CoreExtend_Customer_AccountController extends Mage_Customer_AccountController{
    	/**
         * Get Customer Model
         *
         * @return Mage_Customer_Model_Customer
         */
        protected function _getCustomer()
        {
            $customer = $this->_getFromRegistry('current_customer');
            if (!$customer) {
                $customer = $this->_getModel('customer/customer')->setId(null);
            }
            if ($this->getRequest()->getParam('is_subscribed', false)) {
                $customer->setIsSubscribed(1);
            }
            /**
             * Initialize customer group id
             */
            //$customer->getGroupId();
            //select combo group
            if($this->getRequest()->getPost('group_id'))
     			{ $customer->setGroupId($this->getRequest()->getPost('group_id'));
     			} else {
    			$customer->getGroupId(); } 
            return $customer;
        	//select combo group
    		}
    
    }

    The problem is: the function works and the account is fully registered whit the group selected and I can see it in databasee and in the admin, but in front end, after submit I have a error whitout notice text and the page remains in create account…
    where I’m I wrong?… I’ve (just for testing!!!) modifing the file in core and works…
    Thanks

  7. Hi,

    I am a huge fan of yours, but i ran into a problem.
    actually what i’d like to do is that to change the metadescription and the title,and in the core controller indexAction it has loadLayout() and renderLayout() between these 2 i should insert the code setTitle() and the setDescription() lines.My question is if there is any other way to solve this.I mean like setting these things before the core controller loads like

    public function indexAction(){
               $this->loadLayout();
               $this -> setTitle(); // and setDescription()
               $this -> renderLayout();
              parent::indexAction();          
    }

    thanks in advance 🙂

  8. Hi I am the basic learner of Magento.

    I have good working knowledge in wordpress so i thought to learn magento and working on it.

    In the header of magento i would like to show total wishlist counter of current user . i got some code like this but where i have to add it and how can i make it to get display. I am working in my localhost.

    $wishList = Mage::getModel(‘wishlist/wishlist’)->loadByCustomer(Mage::getSingleton(‘customer/session’)->getCustomer());

  9. Hello,

    Is it possible to edit controllers such as “Onepagecontroller.php” so it will only effect a single store on a multistore installation?

    I have modified the checkout but it has applied these changes to all stores on the magento installation.

    Any ideas?

  10. Is anyone else finding when rewriting the customer account controller, if you then try to login from the checkout page you are redirected to the Customer Account page after login, instead of the checkout page?

  11. is anyone getting this one work?
    i had try to write all the code by myself instead of copy paste and the module was appear and it is enable at the magento back end.
    But it seems like that my AccountController.php was not loaded..any idea?

  12. Is anyone else finding when rewriting the customer account controller, if you then try to login from the checkout page you are redirected to the Customer Account page after login, instead of the checkout page? It seems indexAction is being called after successful login. Thoughts?

  13. for all the users that have the issue of their modules not working.

    open var/log/system.txt

    inside you will most likely see an error from varien.php
    about xml containing wierd characters . this comes from copy/pasting from the website.

    re-write each file indavidually WITHOUT copy/pasting. delete all the files in the var/cache directory(even if caching has been disabled in the admin panel)

    then refresh your page.
    check the system.txt file again and see if the errors are gone. BAM your module should now show up int he admin panel under admin>configuration>advanced>advanced

  14. Hi
    I tried the exact thing in the blog and Im facing the same issue that John mentioned above I dont see the custom module in the admin backend (Config->Advanced tab). where I could enable it

    I gave multiple try like one with Catalog Products controler, then Sales Order and finally I just copied the same code but nothing helps. Im using magento 1.6 is that a problem? or what would be any suggetions?

  15. @Abhi – Those questions are from oDesk for Magento qualification. Posting them here is inappropriate.

    If you are seeking answers to circumnavigate the qualification process, you don’t deserve to work with the framework.

  16. Hi everyone, well i need some help regarding these Magento questions so if you can help me out here, i’ll be very much thankful.

    Q: Which TWO of the following classes exist in Magento?
    Possible answers:
    1. a. Catalog_Model_Product_Type_Composite
    2. b. Catalog_Model_Product_Type_Virtual
    3. c. Catalog_Model_Product_Type_Price
    4. d. Catalog_Model_Product_Type_Physical
    5. e. Catalog_Model_Product_Type_Index

    A: ?

    Q: Which of the following module files is evaluated first?
    Possible answers:
    1. a. app/code/core/Mage/Api/etc/adminhtml.xml
    2. b. app/code/core/Mage/Api/etc/config.xml
    3. c. app/code/core/Mage/Api/etc/system.xml
    4. d. app/etc/modules/Mage_Api.xml

    A: ?

    Q: On quote address entities, the shipping_method property is composed of _______ and _______. (Choose TWO)
    Possible answers:
    1. a. carrier code
    2. b. store code
    3. c. carrier title
    4. d. method code
    5. e. customer group code
    6. f. website code
    7. g. method title

    A: ?

    Q: Which one of the following xpaths is correct for replacing Mage_Page_Block_Html_Head with Custom_Module_Block_Head via the block factory method?
    Possible answers:
    1. a. global/rewrite/blocks/page/html/head
    2. b. global/blocks/page/html_head
    3. c. global/blocks/rewrite/page/head
    4. d. global/blocks/page/rewrite/html_head
    5. e. global/page/blocks/rewrite/html_head

    A: ?

    Q: Which THREE of the following are required for tier prices in Magento?
    Possible answers:
    a. Website
    b. Store
    c. Store View
    d. Customer
    e. Customer Group
    f. Quantity

    A: ?

    Q: Which one of the following xpaths can be read using Mage::getStoreConfig(‘some/value’)?
    Possible answers:
    1. a. default/some/value
    2. b. global/default/some/value
    3. c. some/value
    4. d. stores/some/value
    5. e. some/value/default

    A: ?

    Q: Which one of the following is a possible return value type of Mage::getConfig()->getNode()?
    Possible answers:
    1. a. array
    2. b. integer
    3. c. object
    4. d. string

    A: ?

    Q: Which THREE of the following locations in app/code/local/Some/Module/ are configurable?
    Possible answers:
    1. a. Block/
    2. b. Helper/
    3. c. Model/
    4. d. controllers/
    5. e. etc/

    A: ?

    Q: Assuming a standard Magento installation, which property of every shipping carrier’s model points to that shipping carrier’s configuration?
    Possible answers:
    1. a. $_code
    2. b. $_id
    3. c. $_carrierCode
    4. d. $_carrier

    A: ?

    Q: Assume you have three models A, B and C. Both A and B extend C. Assume C contains a method that you are going to change in both A and B. How can you change the method using Magento class rewrites.
    Possible answers:
    1. a. Rewrite class C using the xpath global/models/_MODULE_/rewrite/C
    2. b. Rewrite the method using the xpath global/models/_YOUR_MODULE_/rewrite/C/_METHOD_
    3. c. You must rewrite both A and B using the xpaths global/models/_MODULE_/rewrite/A and global/models/_MODULE_/rewrite/B
    4. d. You must change that method directly in C.

    A: ?

    Q:
    24
    2011
    To be functional, a shipping carrier model must implement the methods of the ____ and ____ classes. (Choose TWO)
    Possible answers:
    1. a. Mage_Shipping_Model_Carrier
    2. b. Mage_Shipping_Model_Carrier_Abstract
    3. c. Mage_Shipping_Model_Shipping
    4. d. Mage_Shipping_Model_Rate_Request
    5. e. Mage_Shipping_Model_Carrier_Interface

    A: ?

    Q: Which of the following does NOT return an instance of a helper object?
    Possible answers:
    1. a. Mage::app()->getLayout()->helper(‘customer’);
    2. b. Mage::helper(‘customer’);
    3. c. Mage::app()->helper(‘customer’);
    4. d. Mage::app()->getLayout()->createBlock(‘core/template’) ->helper(‘customer’);

    A: ?

    Q: Which of the following will correctly translate the value of the label node?
    Possible answers:
    1)

    Value

    2)

    Value

    3)

    Value

    4)

    Value

    A: ?

    Q: Which of the following is called to apply taxes on the product view page?
    Possible answers:
    1. a. Mage_Tax_Helper_Data
    2. b. Mage_Tax_Model_Sales_Total_Quote_Tax
    3. c. Mage_Sales_Model_Quote_Address_Total_Tax
    4. d. Mage_Catalog_Model_Product_Type_Price

    A: ?

    Q: In a fresh installation of native Magento, the email templates are stored in the _________________.
    Possible answers:
    1. a. email folder of the current theme
    2. b. app/design/email folder
    3. c. app/locale/_LOCALE_/template/email folder
    4. d. app/design/base/default/default/template/email folder

    A: ?

    Q: On quote address entities, the shipping_meathod property is composed of ___________and _________.(Choose two)
    1) carrier code
    2) store code
    3) carrier title
    4) method code
    5) customer group code
    6) website code
    7) method title

    A: ?

  17. @chris I have tried to override AdminProduct Controller using the above config.xml. Mine Config.xml is as below.

    My_Changecatalog
    My_Changecatalog

    And you can try below code to override Newsletter controller. Just look out at xml.

    My_Newsletter

    Just lookout how frontend and admin routers have been set. Hope helpful to you. Exactly i dont have idea why you get 404. May be because of routers have not been set properly.

  18. Hi Inchoo Team,

    I tried this post to extend my Mage_Catalog_ProductController but i can’t seem to make it work. I can see the my module is activated but it keeps giving a 404 error.

    @Kamal how did you do it?

  19. I’ve copy pasted 100% same code with same directory structure but it’s not working. please help me it’s redirecting to login page and if i try to access myaction it display error Whoops, our bad… on page

    please help me

  20. Hi,
    Thanks for your excellent article.
    I copied and pasted your exact code into my site, following all of your folder name convention etc. When I navigate to advanced config, the module does not appear – can you tell me is it suppose to as I would have thought it would have.

    I noticed in one of the posts it said about altering codepool to codePool but this unfortunately still had no effect.
    Thanks again.

  21. Keep attention at the “codepool” tag inside Inchoo_Coreextended.xml.
    It must be named “codePool” otherwise nothing works!!
    Mladen thanks for the useful post!!

  22. @Damu and @Mladen Lotar: Why is it that it redirects to the login page when I try to access my custom action only when I am not logged in? I’ve looked at the preDispatch and cleared my cache…It’s still redirecting…

  23. Very helpful config.xml for overriding core – controller. I have override ProductController.php.

    Thx Mladen Lotar.

    REGARDS,
    KAMAL

  24. Thank for the tutorial.
    I’m trying to flow this tutorial in order to extend the order controller and add a cancel link in the account->recent orders, but it doesn’t seam to work.

    I have a namespace called G4R and what I did is :

    1. I’ve created a file in : app/code/local/G4R/Sales/controllers/OrderController.php

    _loadValidOrder()) {
                return;
            }
            $order = Mage::registry('current_order');
            $order->setState('canceled', true);
            $order->save();
    
            $this->_redirect('customer/account');
        }
    }
    
    ?>

    2. Then I’ve create xml for the module located here: app/code/local/G4R/Sales/etc/config.xml

            0.2.0
    
                        G4R_Sales_Order

    3. I’ve created this file app/etc/modules/G4R_Sales.xml

                  true
                  local

    4. I copied the recent file template to my theme :
    …\app\design\frontend\default\default\template\sales\order\recent.phtml
    and added an a link for cancel :

    <a href="sales/order/cancel/order_id/entity_id; ?>" class="cancel">__('Cancel Order') ?>
    This step is working and I now have a link in the orders table that takes me to :
    http://www.example.com/groupsales/index.php/sales/order/cancel/order_id/38
    but that page give me an error - "The page you requested was not found"
    
    What did I do wrong? Am I missing something?
    
    Thanks
  25. If you use any type of XML tidy script it will likely cause unexpected behaviour within Magento. This is caused by the white-space or line-breaks being evaluated as part of the config values.

    I have submitted a fix to Magento SVN. Once approved this should remove this issue.

  26. What if i need to change only one function in Model / Block? Do I have to copy all other functions (if yes, it will be a similar problem tu upgrading), or if there is some way how to use the all other functions from the core file? And if i do such change, do i have to create also other files (XML)? And is there any way how can i set this up e.g. using magento connect, so give it just some path where i will store such my private “extensions”?

  27. Hi Ben,
    I’ve also noticed that newline character is creating problems too in Magento’s XMLs. Keep that in mind.

  28. Another thing worth pointing out (that bit me!) is that you cannot have any whitespace around your controller name in config.xml. Magento will silently fail to pick up your override and just use the controller from the core.

    Very annoying!

  29. open:
    Mage_Core_Controller_Varien_Action

    and above protected function _rewrite()
    you have comment:

        /**
         * Support for controllers rewrites
         *
         * Example of configuration:
         * 
         *   
         *     
         *       
         *         
         *           new_route/new_controller
         *           true
         *           
         *             new_module/new_controller/new_action
         *           
         *         
         *       
         *     
         *   
         * 
         *
         * This will override:
         * 1. core_module/core_controller/core_action to new_module/new_controller/new_action
         * 2. all other actions of core_module/core_controller to new_module/new_controller
         *
         * @return boolean true if rewrite happened
         */
  30. Sorry guys!
    <global>
    <rewrite>
    <mymod_customer_account>
    <from><![CDATA[#^/customer/account/#]]></from>
    <to>/mymod/customer_account/</to>
    </mymod_customer_account>
    </rewrite>
    </global>

  31. XML code that should have been showed in the last comment was:

    /mymod/customer_account/

  32. It seems there is more than one way to do this.. I can’t remember the first method I used but it didnt allow access to the customer module using the usual ‘customer’ frontname, only the new frontname used by my new module so I ended up using this method which seems to work also:

          /mymod/customer_account/

    It allows all existing functionality to work as normal but gives me the option to overwrite customer controller functions in my own module.

    Anyone know the difference between my method and the one mentioned in this article?

  33. Thank you both Anton and Marc. I fixed the article. I was told I had a misconfiguration in config.xml right after I published article, but I didn’t have the time ’till to fix it.

    @Damu -> take a look at Core Customer module -> you should figure out why do you get that redirection -> and try to do it again, but login first 😀

  34. It should be clear, that by your approach ALL customer controllers will be redirected to your module, because you changed the frontend router definition of the customer frontname.
    This could result in errors when you did not properly create according controller scripts in you module.

  35. it works if i access:
    /customer/account/newfunction

    but i can’t access:
    /customer/ only.

    Also, when i try to access newfunction as above it takes me to login page. Do you know how to fix that.

    Thanks.

    1. Did you find a solution for this? Been trying for 6 hours to get /customer/account/welcomeback to work but always redirects me

  36. @Anton – thanks for the information – I wasn’t aware of that this way magento can compile from folder

  37. You should use

    require_once Mage::getModuleDir(‘controllers’, ‘Mage_Cusomer’).DS.’AccountController.php’;

    this way you don’t break the magento compiler functionality and magento can find your class from compiled folder

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

Tell us about your project

Drop us a line. We'd love to know more about your project.