14

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

4

2 回答 2

35

与 Magento 中的许多人一样,答案很复杂。您的具体情况可能与两个可能的问题有关。这会很长——跳到最后看无上下文的简短版本。

模块加载顺序

没有办法显式设置观察者排序顺序。Magento 将按照它们被合并到全局配置中的顺序运行事件。因此,虽然您无法具体控制事件的顺序,但您可以通过使用XML 声明文件<depends/>中的标记来控制 Magento 加载和合并模块的顺序。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_Api2模块依赖Mage_CoreMage_Oauth模块。这意味着Mage_Api2' 的config.xml文件将在和的文件之后合并。这意味着 中定义的事件将在和中定义的事件之后运行。config.xmlMage_CoreMage_OauthMage_Api2Mage_CoreMage_Oauth

缺少一个<depends/>节点,模块加载的规则是

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

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

让您的模块依赖于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/>节点内部)。这意味着观察者将在Magento和区域中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.

于 2013-04-10T21:11:25.767 回答
3

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

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

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

于 2013-10-30T12:40:34.367 回答