Friday, September 9, 2011

Why can't you override some classes in Magento?

I saw a lot of pleaople having this issue on the magento forum.
Some classes cannot pe overridden the clasical way.
First of all, this is the classical way: http://magedev.com/2009/06/03/magento-overriding-model-block-or-helper/
It's a old post but is still very useful and it saved me a lot of time in the past.

But there are some classes that cannot be overridden this way.
Here are some examples: Mage_Core_Block_Template, Mage_Core_Model_Abstract, Varien_Object, Mage_Core_Block_Abstract, Mage_Customer_Model_Address_Abstract and the list can go on.

Basically these are the classes that are not instantiated in the application. They are used just to create other classes with common behavior.

But if you need to override these classes here are your 2 options. (I only know 2. If you know others please share.)

1. Quick and dirty. Using this there is a small change that on an upgrade you will lose some functionality or even crash. but don't dismiss it yet. Using the second method it's even worse.
The basics of this method is that Magento uses an autoloader to load classes. The autoloader first searches in the 'app/code/local' folder then in 'app/code/community' and in the end 'app/code/core'.
What you have to do is to copy the class you want to override in the app/code/local folder.
Let's take as an example Mage_Core_Model_Abstract. You need to copy the file app/code/core/Mage/Core/Model/Abstract.php to app/code/local/Mage/Core/Model/Abstract.php.
You can make the changes in this file.
Now when all the other classes that extend this are declared
class Mage_Customer_Model_Customer extends Mage_Core_Model_Abstract
{ ...}
they will extend your own class because when searching for Mage_Core_Model_Abstract magento will find it in your app/code/local folder and will stop looking for the one in app/code/core.

2. Long and 'clean?' - You can still lose functionality on the upgrade, it's more time consuming
and a bigger source of errors.
You can create your own class. Let's call it 'Mycomp_Core_Model_Abstract' that extends Mage_Core_Model_Abstract and put your custom code in this.
In order for this to affect all the other models that extend Mage_Core_Model_Abstract you need to override each class that extend Mage_Core_Model_Abstract and make them extend the class you just created. Using the same example as above..
class Mycomp_Customer_Model_Customer extends Mycomp_Core_Model_Abstract
{ ...}
But now you need to copy all the functionality from Mage_Customer_Model_Customer to Mycomp_Customer_Model_Customer because, unfortunately, PHP does not support multiple inheritance (yet?)
And for Mage_Core_Model_Abstract there are around 70 classes that extend it. You have to do this 70 times.

Pick your own method. I strongly recommend the first one.
I hope this helps someone.

Cheers,
Marius.

4 comments:

  1. Wow, Thanks a lot. I spent an entire day to figure out this.

    ReplyDelete
  2. Thank you very much Marius for provide such a nice help

    ReplyDelete
  3. is it ok if i use first one in magento projects?

    ReplyDelete
    Replies
    1. Sometimes you have no other choice. Actually you should you the first approach. The second is not actually an option. I presented it here just to show how hard is to do it.

      Delete