Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Magento - multiple classes extending same core class

Tags:

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:

Class A

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 {}

Class B

<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?

like image 467
Mageician Avatar asked Sep 21 '11 14:09

Mageician


1 Answers

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.

like image 124
Alan Storm Avatar answered Oct 13 '22 23:10

Alan Storm