Category Archives: Class Override

Oh !! Class override, it is a great and really big feature of magento. By this you can easily extend any magento feature without touching core code. So you have no headache about magento upgrade.

Magento CMS controller override / cms page controller override in magento

Whoops !! what Magento’s bad ? Ofcourse documentation. Bullshit documentation !!. Magento have features but without documentation !!!!

Magento cms module has some nice functionality. Using Magento’s 404 event handlers of cms module you can integrate 3rd Party CMS Content such Expression Engine, Drupal, wordpress, joomla etc within Magento.
Magento is robust and have some great nice features but still their documentation is very poor. In Magento forum and wiki they just demonstrate “how to override a controller?” as a general theory. But how to override exceptional cms and api controller is not clear. Even Magento did not mention anything about exceptionality of cms and api module. Cms module calls internally. So we cannot override cms module’s controller using as usual magento controller override process. Here I described how to overrite cms index and page controller.

Target : Override Cms module’s Index (Mage_Cms_IndexController) controller and Page (Mage_Cms_IndexController) controller.

Hint: IndexController is responsible for displaying errors (404) & home page and PageController is responsible for displaying pages like ‘about-us’, keep this in mind as you may want to rewrite which controller.

Ok, let’s start—

Firsty, it’s wise to name your module differently to avoid name collisions. Lets call my module M4U_Mycms for that case.

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

Now create config xml for new module in app/code/local/M4U/Mycms/etc/config.xml. Here as example I mention xml to override norouteAction method of IndexController.

<?xml version="1.0"?>
<config>

    <modules>
        <M4U_Mycms>
            <version>0.1.0</version>
        </ M4U_Mycms>
    </modules>
   
    <frontend>
        <routers>
            <mycms>
                <use>standard</use>
                <args>
                    <module> M4U_Mycms</module>
                    <frontName>mycms</frontName>
                </args>
            </mycms>
        </routers>
</frontend>	
	
<global>
     <routers>
            <cms>
                <rewrite>
                    <index>
                        <to>M4U_Mycms/index</to>
                        <override_actions>true</override_actions>
                        <actions>
                           <noroute><to> M4U_Mycms/index/noroute</to></noroute>
                        </actions>
                    </index>
                </rewrite>
            </cms>
        </routers>

       </global>
</config>

N.B: Please take care about tag. It will let you create additional NEW actions that will be rewritten to new controller.

Now create new index controller in app/code/local/M4U/Mycms/controllers/IndexController.php and update noRouteAction method.


require_once "Mage/Cms/controllers/IndexController.php";
class M4U_Mycms_IndexController extends Mage_Cms_IndexController
{
    public function noRouteAction($coreRoute = null)
    {
        //modify this method as you need
        
        exit('Yes, I can successfully override cms/index noRoute method ');
		
        //$this->getResponse()->setHeader('HTTP/1.1','404 Not Found');
        //$this->getResponse()->setHeader('Status','404 File not found');
       // $pageId = Mage::getStoreConfig('web/default/cms_no_route');
       // if (!Mage::helper('cms/page')->renderPage($this, $pageId)) {
       //     $this->_forward('defaultNoRoute');
       // }
    }
}

Done !!

When any requested class/method is not found in system then Magento throw “404 Not Found” error using noRouteAction method. So we can test this method calling any undefined page url like http://127.0.0.1/magento/index.php/undefinedpagename. Here, undefinedpagename is not a defined page in magento.

ok, now run http://127.0.0.1/magento/index.php/undefinedpagename and if you get result
“Yes, I can successfully override cms/index noRoute method” in browser then noRouteAction method override is success.

Here i just describe noRouteAction method modification system. Like this way you can modify all of the indexController and pageController method.

You will get source code in right side box widget. Download code and enjoy your work.

if need any help let me know.

Magento Helper override rules

Sometimes Magento uses helper class to retrieve some of the help info such url, name, group etc. So you have to override helper class when you want to change any url or something else. Helper class override  is similar to block and model override. Here i described details about helper override with example.  Here i show how to override helper class Mage_Customer_Helper_Data.

1. At first create new module to process override work and write below code in app/etc/modules/M4U_Customer.xml

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

2. Do configuration in app/code/local/M4U/Customer/etc/config.xml

<?xml version="1.0"?>
    <config>
        <modules>
            <M4U_Customer>
                <version>0.1.0</version>
            </M4U_Customer>
        </modules>

        <global>
           <helpers>
              <customer>
                  <rewrite>
                      <data>M4U_Customer_Model_Customer</data>
                 </rewrite>
              </customer>
           </helpers>
        </global>
  </config>

3. Now write your new helper class M4U_Customer_Helper_Data and define all other override methods

class M4U_Customer_Helper_Data extends Mage_Customer_Helper_Data
{
   // override existing method
  * Retrieve customer register form post url
  public function getRegisterPostUrl()
    {
        return $this->_getUrl('customer/account/create2');
    }

    //write new function
    public function getRegisterPostUrl2()
    {
        return $this->_getUrl('customer/account/createpost');
    }
}

I think who is familiar with Magento override theory, helper override is easy for them. Just try your self. If you face any problem then just make a post. I will try to help you.

Magento Block override rules

Magento Block override rule is similar as helper and model override. Magento follows MVC pattern but Block is the extra layer in Magento. Block class render data for a particular template block. Magento introduces great blocking system in template design system.

Blocks are a way by which Magento distinguishes the array of functionalities in the system and creates a modular way to manage it from both visual and functional stand point. There are two types of blocks and they work together to create the visual output.

* Structural Blocks
These are blocks created for the sole purpose of assigning visual structure to a store page such as header, left column, main column and footer.
* Content Blocks
These are blocks that produce the actual content inside each structural block. They are representations of each feature functionality in a page and employs template files to generate (X)HTML to be inserted into its parent structural block. Category list, mini cart, product tags and product listing…etc are each its own content block.

Instead of including template after template as a typical eCommerce application would in order to gather the whole (X)HTML output, Magento gathers and arranges page content through blocks.

How to override a block ?:
Here i used Customer module as example. And here i describe various customer block class override system as example.
a) Customer register form block (Mage_Customer_Block_Form_Register)
b) Customer view form block (Mage_Customer_Block_Form_View)
c) Customer address edit block (Mage_Customer_Block_Address_Edit)
d) Customer account dashboard info block (Mage_Customer_Block_Account_Dashboard_Info)
e) Customer account dashboard address block (Mage_Customer_Block_Account_Dashboard_Address)
f) Customer widget name block (Mage_Customer_Block_Widget_Name)

Lets start step by step…………

1. At first create new module to process override work and write below code in app/etc/modules/M4U_Customer.xml

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

2. Configure in app/code/local/M4U/Customer/etc/config.xml. Here, I mention 5/6 block override syntax as example. Keep only those classes whose classes you want to override.

<?xml version="1.0"?>
    <config>
        <modules>
            <M4U_Customer>
                <version>0.1.0</version>
            </M4U_Customer>
        </modules>

        <global>
           <blocks>
              <customer>
                  <rewrite>
                      <form_register>M4U_Customer_Block_Form_Register</form_register>
                      <form_view>M4U_Customer_Block_Form_View</form_view>
                      <address_edit>M4U_Customer_Block_Address_Edit</address_edit>
                      <account_dashboard_address>M4U_Customer_Block_Account_Dashboard_Address</account_dashboard_address>
                      <account_dashboard_info>M4U_Customer_Block_Account_Dashboard_Info</account_dashboard_info>
                      <widget_addressname>M4U_Customer_Block_Widget_Name</widget_addressname>
                 </rewrite>
              </customer>
           </blocks>
        </global>
  </config>

3. Now write your new block class and define all override methods

a) Customer register form block override

class M4U_Customer_Block_Form_Register extends Mage_Customer_Block_Form_Register
{
   // override existing method
  //write new function
    public function newmethod()
    {
        return true;
    }
}

b) Customer view form block (Mage_Customer_Block_Form_View)

class M4U_Customer_Block_Form_View extends Mage_Customer_Block_Account_Dashboard
{
   // override existing method
  //write new function
    public function newmethod()
    {
        return true;
    }
}

c) Customer address edit block (Mage_Customer_Block_Address_Edit)

class M4U_Customer_Block_Address_Edit extends Mage_Customer_Block_Address_Edit
{
   // override existing method
  public function getAddressStatus()
   {
      return $this->getRequest()->getParam('address');
   }

  //write new function
    public function newmethod()
    {
        return true;
    }
}


d) Customer account dashboard info block (Mage_Customer_Block_Account_Dashboard_Info)

class M4U_Customer_Block_Account_Dashboard_Info extends Mage_Customer_Block_Account_Dashboard_Info
{
   // override existing method
  //write new function
    public function newmethod()
    {
        return true;
    }
}

e) Customer account dashboard address block (Mage_Customer_Block_Account_Dashboard_Address)

class M4U_Customer_Block_Account_Dashboard_Address extends Mage_Customer_Block_Account_Dashboard_Address
{
   // override existing method
  //write new function
    public function newmethod()
    {
        return true;
    }
}

f) Customer widget name block (Mage_Customer_Block_Widget_Name)

class M4U_Customer_Block_Widget_Name extends Mage_Customer_Block_Widget_Abstract
{
   // override existing method
  public function showMiddlename()
    {
        return $this->_showConfig('middlename_show');
    }

  //write new function
    public function newmethod()
    {
        return true;
    }
}

Magento Model override rules

I worked on various e-commerce open-source such x-cart, zen-cart but Magento is the special one for his great convention and high thought system. Override system was the great thinking of Magento team. Using Magento override rules you can can easily extends any Magento feature or can add new modules. Magento follows MVC pattern. Model is one of the main pattern of MVC. Usually model is used for database connectivity and for various logical coding. Mogento also use model for same purpose. Every module of Magento have his own model class. But you can extend or modify any existing model class by following Magento override rules.

Suppose, to fulfill your project requirements you need to change or enhance customer model class. You can change code in Mage_CUstomer_Model_Customer class. But it’s not a good practice of Magento customization and when upgrade your Magento version then there have a chance of remove your customized code. Means you will lost your changes. Really it will be pathetic for you !!!!! So we should follow magento override rules. Here i tried to clear how you can easily override your various model classes.

Override Customer Model class:

At first create new module to do override work and write below code in app/etc/modules/M4U_Customer.xml

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

Do configuration in app/code/local/M4U/Customer/etc/config.xml

<?xml version="1.0"?>
    <config>
        <modules>
            <M4U_Customer>
                <version>0.1.0</version>
            </M4U_Customer>
        </modules>

        <global>
           <models>
              <customer>
                  <rewrite>
                      <customer>M4U_Customer_Model_Customer</customer>
                 </rewrite>
              </customer>
           </models>
        </global>
  </config>

Now write your new model class M4U_Customer_Model_Cutomer and define all override method

class M4U_Customer_Model_Customer extends Mage_Customer_Model_Customer
{
   // override existing method
   public function validate()
    {
       // Define new validate rules. From now magento call this validate method instead of existing method
        //return $errors;
        return true;
    }

    // You can create new method as you needed.
    public function newMethod()
    {
       // function logic
    }
}

Override Address Model class :

Every thing is same as customer model override system. Just put a line in etc/config.xml.

<?xml version="1.0"?>
    <config>
        <modules>
            <M4U_Customer>
                <version>0.1.0</version>
            </M4U_Customer>
        </modules>

        <global>
           <models>
              <customer>
                  <rewrite>
                      <customer>M4U_Customer_Model_Customer</customer>
                      <address>M4U_Customer_Model_Address</address>
                  </rewrite>
              </customer>
           </models>
        </global>
  </config>

Now write your new model class M4U_Customer_Model_Address and define all override method

class M4U_Customer_Model_Address extends Mage_Customer_Model_Address
{
   // override existing method
   public function validate()
    {
       // Define new validate rules. From now magento call this validate method instead of existing method
        //return $errors;
        return true;
    }

    // You can create new method as you needed.
    public function newMethod()
    {
       // function logic
    }
}

Override Customer Entity Model class :

Define app/code/M4U/Customer/etc/config.xml like below. Here you will get clear concept how to override various model class in same xml.

<?xml version="1.0"?>
    <config>
        <modules>
            <M4U_Customer>
                <version>0.1.0</version>
            </M4U_Customer>
        </modules>

        <global>
           <models>
              <customer>
                  <rewrite>
                      <customer>M4U_Customer_Model_Customer</customer>
                      <address>M4U_Customer_Model_Address</address>
                  </rewrite>
              </customer>
              <customer_entity>
                  <rewrite>
                      <address>M4U_Customer_Model_Entity_Address</address>
                  </rewrite>
              </customer_entity>
           </models>
        </global>
  </config>
class M4U_Customer_Model_Entity_Address extends Mage_Customer_Model_Entity_Address
{
    protected function _afterSave(Varien_Object $address)
    {
        // Write your code
    }
}

Now just try your self. If you face any problem then make a post. I will try to help you.

What is class override in Magento ?

Magento e-commerce support class override theory. Override means “suspension of an automatic function”. That means you can overlap any magento function using your own modified function by following magento’s class override theory.
For example, suppose you want to extend magento registration system, so need to change registerPostAction() function in Mage_Customer class. Magento suggest you should not touch any magento core code to extend any feature. But you can extend or change any classes as you needed just creating a new class outside of Mage_Core. For this you should follow magento class override rules. By following rules you can create a new customer class like M4U_Customer outside of core. And write your extended function registerPostAction() in M4U_Customer class. Now, when you call registerPostAction() function then Magento automatically will render your own function and suspend calling of Mage_Customer function. Its called magento class overriding.

Magento is unique in opensource world for it’s class override facilities. If you customize magento by following override rules then you can easily upgrade magento version on your live site.

To know about specific class override rules you can see controller override, model override, block override, helper override, etc xml override posts in this blog.