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