Magento事件机制 - Magento Event/Observer

为了扩展Magento的功能,我们可以重写Magento的代码,但因为代码只能被重写一次,所以当多个模块需要重写同一部分的代码时,就会引起冲突,好在Magento提供了另一种扩展功能的方法:事件机制,原理是在需要扩展的地方触发事件,各模块捕捉到事件后,如果有该事件的响应,便执行对应的代码,这样便实现了在多个模块中扩展程序的功能。
 
我们首先看一下Magento系统中预定义了哪些事件:Magento Events , 这个表格有三列,第一列是事件的名称,比如"customer_login",我们大概知道,这是用户登录时触发的事件;第二列是事件的作用域,只要有global/frontend/adminhtml这三种,分别是全局/前台/后台作用域,我们可以指定在哪些作用域响应该事件;最后一列是相应该事件的模块,比如"customer_login"事件在Catalog,Checkout,Log,Reports,Wishlist这几个模块中都有相应。ba
 
如果需要找到触发事件的地方,可以在《Magento Event/Observer Hooks Cheat Sheet》这个网页中搜索,比如通过查找,我们可以知道"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文件,会看到这样的部分代码:
<config>
    <frontend>
        <events>
            <customer_login>
                <observers>
                    <log>
                        <class>log/visitor</class>
                        <method>bindCustomerLogin</method>
                    </log>
                </observers>
            </customer_login>
        </events>
    </frontend>
<config>

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

class Mage_Log_Model_Visitor extends Mage_Core_Model_Abstract
{
    // ...

    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(),之后进行相应的扩展。

posted @ 2016-11-04 09:34  郑彦彬  阅读(735)  评论(0编辑  收藏  举报