Magento Event/Observer(事件)

Magento事件机制 – Magento Event/Observer

为了扩展Magento的功能,我们可以重写Magento的代码,但因为代码只能被重写一次,所以当多个模块需要重写同一部分的代码时,就会引起冲突,好在Magento提供了另一种扩展功能的方法:事件机制,原理是在需要扩展的地方触发事件,各模块捕捉到事件后,如果有该事件的响应,便执行对应的代码,这样便实现了在多个模块中扩展程序的功能。

我们首先看一下Magento系统中预定义了哪些事件:Magento Events , 这个表格有三列,第一列是事件的名称,比如”customer_login”,我们大概知道,这是用户登录时触发的事件;第二列是事件的作用域,只要有global/frontend/adminhtml这三种,分别是全局/前台/后台作用域,我们可以指定在哪些作用域响应该事件;最后一列是相应该事件的模块,比如”customer_login”事件在Catalog,Checkout,Log,Reports,Wishlist这几个模块中都有相应 . 我们可以知道”customer_login”这个事件是在 app/code/core/Mage/Customer/Model/Session.php 这个文件中触发的,我们打开这个文件,会发现这样的代码 :

class Mage_Customer_Model_Session extends Mage_Core_Model_Session_Abstract
{
// …
public function setCustomerAsLoggedIn($customer) {
$this->setCustomer($customer);
Mage::dispatchEvent('customer_login',array('customer'=>$customer));
return $this;
}
}

我们可以发现”customer_login”事件是在Mage_Customer_Model_Session类的setCustomerAsLoggedIn()函数中通过Mage::dispatchEvent()触发的,同时把customer变量作为参数传递给相应事件的对象。

我们再来分析模块是怎样相应事件的,仍以”customer_login”这个事件为例,我们看到Log模块响应了该事件,打开/app/code/core/Mage/Log/etc/config.xml文件,会看到这样的部分代码:

<frontend>
<events>
<controller_action_predispatch>
<observers>
<log>
<class>log/visitor</class>
<method>initByRequest</method>
</log>
</observers>
</controller_action_predispatch>
<controller_action_postdispatch>
<observers>
<log>
<class>log/visitor</class>
<method>saveByRequest</method>
</log>
</observers>
</controller_action_postdispatch>
<customer_login>
<observers>
<log>
<class>log/visitor</class>
<method>bindCustomerLogin</method>
</log>
</observers>
</customer_login>
<customer_logout>
<observers>
<log>
<class>log/visitor</class>
<method>bindCustomerLogout</method>
</log>
</observers>
</customer_logout>
<sales_quote_save_after>
<observers>
<log>
<class>log/visitor</class>
<method>bindQuoteCreate</method>
</log>
</observers>
</sales_quote_save_after>
<checkout_quote_destroy>
<observers>
<log>
<class>log/visitor</class>
<method>bindQuoteDestroy</method>
</log>
</observers>
</checkout_quote_destroy>
</events>
</frontend>

可以看到在Log模块中是在前台相应”customer_login”事件的,捕捉到这个事件时将执行”log/visitor”类的”bindCustomerLogin”方法,我们打开/app/code/core/Mage/Log/Model/Visitor.php文件,将发现这样的代码:

class Mage_Log_Model_Visitor extends Mage_Core_Model_Abstract 
{
//...
/**
* Bind customer data when customer login
*
* Used in event "customer_login"
*
*
@param Varien_Event_Observer $observer
*
@return Mage_Log_Model_Visitor
*/
  public function bindCustomerLogin($observer)
{
if (!$this->getCustomerId() && $customer = $observer->getEvent()->getCustomer()) {
$this->setDoCustomerLogin(true);
$this->setCustomerId($customer->getId());
}
return $this;
}
}

在触发事件时我们使用 Mage::dispatchEvent(‘customer_login’, array(‘customer’=>$customer)); 的第二个参数传递变量,在bindCustomerLogin($observer)函数中使用$observer参数获取该变量$customer = $observer->getEvent()->getCustomer(),之后进行相应的扩展。

Leave a Reply

您的邮箱地址不会被公开。 必填项已用 * 标注