Magento override controller

16,296

Solution 1

  1. Create your module folders and files

    app/code/local/MyNameSpace/MyModule/etc/config.xml
    app/code/local/MyNameSpace/MyModule/controllers/Checkout/CartController.php
    app/etc/modules/MyNameSpace_All.xml
    
  2. Edit /etc/config.xml and Create app/code/local/MyNameSpace/MyModule/etc/config.xml with the following content:

    <?xml version="1.0"?>
     <config>
    <modules>
        <MyNameSpace_MyModule>
            <version>0.1.0</version>
        </MyNameSpace_MyModule>
    </modules>
    <global>
        <!-- This rewrite rule could be added to the database instead -->
        <rewrite>
            <!-- This is an identifier for your rewrite that should be unique -->
            <!-- THIS IS THE CLASSNAME IN YOUR OWN CONTROLLER -->
            <mynamespace_mymodule_checkout_cart>
                <from><![CDATA[#^/checkout/cart/#]]></from>
                <!--
                    - mymodule matches the router frontname below
                    - checkout_cart matches the path to your controller
    
                    Considering the router below, "/mymodule/checkout_cart/" will be
                    "translated" to "/MyNameSpace/MyModule/controllers/Checkout/CartController.php" (?)
                -->
                <to>/mymodule/checkout_cart/</to>
            </mynamespace_mymodule_checkout_cart>
        </rewrite>
    </global>
    <!--
    If you want to overload an admin controller this tag should be <admin> instead,
    or <adminhtml> if youre overloading such stuff (?)
    -->
    <frontend>
        <routers>
            <mynamespace_mymodule>
                <!-- should be set to "admin" when overloading admin stuff (?) -->
                <use>standard</use>
                <args>
                    <module>MyNameSpace_MyModule</module>
                    <!-- This is used when "catching" the rewrite above -->
                    <frontName>mymodule</frontName>
                </args>
            </mynamespace_mymodule>
        </routers>
    </frontend>
    

    Note: The above didn’t work for me when I override catalog/product controller. I had to use:

                <from><![CDATA[#^catalog/product/#]]></from>
                <to>mymodule/mycontroller</to>
    

    (notice the missing leading slash)

    Since Magento 1.3 you can simply add your module to the frontend router. Rewrites are not neccessary any more:

      <?xml version="1.0" encoding="UTF-8"?>
     <config>
    <modules>
        <MyNameSpace_MyModule>
            <version>0.1.0</version>
        </MyNameSpace_MyModule>
    </modules>
    
    <frontend>
        <routers>
            <checkout>
                <args>
                    <modules>
                        <MyNameSpace_MyModule before="Mage_Checkout">MyNameSpace_MyModule</MyNameSpace_MyModule>
                    </modules>
                </args>
            </checkout>
        </routers>
    </frontend>
    

    Please note that before=”Mage_Checkout” will load your controller first if available and fall back to Magento’s if not.

    If the controller is in another folder, you’ll have to modify the code:
    app/code/local/MyNameSpace/MyModule/controllers/Checkout/CartController.php.

Replace

<MyNameSpace_MyModule before="Mage_Checkout">MyNameSpace_MyModule</MyNameSpace_MyModule>

with

    <MyNameSpace_MyModule before="Mage_Checkout">MyNameSpace_MyModule_Checkout</MyNameSpace_MyModule>
  1. Edit 'controllers/Checkout/CartController.php'

    Create app/code/local/MyNameSpace/MyModule/controllers/Checkout/CartController.php with the following content: (the only change to indexAction() is adding an error_log() call):

        <?php
           # Controllers are not autoloaded so we will have to do it manually:
           require_once 'Mage/Checkout/controllers/CartController.php';
           class MyNameSpace_MyModule_Checkout_CartController extends
                           Mage_Checkout_CartController
        {
        # Overloaded indexAction
         public function indexAction() {
        # Just to make sure
        error_log('Yes, I did it!');
        parent::indexAction();
        }
         }
    
    1. Edit 'app/etc/modules/MyNameSpace_All.xml' (This is to activate your module)

      true local

  2. Edit 'app/design/frontend/[myinterface]/[mytheme]/layout/checkout.xml' and add the following to use the same update handle as before:

     <mynamespace_mymodule_checkout_cart_index>
        <update handle="checkout_cart_index"/>
      </mynamespace_mymodule_checkout_cart_index>
    

    (Note that these tags seem to be case sensitive. Try using all lowercase if this isn’t working for you)

    [by Hendy: When I override catalog/product/view using the method described in this Wiki or here, I didn’t have to do the above. However, when using the 'cms way', I had to update the handle manually.]

    The above item did not work for me (2009-02-19 by Jonathan M Carvalho)

    I discovered that the file to change is app/design/frontend/[myinterface]/[mytheme]/layout/mymodule.xml

    Add the following lines:


    1. Point your browser to /checkout/cart/ In your PHP error log, you should find ‘Yes, I did it!’.

    You need to be extra precise with the rewrite regular expression because errors are very hard to find.

Solution 2

<Idigital_Idgeneral before="Mage_Checkout">Idgeneral_Checkout</Idigital_Idgeneral>

Should be

<Idigital_Idgeneral before="Mage_Checkout">Idigital_Idgeneral_Checkout</Idigital_Idgeneral>

or try moving your custom controller up to

../Idigital/Idgeneral/controllers/CartController.php

and use

<Idigital_Idgeneral before="Mage_Checkout">Idigital_Idgeneral</Idigital_Idgeneral>

There is also an error in your <modules> tag location. It should be:

<config>
    <modules>
        <idigital_idgeneral>
            <version>0.1.0</version>
        </idigital_idgeneral>
    </modules>
    <global>
    ...
    </global>   

    <frontend>
        ....
    </frontend>
...
</config>

i.e <modules> shouldn't be inside <global>

Here's a good tutorial on how to dump the config tree that Magento sees as XML: http://alanstorm.com/magento_config

Solution 3

I'm leaving this here for the next poor developer forced to work with this jalopy. Much of the instructions here are pasted from the magento docs which like its source, is a twisted labyrinth of misdirection. Okay enough complaints...

This worked for me in version 1.8

Create your namespace and module: /app/code/local/MyNameSpace/MyModule

Create your module config: /app/code/local/MyNameSpace/MyModule/etc/config.xml

<?xml version="1.0" ?>
<config>
<modules>
    <MyNameSpace_MyModule>
        <version>0.1.0</version>
    </MyNameSpace_MyModule>
</modules>
<frontend>
    <routers>
        <checkout>
            <args>
                <modules>
                    <MyNameSpace_MyModule before="Mage_Checkout">MyNameSpace_MyModule_Checkout</MyNameSpace_MyModule>
                </modules>
            </args>
        </checkout>
    </routers>
</frontend>

Create your controller: /app/code/local/MyNameSpace/MyModule/controllers/Checkout/CartController.php

<?php

require_once Mage::getModuleDir('controllers', 'Mage_Checkout').DS.'CartController.php';

class MyNameSpace_MyModule_Checkout_CartController extends Mage_Checkout_CartController
{
    public function indexAction() {
        // /var/log/debug.log should log the output
        Mage::log('cart index override', null, 'debug.log');

        // Call the parent class
        parent::indexAction();
    }
}

Enable your new module: /app/etc/modules/MyNameSpace_All.xml

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

That's all thats needed. Now go celebrate, you just polished a turd! ;)

Solution 4

This is a little notification on the include path of the controller.

This include path can cause errors if the Magento Compiler mode is turned on.

require_once 'Mage/Checkout/controllers/CartController.php';

Instead of that it is good to use

require_once Mage::getModuleDir('controllers', 'Mage_Checkout').DS.'CartController.php';

It will be safer.

Share:
16,296
ShaunTheSheep
Author by

ShaunTheSheep

Updated on June 21, 2022

Comments

  • ShaunTheSheep
    ShaunTheSheep almost 2 years

    I would like to do the above. Ive overridden many files in the past...block, model, helper....but this one eludes me.

    Can anyone see what im doing wrong here: (ive edited this code...to include some of the recomendations now...)

    Heres my folder structure (2 controller locations as a test):

    /Idigital/Idgeneral/etc/config.xml
    /Idigital/Idgeneral/controllers/Checkout/CartController.php
    /Idigital/Idgeneral/controllers/CartController.php
    

    Heres my config.xml:

    <?xml version="1.0"?>
    <config>
    <modules>
        <idigital_idgeneral>
        <version>0.1.0</version>
        </idigital_idgeneral>
    </modules>
    <global>
    <blocks>
            <idgeneral><class>Idigital_Idgeneral_Block</class></idgeneral>
        </blocks>
    </global>   
    
    <frontend>
        <routers>
                    <checkout>
                        <use>standard</use>
                        <args>
                            <modules>
                                <Idigital_Idgeneral before="Mage_Checkout">Idigital_Idgeneral_Checkout</Idigital_Idgeneral>
                            </modules>
                        </args>
                    </checkout>
               </routers>
           <layout>   
            <updates>   
                <idgeneral>   
                    <file>idigital.xml</file>   
                </idgeneral>   
            </updates>   
        </layout>
    </frontend>
    </config>
    

    Ihave placed my controller file in 2 locations to test. And heres the top of my FIRST controller file:

    require_once 'Mage/Checkout/controllers/CartController.php';
    class Idigital_Idgeneral_Checkout_CartController extends Mage_Checkout_CartController
    {
    
    
    public function testAction()
    {  
        var_dump('inside checkout/cart/test');exit; 
    }
    
    /**
     * Add product to shopping cart action
     */
    public function addAction()
    {
        blah...
    }
    

    Ans my second controller:

    require_once 'Mage/Checkout/controllers/CartController.php';
    class Idigital_Idgeneral_CartController extends Mage_Checkout_CartController
    {
    
    
    public function testAction()
    {  
        var_dump('inside cart/test');exit; 
    }
    
    /**
     * Add product to shopping cart action
     */
    public function addAction()
    {
        blah...
    }
    

    When i visit: /checkout/cart/add Im directed to the mage controller...not my local. (i have var_dump stmts in each..so i can see which is ran).

    When i visit /checkout/cart/test - i get a 404 When i visit /cart/add or cart/test - i get a 404 when i visit idgeneral/cart/test or idgeneral/cart/add - i get a 404