如何使用OpenCart 2.x Event事件系统
包含很多新特性,其中之一就是专为开发者提供的事件系统,Event System。它允许你在不修改原有系统代码的基础上( 当然也不使用vQmod或者是2.x版本新增的OCMOD修改代码,这样可以规避代码冲突的风险。 ),规定某些特定操作执行的时候,触发特定的动作。比如说:在用户下单或是注册的时候,你可以使用事件系统向后台发送通知信息。
使用原理:
使用事件系统需要两个步骤:
-
注册事件处理器。
-
接入事件处理器。
在控制器文件中注册事件处理器十分简单。你可以使用一个包含所有方法的单独文件作为事件处理器 ,也可以使用在控制器里分出一个方法。注册事件处理器你需要使用 extension/event 模型(OpenCart 2.0.1+)或者 tool/event 模型(OpenCart 2.0.0.0)。 extension/event 模型有两个方法: addEvent($code, $trigger, $action) 注册事件 和 deleteEvent($code) 删除事件。你可以在你开发插件时,在intsall()方法里面使用addEvent。在卸载插件的方法 uninstall()中使用 deleteEvent。
$code 参数用于组合你的事件处理器。
$trigger 参数用于规定触发时的动作参数 .这里有许多预定的opencart系统触发参数: .
$action 参数用于定位你的事件处理器。它通常是一组标准的控制器路由,比如:module/mymodule/on_user_created。
实例
环境:opencart 2.0.1+。
假设我们要开发一个名叫“My Module”的模块。
后台控制器: admin/controller/module/mymodule.php .
前台文件: catalog/controller/module/mymodule.php .
需求:当有用户注册或是删除一个店铺的时候,发送一份email给网站管理员。触发的参数我们可以定义为 pre.admin.store.delete 和 post.customer.add。
首先我们可以在我们的模块中使用 install() 方法:
public function install() { $this->load->model('extension/event'); $this->model_extension_event->addEvent('mymodule', 'pre.admin.store.delete', 'module/mymodule/on_store_delete'); $this->model_extension_event->addEvent('mymodule', 'post.customer.add', 'module/mymodule/on_customer_add'); }
卸载模块的流程方法 uninstall 如下:
public function install() { $this->load->model('extension/event'); $this->model_extension_event->addEvent('mymodule', 'pre.admin.store.delete', 'module/mymodule/on_store_delete'); $this->model_extension_event->addEvent('mymodule', 'post.customer.add', 'module/mymodule/on_customer_add'); }
接下来我们接入事件处理器。`pre.admin.store.delete` 处理后台事件,所以他的处理器必须接入admin/中的控制器文件中。当店铺被删除时,我们需要一个处理器方法来发送通知给后台管理员。以 pre. 开头的事件表示在控制器方法执行前触发,以 post. 开头的事件则表示控制器方法执行之后触发。同时,我们也想要在我们的信息中包含店铺地址的域名,如果先执行完删除店铺的操作,那么我们就无法得到被删店铺 的域名了。
事件处理器:
public function on_store_delete($store_id) { $this->load->model('setting/store'); $store_info = $this->model_setting_store->getStore($store_id); $admin_mail = $this->config->get('config_email'); mail($admin_mail, "A store has been deleted", "The store " . $store_info['url'] . " was deleted."); }
post.customer.add 需要在前台控制器catalog中写入事件处理器。当有新用户注册时,通知后台管理员。类似的方法如下:
public function on_customer_add($customer_id) { $this->load->model('account/customer'); $customer_info = $this->model_account_customer->getCustomer($customer_id); $admin_mail = $this->config->get('config_email'); mail($admin_mail, "New Customer", "A new customer has just registered with the following e-mail: " . $customer_info['email']); }
注意: 我们使用 mail() 函数发送邮件真实情况,我们可能要用到 OpenCart 的 Mail 类 发送 e-mails。
最后的代码如下:
admin/controller/module/mymodule.phpload->model('extension/event'); $this->model_extension_event->addEvent('mymodule', 'pre.admin.store.delete', 'module/mymodule/on_store_delete'); $this->model_extension_event->addEvent('mymodule', 'post.customer.add', 'module/mymodule/on_customer_add'); } public function uninstall() { $this->load->model('extension/event'); $this->model_extension_event->deleteEvent('mymodule'); } public function on_store_delete($store_id) { $this->load->model('setting/store'); $store_info = $this->model_setting_store->getStore($store_id); $admin_mail = $this->config->get('config_email'); mail($admin_mail, "A store has been deleted", "The store " . $store_info['url'] . " was deleted."); } }
catalog/controller/module/mymodule.php
load->model('account/customer'); $customer_info = $this->model_account_customer->getCustomer($customer_id); $admin_mail = $this->config->get('config_email'); mail($admin_mail, "New Customer", "A new customer has just registered with the following e-mail: " . $customer_info['email']); } }
进阶
除了上述的标准用法,事件系统也能用做创建跨模块接口。使用Event 对象 ($this->event),你可以在任何地方触发任何的事件。你可以使用它触发你自定义的事件。设想你正在开发一个用户评论的模块。你可以在客 户发送评论的时候触发一个事件,这就允许其他的模块开发者为你的事件处理期创建自定义的处理方法,而不需要使用vQmod或者OCMOD来修改代码。它可 以确保Opencart变得更加稳定。
PS:Event类定义在 system/engine/event.php 文件中。