如何在 Magento 中设置事件观察者的排序顺序?

问题描述 投票:0回答:2

我已经在

catalog_product_save_after
事件上创建了一个观察者,但它似乎在运行
applyAllRulesOnProduct()
方法的目录规则观察者之前被调用。我需要在
applyAllRulesOnProduct()
运行后打电话给我的。这些观察员的顺序是如何选择的?

events magento magento-1.9 observers magento-1.4
2个回答
36
投票

就像 Magento 中的许多答案一样,答案很复杂。还有“两个”可能与您的具体情况相关的问题。这会很长——跳到最后查看无上下文的简短版本。 模块加载顺序

没有办法

显式地

设置观察者排序顺序。 Magento 将按照事件“合并到全局配置”中的顺序运行这些事件。因此,虽然您无法具体控制事件的顺序,但您可以通过使用 <depends/> XML 声明文件中的 app/etc/modules 标签来控制 Magento 加载和合并模块的顺序。 例如,在

Mage_Api2.xml
文件中
<!-- File: app/etc/modules/Mage_Api2.xml -->
<config>
    <modules>
        <Mage_Api2>
            <active>true</active>
            <codePool>core</codePool>
            <depends>
                <Mage_Core />
                <Mage_Oauth />
            </depends>
        </Mage_Api2>
    </modules>
</config>

作者指出,

Mage_Api2
模块

依赖于
Mage_Core

Mage_Oauth
模块。这意味着 Mage_Api2
config.xml
文件将被合并到
config.xml
Mage_Core
Mage_Oauth
文件之后。这意味着 Mage_Api2 中定义的事件将在
Mage_Core
Mage_Oauth
中定义的事件之后运行。
缺少
<depends/>
节点,模块加载规则为

所有

核心

模块都在非核心模块之前加载


    其余模块按字母顺序加载。
  1. 让您的模块依赖于

    Mage_CatalogRule
  2. 模块(其中定义了
  3. applyAllRulesOnProduct

    观察者方法)是一种很好的形式。

    但是
  4. ,这不是必需的,因为所有核心模块都会在非核心模块之前加载。

那是因为事件观察器方法的运行顺序还有另一个因素。

区域顺序
除了模块顺序之外,您还需要考虑您的事件观察器定义在哪个区域。也就是说,当您在 Magento 中创建事件观察器时,您会放入一些看起来像这样的

config.xml

<config> <!-- ... --> <global> <!-- ... --> <events> <catalog_product_save_after> <observers> <abc_abc> <class>abc_abc/observer</class> <method>test</method> </abc_abc> </observers> </catalog_product_save_after> </events> </global> </config>

在上面的示例中,该事件观察者已在 global 区域中定义(因为它位于

<global/>
节点内)。这意味着观察者将在 Magento 的

both
 
frontend

adminhtml
区域中运行。但是,也可以
限制
您的活动运行的区域。例如,您提到的catalogrule活动定义在
adminhtml
区域
<!-- #File: app/code/core/Mage/CatalogRule/etc/config.xml -->
<config>
    <!-- ... -->
    <adminhtml>
        <!-- ... -->
        <events>
            <!-- ... -->
            <catalog_product_save_after>
                <observers>
                    <catalogrule>
                        <class>catalogrule/observer</class>
                        <method>applyAllRulesOnProduct</method>
                    </catalogrule>
                </observers>
            </catalog_product_save_after>
        </events>
    </adminhtml>
</config>

这意味着该事件观察器将仅在 Magento 的后端 
adminhtml
区域中运行。换句话说,它仅在您在后端管理控制台中保存事件时运行。

是我认为你的问题所在,因为在现代版本的Magento(可能还有旧版本)中,来自
<global/>

节点的事件观察者总是在

<adminhtml/>
节点中的事件观察者之前运行。我的猜测是您的事件位于

<global/>

节点中。尝试将其移动到 <adminhtml/> 节点。

简短版本
:确保您的模块
<depends/>
位于
Mage_CatalogRule
模块上,并将事件观察器配置移动到模块的

<adminhtml/>

中的config.xml节点。

    
我知道这是一个旧线程,但如果有人想更改其模块的加载顺序:

/etc/modules/* 文件夹按字母顺序加载,因此,如果模块的文件位于第一个(或最后一个),则会相应地按该顺序加载 - 因此,您可以将 /etc/modules/Namespace_Module.xml 重命名为 /etc/modules /ZZZNamespace_Module.xml 最后加载它(假设没有任何其他带有 ZZZZ 的模块...)

另外,为了澄清,模块中的其他所有内容都可以保持不变(代码/文件和文件夹名称),您只需更改这个文件即可,该文件可以命名为您选择的任何名称。


3
投票

© www.soinside.com 2019 - 2024. All rights reserved.