2

这既是一个问题,也是一种答案。但我仍然很想找到一个更好的解决方案,你可能会对此有所了解。

在 Magento 中创建观察者时,负责调度它并调用在模块的 config.xml 文件中的观察者声明中配置的函数的方法是Mage_Core_Model_App::dispatchEvent.

在这种方法中,有一个收集观察者信息的代码位:

foreach ($eventConfig->observers->children() as $obsName=>$obsConfig) {
    $observers[$obsName] = array(
        'type'  => (string)$obsConfig->type,
        'model' => $obsConfig->class ? (string)$obsConfig->class : $obsConfig->getClassName(),
        'method'=> (string)$obsConfig->method,
        'args'  => (array)$obsConfig->args,
    );
}

这个代码位意味着可以像这样在观察者中声明一个 <args> 节点:

<events>
    <event_to_observe>
        <observers>
            <observer_name>
                <type>singleton</type>
                <class>Namespace_Module_Model_ObserverClass</class>
                <method>observerMethod</method>

                <args>
                    <arg_name>arg_value</arg_name>
                </args>

            </observer_name>
        </observers>
    </event_to_observe>
</events>

在后面Mage_Core_Model_App::dispatchEvent,我们可以找到一些代码,负责调用观察者的方法并将$observer对象作为参数传递。

但是,如果我是正确的,则没有代码将$observers[$obsName]['args']值设置为$event对象或$observer对象。结果是:观察者声明中的 < args > 节点在观察者的调用方法中不可访问(Namespace_Module_Model_ObserverClass::observerMethod在我之前的示例中)。

我的第一个赌注是尝试使用以下方法获取 <args> 节点:

$args = (array) Mage::getConfig()->getXpath('//events/' . $observer->getEvent()->getName() . '/observers/' . $observer->getName() . '/args');

但是,令人失望的是,$name变量(也用于Mage_Core_Model_App::dispatchEvent分析器)也没有传递给$observer对象......所以$observer->getName()没有返回任何数据。

所以我最终创建了一个辅助方法,任何 oberver 方法都可以调用它来检索它的 <args> 节点。您可以在此处找到此帮助程序的要点以及如何使用它:

https://gist.github.com/3312869

有这样的东西会更容易Mage_Core_Model_App::dispatchEvent$observer->setMethodArgs($obs['args'])允许$observer->getMethodArgs()在观察者方法中使用......

或者也许我错过了一些允许我们检索 <args> 节点的东西,但我不确定,通过核心代码搜索,我没有找到任何 <args> 节点,这意味着 Magento 没有在它的核。

所以,现在的问题是......你有一个简单的 Magento Core 方法来从观察者声明中检索 <args> 吗?

4

1 回答 1

1

不幸的断开args是……不幸的。该<args>节点似乎是退化的。但是,如果您有一个方法根据参数执行多种行为之一,则将这些不同的活动包含在不同的方法中可能是合适的。也就是说,虽然您需要为每个想要使用相同方法观察/使用的事件进行单独的总体配置,但您有三个选项:

为每个事件调用相同的方法,并通过使用 测试事件名称来控制观察者方法内部的行为$observer->getEvent()->getName()

在每个事件观察器配置中调用一个不同的方法,并让这些方法在内部调用包含该行为的方法,并简单地传入一个参数来指示哪种行为。

修复您的 xpath 引用以检索 args:

Mage::getConfig()->getNode('global/events/'.$observer->getEvent()->getName().'/observers/your_config/args');

或者

Mage::getConfig()->getXpath('global/events/'.$observer->getEvent()->getName().'//args');
$args = $cfg[0];

请注意,后者args将从任何全局观察者配置中获取给定事件,其中包含args. 您可能希望添加一个节点以在节点内包含您的参数,然后args将其用作 xpath 的一部分 - 尽管任何其他模块都不太可能使用 args,更不用说传入会影响模块处理的参数了。

于 2012-08-10T23:11:04.353 回答