第十五天
一、 Magento Event Handlers概述
在Magento系统的业务流程(主要是购物流程)中,存在很多的事件(Event)。Magento系统会自动调度这些事件,我们可以使用钩子(hook)挂载在事件上,通过钩子来完成自定义的功能或动作。使用事件监听器(Event Listeners)可以用来代替之前提过的类的重写方法,通过事件方式即可以避免类的重写带来的影响系统的不确定性,又可以完成功能的扩展或重写。
Magento的事件处理系统依据观察者设计模式实现,系统配置将自动调用observer类中相应的方法执行。
二、 Magento事件处理器实例测试:Magento事件类型测试
该实例将测试Magento事件系统如何工作,哪些事件是注册可用的,这些事情是如何被调度使用的。
1. 开启Magento的logging系统,System|Configuration|Advanced|Developer|Log Settings;
2. Magento事件通过Mage::dispatchEvent()方法进行调度,该方法定义在app/code/core/Mage/Core/Model/App.php文件中,将该文件复制到app/code/local/Mage/Core/Model下,以方便我们做接下来的调试工作。
3. 在刚拷贝的文件中需找dispatchEvent方法定义处,增加一句代码如下:
Mage::log($eventName);
4. 刷新前端页面后,添加的代码将执行,我们打开/magento/var/log/system.log文件,可以在最新的记录中看到如下log信息,在这些信息里我们可以发现很多的事件:
5. 调试工作已经完成,我们将刚才拷贝的App.php文件删除,以免影响系统正常功能;
6. Mage::log()方法有以下四个参数:
- 指定要被log输出的参数,如果该参数是一个对象或数组,系统会dump打印每个变量的日志信息;
- 参数二(可选)是log级别,默认值为DEBUG,zend_log类中有以下常量的定义:
- Zend_log::EMERG;
- Zend_log::ALERT;
- Zend_log::CRIT;
- Zend_log::ERR;
- Zend_log::WARN;
- Zend_log::NOTICE;
- Zend_log::INFO;
- 参数三(可选),指定log输出的文件,默认为system.log;
- 参数四(可选),该参数是布尔值,可设置强制输出log信息,即使后台关闭了log功能。
三、 Magento事件处理器实例测试:创建自定义事件并添加事件观察者
1. 创建新模块Eventandobserver;
2. 在控制器中调用dispatchEvent()方法,申明调用事件;
1 class YEMA_Eventandobserver_IndexController extends Mage_Core_Controller_Front_Action { 2 function indexAction() { 3 $this->loadLayout(); 4 Mage::dispatchEvent('eventandobserver_event_test'); 5 $this->renderLayout(); 6 echo "test"; 7 } 8 }
3. 当访问前端页面所属的控制器时,事件被调度使用,现在我们没有添加监听器,所以事件被调度使用后,什么都不会发生;
4. 现在我们给事件添加两个参数;
1 $parameters = array( 2 'product' => Mage::getModel('catalog/product')->load(1), 3 'category' => Mage::getModel('catalog/category')->load(1), 4 ); 5 Mage::dispatchEvent('eventandobserver_event_test', $parameters);
5. 注册事件监听者,在config.xml中进行如下配置:
1 <global> 2 <events> 3 <eventandobserver_event_test> 4 <observers> 5 <register_visit> 6 <type>Singleton</type> 7 <class>eventandobserver/observer</class> 8 <method>registerVisit</method> 9 </register_visit> 10 </observers> 11 </eventandobserver_event_test> 12 </events> 13 </global>
6. 创建与该事件相关的类及方法,/Eventandobserver/Model/Observer.php
1 class YEMA_Eventandobserver_Model_Observer { 2 public function registerVisit(Varien_Event_Observer $observer) { 3 Mage::log('Registered'); 4 } 5 }
7. 访问前端路由地址/index.php/Eventandobserver/index/index,此时查看system.log会增加如下内容;
8. 现在事件与监听都已加好了,我们修改一下观察者控制器的方法,将我们刚才添加的两个变量进行Debug,system.log中会记录相关信息;
1 $product = $observer->getProduct(); 2 $category = $observer->getCategory(); 3 Mage::log($product->debug()); 4 Mage::log($category->debug());
9. 接下来,我们给加入购物车这个动作增加一个事件,当购物车结算总个数为奇数时,发出错误提示;所以,我们需要先创建事件观察者(或叫监听器),监听checkout_cart_product_add_after事件,编辑模块的config.xml文件,添加如下内容;
1 <checkout_cart_product_add_after> 2 <observers> 3 <check_cart_qty> 4 <type>singleton</type> 5 <class>eventandobserver/observer</class> 6 <method>checkCartQty</method> 7 </check_cart_qty> 8 </observers> 9 </checkout_cart_product_add_after>
10. 在控制器中创建相关方法/controllers/IndexController.php;
1 public function checkCartQty($observer) { 2 Mage::getSingleton('checkout/session')->addNotice('Product add event fired'); 3 }
11. 接下来增加判断逻辑,当数量是奇数时,发出错误提示;
1 public function checkCartQty(Varien_Event_Observer $observer) { 2 if ($observer->getProduct()->getQty() % 2 == 0) { 3 Mage::getSingleton('checkout/session')->addNotice('Even quantity added.'); 4 } else { 5 Mage::throwException('Quantity is odd. It needs to be even.'); 6 } 7 }