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

时间:2013-04-10 19:20:08

标签: magento events observers

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

2 个答案:

答案 0 :(得分:30)

与Magento中的许多人一样,答案很复杂。您的具体情况可能还有两个可能存在的问题。这将是很长的 - 跳到最后的无环境短版本。

模块装货订单

无法显式设置观察者排序顺序。 Magento将按照他们merged into the global configuration的顺序浏览事件。因此,虽然您无法专门控制事件的顺序,但可以控制Magento加载的顺序并使用<depends/> XML声明中的app/etc/modules标记合并模块文件。

例如,在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_Api2Mage_Core模块上指出Mage_Oauth模块取决于。这意味着Mage_Api2的{​​{1}}文件将在config.xmlconfig.xml的{​​{1}}文件之后合并。这意味着Mage_Core中定义的事件将在Mage_OauthMage_Api2中定义的事件之后运行。

缺少Mage_Core节点,模块加载规则为

  1. 所有核心模块在非核心模块之前加载

  2. 其余模块按字母顺序加载。

  3. 让模块依赖于Mage_Oauth模块(定义{{​​1}}观察者方法的位置)是一种很好的形式。 然而,它不应该是必要的,因为所有核心模块都是在非核心模块之前加载的。

    这是因为在命令事件中有另一个因素运行观察者方法。

    区域订单

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

    <depends/>

    在上面的示例中,此事件观察器已在Mage_CatalogRule区域中定义(因为它位于applyAllRulesOnProduct节点内)。这意味着观察者将在两个 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/>区域中定义

    frontend

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

    这个是我认为你的问题所在,因为在现代版本的Magento(可能还有旧版本)中,来自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> 节点。尝试将其移至adminhtml节点。

    短版:确保<global/>模块上的模块<adminhtml/>,并将事件观察器配置移至模块<global/>中的<adminhtml/>节点{1}}。

答案 1 :(得分:3)

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

/ etc / modules / *文件夹是按字母顺序加载的,所以如果你的模块的文件是第一个(或最后一个),那么它会按照这个顺序加载 - 所以你可以将/etc/modules/Namespace_Module.xml重命名为/ etc /modules/ZZZNamespace_Module.xml最后加载它(假设没有任何其他模块与ZZZZ ...)

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