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!