Article 1: Rewrites in Magento: problems & solutions

We all come across issues where there is a need to rewrite the same model (class) in two different modules. It usually happens with an extension which implements some logic changes, e.g., Mage_Sales_Model_Order class. At the same time, we have our own extension which implements other changes to the same model via rewrite as well. In order to keep both extensions operating, and to keep logic separated in order that extensions remain compatible with possible updates, we need to refer to several basics of Magento.

First, ensure that implementation of the required changes/logic is impossible without rewriting a class/model. Extending default functionality via observers by subscribing to some specific event is the best method. Moreover, you can subscribe to an event in a predefined scope:
– globally,
– only for admin area,
– only for front-end.

For this you simply need to add listener to a specific config section: adminhtml, frontend or global.

However, achieving a desired result only with the help of observers can become complicated, which can then necessitate a total rewrite of the specific class/model. To do this properly, we have to take a step back, look at loading fallback, and consider how it actually works.

Basically, Magento locates its extensions in 3 code pools:
– core,
– community and
– local.

In addition, Magento loads it’s module configuration in the following order:
1. Mage_All
2. Mage_*
3. All others in alphabetical order.

Once all configuration files are loaded, Magento will check the section of each config and will put modules after the ones mentioned in this section.

In this way, we ensure that our module is loaded only after the required modules have already been loaded. For example, let’s assume module A is rewritten by module B at the same time we need to implement some changes in the scope of module C. In this case, we will configure our module C with a dependence on module B and will specify rewriting the class from module A. The only thing which remains for us to do is to extend our class from the class located in module B, so that the existing changes in module B are preserved.

Here is a short example. Assuming that there are two modules which must be rewritten, i.e., Sales/Order model, this is how we can define these modules:

 

 

 

 

 

 

 

 

 

 

 

 

As per sample above, the configuration for CoreValue_AutoSupply will be loaded after Mage_Sales. CoreValue_Installment will be loaded after CoreValue_AutoSupply.

Here is a sample configuration of each module as it relates to rewrites.

CoreValue_AutoSupply.

 

 

 

 

CoreValue_Installment

 

 

 

Now let’s take a look at the actual php files.

 

 

 

And

 

 

 

This way we ensure that the instance of CoreValue_Installment_Model_Sales_Order will be created on Mage::getModel(‘sales/order’).

In both classes, i.e., CoreValue_Installment_Model_Sales_Order and CoreValue_AutoSupply_Model_Sales_Order, we are rewriting function _checkState():

 

 

 

 

 

 

 

 

 

As a result, each module encompasses changes applied by the Parent class and applies its own changes where required.

This method of applying as many rewrites as needed also saves original logic and time. It does not eliminate the need to be extremely careful when making these changes so as not to break any of the default functionalities.

Vladyslav Litovka
Senior Engineer, CoreValue

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *