Magento - 多个类扩展同一个核心类

20

我相信我们都遇到过这样的情况,即您有多个扩展程序具有重写相同核心块/模型的块或模型。 我遇到的问题是: 如何控制Magento看到这些类的顺序?

例如,假设我们有两个扩展程序,其中包含以下两个类:

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

类 B

<catalog>
    <rewrite>
        <product_view>My_ClassB_Block_Catalog_Product_View</product_view>
    </rewrite>
</catalog>

我的/类B/块/目录/产品/视图.php

class My_ClassB_Block_Catalog_Product_View extends Mage_Catalog_Block_Product_View {}

--

推荐的解决方案是更改它们中的一个,使其继承另一个并将它们链接在一起(class A extends B {}class B extends C {}等):

我的/类A/块/目录/产品/视图.php

class My_ClassA_Block_Catalog_Product_View extends My_ClassB_Block_Catalog_Product_View {}

我的/ClassB/Block/Catalog/Product/View.php

class My_ClassB_Block_Catalog_Product_View extends Mage_Catalog_Block_Product_View {}

--

我遇到的问题是,Magento并不总是按照我期望的方式来处理它。我不知道它是按字母顺序还是有些随机性,但有时这种方法有效,有时则不行。 在某些情况下,Magento会优先考虑ClassB,并且所有对createBlock('catalog/product_view')的调用都创建ClassB的实例,完全绕过ClassA中的任何代码。

那么我的问题是:当两个不同的扩展程序都重写了核心catalog_product_view类时,我该如何控制哪个类由createBlock('catalog/product_view')实例化?

1个回答

33

当Magento获取用于特定块的类时,它会在合并的config.xml树中查找一个单一的节点


catalog/rewrite/product_view

多次重写的问题在于,由于Magento加载模块的XML、将其与配置树合并,然后加载另一个模型的方式,只能有一个节点存在。这意味着你只能让一个类别名解析到一个类名。

这就是位于

app/etc/modules/*.xml

这些文件在Magento中起着重要作用。它们告诉Magento应该使用哪些模块。此外还支持<depends>标签,可以让你指定某些模块依赖于其他模块,这意味着它们的config.xml会在另一个模块的config.xml之后加载。通过这种方式,您可以控制模块加载的顺序,从而控制合并的rewrite节点的“优先级”,进而可以知道哪个类需要成为继承链中的最终类。


谢谢,这是一个很好的解释。根据我的例子,我假设ClassA 在它的 config.xml 中会有一些像 <depends>ClassB</depends> 的东西,对吗?如果是这样,如果 ClassB 不存在怎么办?ClassA 是否仍然会被加载?如果不会的话,是否有任何通用的方法来解决这种情况? - Mageician
我认为你差不多懂了,但还差一点。Depends标签不应该放在config.xml中,而是应该放在Packagename_Modulename.xml文件中(可以查看其中现有文件的示例)。每个Magento模块可以为一个类定义一个重写。你看到的问题是因为多个模块为同一个类定义了重写。通过定义模块加载的顺序,您定义哪个模块“获胜”。然后,通过包含继承链中的所有类,您确保所有重写的功能都得以维护。 - Alana Storm
1
需要记住的一件事,可能会有所帮助。 如果两个重写覆盖了相同的方法,并且在某个时刻没有调用parent::method,即使A扩展了B,B扩展了C,解决方案也无法正常工作。 - Alana Storm
@AlanStorm 我完全按照你的示例操作,但无法使其工作。如果你有空的话,我非常感激你的帮助>< http://magento.stackexchange.com/questions/5143/how-to-rewrite-a-class-that-has-already-been-rewritten - Nick Rolando
我在etc/modules/ModuleB.xml中添加了<depends>ModuleA</depends>,但是类文件是按照ModuleB、ModuleA的顺序加载的。我没有收到任何错误提示,只是好奇为什么加载顺序不如预期? - Kostanos
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接