11

据我所知,当脚本在 Magento 之外运行时,触发事件时不会调用观察者。为什么?我如何解决它?

以下是导致我提出这个问题的原始问题。问题是永远不会调用将应用目录规则的观察者。事件触发,但观察者没有接收到它。


我正在运行一个加载 Magento 会话的外部脚本。

在该脚本中,我正在加载产品并获取一堆属性。一个问题是getFinalPrice()不适用于适用于产品的目录规则。

我正在做我所知道的一切来设置会话,即使是一堆我认为是多余的东西。似乎没有什么可以应用这些规则。

这是一个测试脚本:

require_once "app/Mage.php";
umask(0);
$app = Mage::app("default");

$app->getTranslator()->init('frontend');  //Probably not needed
Mage::getSingleton('core/session', array('name'=>'frontend'));
$session = Mage::getSingleton("customer/session");
$session->start();  //Probably not needed
$session->loginById(122);

$product = Mage::getModel('catalog/product')->load(1429);
echo $product->getFinalPrice();

任何见解都值得赞赏。

4

1 回答 1

14

我的第一个猜测是您尝试挂钩的事件是 a <frontend />or<admin />事件,因为看起来只有<global />在您运行命令行脚本时才会触发事件。

Magento 有一个称为“区域”的概念。区域有点像系统中的单个应用程序(但不完全是,我对这个概念仍然有些模糊)。当您与观察者一起设置 config.xml 时,您要么将它们放在<global />标签中、<frontend />标签或<admin />标签。

当涉及到事件时,Magento 只加载它必须为特定请求处理的区域。因此,该<global />区域总是被加载。但是,只有当应用程序到达控制器调度时,<frontend />或区域才会被加载。<admin />具体来说,在以下文件/行中

File: app/code/core/Mage/Core/Controller/Varien/Action.php
Mage::app()->loadArea($this->getLayout()->getArea());

命令行应用程序永远不会发生这种情况。只有该<global />区域被加载。

因此,如第一段所述,我的猜测是您的观察者没有触发,因为 Magento 从不加载<frontend /> 应用程序的区域。至于解决方案,您可以尝试将观察者移动到该<global />区域。您也可以尝试手动调用

Mage::app()->loadArea(Mage_Core_Model_App_Area::AREA_FRONTEND);

但是,您将加载该<frontend />区域中的所有观察者,其中许多观察者可能是在假设 Web 浏览器上下文的情况下创建的。

如果这些都没有帮助,请查看类中的dispatchEvent方法Mage_Core_Model_App。这就是事件观察者被调用的地方。

于 2010-05-13T02:20:09.177 回答