Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.8k views
in Technique[技术] by (71.8m points)

php - Magento - multiple classes extending same core class

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...