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

Scr*_*aws 12 events observers magento

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

Ala*_*orm 33

像Magento中的许多人一样,答案很复杂.还有2可能出现的问题您的具体情况可能会涉及到.这将是很长的 - 跳到最后的无环境短版本.

模块装载订单

无法显式设置观察者排序顺序.Magento将按照它们合并到全局配置中的顺序运行事件.因此,虽然您无法专门控制事件的顺序,但您可以通过使用XML声明文件中的标记控制Magento加载和合并模块的顺序.<depends/>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>
Run Code Online (Sandbox Code Playgroud)

作者表示该Mage_Api2模块依赖Mage_CoreMage_Oauth模块.这意味着Mage_Api2config.xml文件将被合并config.xml的文件Mage_CoreMage_Oauth.这意味着定义的Mage_Api2事件将在Mage_Core和中定义的事件之后运行Mage_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>
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,此事件观察器已在global区域中定义(因为它位于<global/>节点内).这意味着观察者将在运行frontendadminhtmlMagento的领域.但是,也可以限制运行事件的区域.例如,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>
Run Code Online (Sandbox Code Playgroud)

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

是我认为你的问题所在,因为在现代版本的Magento(可能还有旧版本)中,来自<global/>节点的事件观察者总是在<adminhtml/>节点中的事件观察者之前运行.我的猜测是你的事件在<global/>节点中.尝试将其移动到<adminhtml/>节点.

简短版本:确保模块<depends/>上的Mage_CatalogRule模块,并将事件观察器配置移动到<adminhtml/>模块中的节点config.xml.

  • 作为参考,第三个选项可以是:禁用来自catalogrule的观察者(只需在该节点的config.xml中设置类型>禁用</ type)并在您自己的观察者中调用该方法:Mage :: getSingleton(' catalogrule/observer') - > applyAllRulesOnProduct($ event);,在你的监听器的开头或结尾(取决于你想要的) (2认同)