How to override abstract class in Magento?

If you are googling “override abstract class in magento” to find my blog, probably you already tried Mage::getModel(‘module/model_abstract’) as it worked for instantiatable classes.

The scenario when requires override an abstract class is overriding isActive() method in Mage_Shipping_Model_Carrier_Abstract. If Mage_Shipping_Model_Carrier_Abstract can be overridden, all carrier methods’ isActive logic can be changed without changing each instantiatable class. However, whether Magento overriding mechanism can work has a prerequisite –

All instantiation of parent class (in Mage namespace, to be overridden) are using Mage::getModel(‘module/model_class’), or $layout->getBlock(‘module/block_class’), or Mage::helper(‘module/helper_class’) instead of new Class_Name(). This guarantees Mage is the single entry point of class instantiation, then Mage Config can always instantiate an overridden class if any.

The codes coming with Magento follow this rule to the maximum. But when it comes to class inheritance, the rule is broken. Say Mage_Class_A extends Mage_Abstract_B, Mage_Class_A makes reference to Mage_Abstract_B using normal php syntax. It means even if Mynamespace_Abstract_B is overriding Mage_Abstract_B, Mage_Class_A still inherit from Mage_Abstract_B.

Come back to the question: How to override abstract class in Magento? Use Mage_Shipping_Model_Carrier_Abstract for example, to override isActive() method, you need to override all chid classes, e.g. Mage_Shipping_Model_Carrier_Flatrate, Mage_Shipping_Model_Carrier_Freeshipping, Mage_Shipping_Model_Carrier_Tablerate, etc.

You may not satisfied with the answer simply because you do not want to override every carrier class. Let me raise the question again: Is there another way to override abstract class in Magento? Yes! Copy Mage_Shipping_Model_Carrier_Abstract from app/code/core/Mage/Shipping/Model/Carrier to app/code/local/Mage/Shipping/Model/Carrier, do NOT change the class name, just change or add the methods as you need. This is a trick. Magento loads a class from several locations, and app/code/local comes before app/code/core. That’s why it works.

By the way, if php_apc is running, you must force apc to refresh for new class created in include_path. Please refer to “when does php apc refresh cache data” for details.

Leave a Reply

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