I'm sure we've all run into a situation where you have multiple extensions with a block or model that rewrites the same core block/model. The problem I've run into is this: How do you control the order in which Magento sees these classes?
For example, let's say we have 2 extensions with the following 2 classes:
config.xml
<catalog>
<rewrite>
<product_view>My_ClassA_Block_Catalog_Product_View</product_view>
</rewrite>
</catalog>
My/ClassA/Block/Catalog/Product/View.php
class My_ClassA_Block_Catalog_Product_View extends Mage_Catalog_Block_Product_View {}
<catalog>
<rewrite>
<product_view>My_ClassB_Block_Catalog_Product_View</product_view>
</rewrite>
</catalog>
My/ClassB/Block/Catalog/Product/View.php
class My_ClassB_Block_Catalog_Product_View extends Mage_Catalog_Block_Product_View {}
The recommended solution is to change one of them so they extend the other and chain them together (class A extends B {}
, class B extends C {}
, etc):
My/ClassA/Block/Catalog/Product/View.php
class My_ClassA_Block_Catalog_Product_View extends My_ClassB_Block_Catalog_Product_View {}
My/ClassB/Block/Catalog/Product/View.php
class My_ClassB_Block_Catalog_Product_View extends Mage_Catalog_Block_Product_View {}
The problem I've run into is that Magento doesn't necessarily see it that way. I don't know if it's alphabetical or somewhat random, but sometimes this works and sometimes it doesn't. In some cases, Magento gives priority to ClassB and all calls to createBlock('catalog/product_view')
create an instance of ClassB, completely bypassing any code in ClassA.
So my question is this: How do I control which class gets instantiated by createBlock('catalog/product_view')
when 2 different extensions both rewrite the core catalog_product_view class?
When Magento fetches the class to use for a particular block, it looks inside the merged config.xml
tree for a single node at
catalog/rewrite/product_view
The problem with multiple rewrites is, only one node can be there due to the way Magento loads a module's XML, merges it with the config tree, and then loads another model. This means you can only ever have one class alias resolve to one class name.
That's where the files in
app/etc/modules/*.xml
come into play. These files tell Magento which modules to use. They also have support for a <depends>
tag. This tag allows you to say certain modules depend on another module, which means their config.xml
will be loaded after another module's config.xml
. In this way, you can control which order the modules are loaded in, and therefore control which merged rewrite node "wins", which in turn will allow you to know which class needs to be the final in your inheritance chain.