Chinaunix首页 | 论坛 | 博客
  • 博客访问: 40867
  • 博文数量: 31
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2015-06-08 16:34
文章分类

全部博文(31)

文章存档

2015年(31)

我的朋友
最近访客

分类: 系统运维

2015-06-08 17:31:04

为了扩展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 这个文件中触发的,我们打开这个文件,会发现这样的代码:
  1. class Mage_Customer_Model_Session extends Mage_Core_Model_Session_Abstract
  2. {
  3.     // ...

  4.     public function setCustomerAsLoggedIn($customer)
  5.     {
  6.         $this->setCustomer($customer);
  7.         Mage::dispatchEvent('customer_login', array('customer'=>$customer));
  8.         return $this;
  9.     }
  10. }
我们可以发现"customer_login"事件是在Mage_Customer_Model_Session类的setCustomerAsLoggedIn()函数中通过Mage::dispatchEvent()触发的,同时把customer变量作为参数传递给相应事件的对象。

我们再来分析模块是怎样相应事件的,仍以"customer_login"这个事件为例,我们看到Log模块响应了该事件,打开/app/code/core/Mage/Log/etc/config.xml文件,会看到这样的部分代码:
  1. <config>
  2.     <frontend>
  3.         <events>
  4.             <customer_login>
  5.                 <observers>
  6.                     <log>
  7.                         <class>log/visitor</class>
  8.                         <method>bindCustomerLogin</method>
  9.                     </log>
  10.                 </observers>
  11.             </customer_login>
  12.         </events>
  13.     </frontend>
  14. <config>
可以看到在Log模块中是在前台相应"customer_login"事件的,捕捉到这个事件时将执行"log/visitor"类的"bindCustomerLogin"方法,我们打开/app/code/core/Mage/Log/Model/Visitor.php文件,将发现这样的代码:
  1. class Mage_Log_Model_Visitor extends Mage_Core_Model_Abstract
  2. {
  3.     // ...

  4.     public function bindCustomerLogin($observer)
  5.     {
  6.         if (!$this->getCustomerId() && $customer = $observer->getEvent()->getCustomer()) {
  7.             $this->setDoCustomerLogin(true);
  8.             $this->setCustomerId($customer->getId());
  9.         }
  10.         return $this;
  11.     }
  12. }
在触发事件时我们使用 Mage::dispatchEvent('customer_login', array('customer'=>$customer)); 的第二个参数传递变量,在bindCustomerLogin($observer)函数中使用$observer参数获取该变量$customer = $observer->getEvent()->getCustomer(),之后进行相应的扩展。

《Magento删除产品同时删除图片》这篇文章中也使用了事件触发的方式扩展Magento,可以作为参照,这里也有一个例子:《Customize Magento using Event/Observer》

阅读(762) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~