Magento – rewriting model, block or helper

Magento is more than e-commerce platform – it’s a great framewrok based on Zend Framework. One of its best features is modularity (far better then in ZF) and possibility of overriding core classes.You can rewrite blocks, models and helpers with the use of configuration file. This way you get new functionality by enabling your custom module leaving original code intact. Suppose you want to change behavior of Mage_Catalog_Model_Product class. You can create your own class (say MageDev_Catalog_Model_Product) extending core class. Module should be located in the local pool – here goes directory structure:

app/code/local/MageDev/Catalog – contains module files
app/code/local/MageDev/Catalog/etc – here go configuration files
app/code/local/MageDev/Catalog/Model – custom class extending Mage_Catalog_Model_Product will be stored in this directory

Rewrites are defined in app/code/local/MageDev/Catalog/etc/config.xml file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0"?>
<config>
    <modules>
         <MageDev_Catalog>
            <version>0.0.1</version>
        </MageDev_Catalog>
    </modules>
    <global>
        <models>
            <catalog>
                <rewrite>
                    <product>MageDev_Catalog_Model_Product</product>
                </rewrite>
            </catalog>
        </models>
   </global>
</config>

Now you just need to activate the module in app/etc/modules/MageDev_Catalog.xml file:

1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0"?>
<config>
    <modules>
        <MageDev_Catalog>
            <active>true</active>
            <codePool>local</codePool>
	    <depends>
                <Mage_Catalog />
	    </depends>
        </MageDev_Catalog>
    </modules>
</config>

From now on all calls to

Mage::getModel('catalog/product');

will return MageDev_Catalog_Model_Product instance (if this class is defined in app/code/local/MageDev/Catalog/Model/Product.php file).

Suppose I’d like to extend MageDev_Catalog_Model_Product_Class and don’t want to change existing module. To do this I have to create another module. Let’s have a look at the new module config file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0"?>
<config>
    <modules>
         <MageDev_NewCatalog>
            <version>0.0.1</version>
        </MageDev_NewCatalog>
    </modules>
    <global>
        <models>
            <catalog>
                <rewrite>
                    <product>MageDev_NewCatalog_Model_Product</product>
                </rewrite>
            </catalog>
        </models>
   </global>
</config>

At this stage Magento during initialization of modules has to choose which class to use to rewrite Mage_Catalog_Model_Product. In order to solve this issue Magento sorts rewrites using dependencies. You can define dependency in config file located at app/etc/modules directory. For the two classes presented above these files might look like:

app/etc/modules/MageDev_Catalog.xml:

1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0"?>
<config>
    <modules>
        <MageDev_Catalog>
            <active>true</active>
            <codePool>local</codePool>
	    <depends>
                <Mage_Catalog />
	    </depends>
        </MageDev_Catalog>
    </modules>
</config>

app/etc/modules/MageDev_NewCatalog.xml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0"?>
<config>
    <modules>
        <MageDev_NewCatalog>
            <active>true</active>
            <codePool>local</codePool>
	    <depends>
		<Mage_Core />
                <Mage_Catalog />
                <MageDev_Catalog />
	    </depends>
        </MageDev_NewCatalog>
    </modules>
</config>

Now Magento will firstly load MageDev_Catalog and later MageDev_NewCatalog using rewrites from the latest module.

It’s worth to note that when new module is installed you may need to change dependency in your config file to address rewrites done by the new module. This is another good reason to install new modules in your test environment.

17 thoughts on “Magento – rewriting model, block or helper”

  1. Hi Cris,

    Thanks for interest. As you may know there’s no official Magento guide for developers so you need to make your own exploration of the source code. Although at first glance it might seem quite complex, after some time you’ll discover how well designed the Magento code is.

  2. Really helpful.
    Thanks a lot ;-)

    It works too for the blocks you just need to replace the tag ‘models’ by ‘blocks’ (and close it of course) in the config.xml

  3. Hello George,

    Here’s a part of config file that rewrites onepage checkout:

      <global>
        <blocks>
          <checkout>
            <rewrite>
              <onepage>MageDev_Checkout_Block_Onepage</onepage>
            </rewrite>
          </checkout>
        </blocks>
      </global>

    If you want to rewrite onepage checkout steps you should rewrite blocks in app/code/core/Mage/Checkout/Block/Onepage/ directory. Hope that helps.

  4. hello Admin,

    i need to rewrite Magento’s core Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection as Mycompany_Catalog_Model_Resource_Eav_Mysql4_Product_Collection

    For that i created a new module ‘Mycompany’ under app/code/local/. Now i placed this collection.php file under Mycompany_Catalog_Model_Resource_Eav_Mysql4_Product_Collection
    under app/code/local/Mycompany/Catalog/Model/Resource/Eav/Mysql4/Product/.

    I enabled this module in app/etc/modules/Mycompany_All.xml

    In app/code/local/Mycompany/etc/config.xml i added following xml code:

    Eyemagine_Catalog_Model_Resource_Eav_Mysql4_Product_Collection

    but still this core model collection is not being rewrite.

    What i am doing wrong, please guide me :(

    spent big time on this issues but no luck … Need some guidelines.

  5. Hello Randy,

    I can’t see xml code in your previous message but I guess it was overriding catalog in a way similar to:

     <catalog>
       <rewrite>
        <resource_eav_mysql4_product_collection>Mycompany_Catalog_Model_Resource_Eav_Mysql4_Product_Collection</resource_eav_mysql4_product_collection>
       </rewrite>
     </catalog>

    while it works only when you override catalog_resource_eav_mysql4:

     <catalog_resource_eav_mysql4>
       <rewrite>
        <product_collection>Mycompany_Catalog_Model_Resource_Eav_Mysql4_Product_Collection</preoduct_collection>
       </rewrite>
     </catalog_resource_eav_mysql4>

    To find out the model id (used with Mage::getModel(model_id)) you need to use in rewrite declaration go to config file of module in which original class is located (in case of Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection it is app/code/core/Mage/Catalog/etc/config.xml). Then try to locate the longest prefix of the class inside

    <models />

    tag.

            <models>
                <catalog>
                    <class>Mage_Catalog_Model</class>
                    <resourceModel>catalog_resource_eav_mysql4</resourceModel>
                </catalog>
     
                <catalog_resource_eav_mysql4>
                    <class>Mage_Catalog_Model_Resource_Eav_Mysql4</class>
                    <entities>
                        <product>
                            <table>catalog_product_entity</table>
                        </product>
                        <category>
                            <table>catalog_category_entity</table>
                        </category>
                        <category_product>
                            <table>catalog_category_product</table>
                        </category_product>
                        <category_product_index>
                            <table>catalog_category_product_index</table>
                        </category_product_index>
                        <compare_item>
                            <table>catalog_compare_item</table>
                        </compare_item>
     
                        <product_website>
                            <table>catalog_product_website</table>
                        </product_website>
     
                        <product_enabled_index>
                            <table>catalog_product_enabled_index</table>
                        </product_enabled_index>
     
                        <product_link_type>
                            <table>catalog_product_link_type</table>
                        </product_link_type>
     
                        <product_link>
                            <table>catalog_product_link</table>
                        </product_link>
     
                        <product_link_attribute>
                            <table>catalog_product_link_attribute</table>
                        </product_link_attribute>
                        <product_link_attribute_decimal>
                            <table>catalog_product_link_attribute_decimal</table>
                        </product_link_attribute_decimal>
                        <product_link_attribute_int>
                            <table>catalog_product_link_attribute_int</table>
                        </product_link_attribute_int>
                        <product_link_attribute_varchar>
                            <table>catalog_product_link_attribute_varchar</table>
                        </product_link_attribute_varchar>
     
                        <product_super_attribute>
                            <table>catalog_product_super_attribute</table>
                        </product_super_attribute>
                        <product_super_attribute_label>
                            <table>catalog_product_super_attribute_label</table>
                        </product_super_attribute_label>
                        <product_super_attribute_pricing>
                            <table>catalog_product_super_attribute_pricing</table>
                        </product_super_attribute_pricing>
                        <product_super_link>
                            <table>catalog_product_super_link</table>
                        </product_super_link>
     
                        <product_attribute_tier_price>
                            <table>catalog_product_entity_tier_price</table>
                        </product_attribute_tier_price>
     
                        <product_attribute_media_gallery>
                            <table>catalog_product_entity_media_gallery</table>
                        </product_attribute_media_gallery>
     
                        <product_attribute_media_gallery_value>
                            <table>catalog_product_entity_media_gallery_value</table>
                        </product_attribute_media_gallery_value>
     
                        <product_option>
                            <table>catalog_product_option</table>
                        </product_option>
                        <product_option_price>
                            <table>catalog_product_option_price</table>
                        </product_option_price>
                        <product_option_title>
                            <table>catalog_product_option_title</table>
                        </product_option_title>
                        <product_option_type_value>
                            <table>catalog_product_option_type_value</table>
                        </product_option_type_value>
                        <product_option_type_price>
                            <table>catalog_product_option_type_price</table>
                        </product_option_type_price>
                        <product_option_type_title>
                            <table>catalog_product_option_type_title</table>
                        </product_option_type_title>
     
                        <category_flat>
                            <table>catalog_category_flat</table>
                        </category_flat>
     
                        <product_flat>
                            <table>catalog_product_flat</table>
                        </product_flat>
                    </entities>
                </catalog_resource_eav_mysql4>
            </models>

    In xml above you can locate

    <class>Mage_Catalog_Model_Resource_Eav_Mysql4</class>

    inside

    <catalog_resource_eav_model />

    id so you should use this id to rewrite classes which names starts with Mage_Catalog_Model_Resource_Eav_Mysql4.
    Hope this helps.

  6. Hi I’ve been using Magento for awhile now still kind of a noob I was wondering if there is anyway to make a grouped product name show up in the cart with the simple products name?

  7. Can there be a simple solution. I just want to use php code connecting sql data and fetch the details and show them in products descriptions pages. Each product will have different results, hence want to run php configured for each products. cannot use static block to call php in product description. The above solution looks bit complicated. Cannot find even the folder app/code/local/MageDev/Catalog. Seems like new magento versions have some changes in structure.

Comments are closed.