使用< args>在Magento观察员宣言中

时间:2012-08-10 09:29:07

标签: php arrays magento dispatchevent

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

在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对象。结果是:&lt; args&gt;观察者声明中的节点无法在观察者的被调用方法中访问(在我之前的示例中为Namespace_Module_Model_ObserverClass::observerMethod)。

我的第一个赌注是试图获得&lt; args&gt;节点使用这样的东西:

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

但是,令人失望的是$name变量(在Mage_Core_Model_App::dispatchEvent中也用于探查器)也没有传递给$observer对象......所以{{1} }没有返回任何数据。

所以我最终创建了一个帮助器方法,任何oberver方法都可以调用它来检索它的&lt; args&gt;节点。 你可以在这里找到这个助手的要点以及如何使用它:

https://gist.github.com/3312869

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

或许我错过了一些允许我们检索&lt; args&gt;节点,但我不确定,通过核心代码搜索,我没有找到任何&lt; args&gt;节点意味着Magento在其核心中不使用此功能。

所以,现在,问题是...... 你有一个简单的Magento Core方法来检索&lt; args&gt;观察员声明?

1 个答案:

答案 0 :(得分:1)

args的不幸脱节是......不幸的。 <args>节点似乎是残留的。但是,如果您有一个方法根据参数执行多个行为之一,那么将这些不同的活动置于不同的方法中可能是适当的。也就是说,对于您希望使用相同方法观察/消费的每个事件,您需要单独和完整的配置,您有三个选择:

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

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

修复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节点内 的args ,然后将其用作xpath的一部分 - 尽管任何其他模块都不可能使用< / em> args,更不用说传递会影响模块处理的参数。