编程

OpenCart 4 的事件系统

1050 2023-10-18 19:38:00

OpenCart 4.0 有一个事件系统,允许你在代码执行的特定时刻执行特定操作。这允许你在不修改源码的情况下,扩展 OpenCart 的功能。

当特定事件发生时,事件系统为该事件调用所有注册的句柄。每个句柄可以有自己的代码去处理事件。

OpenCart 有一些内置事件,比如 “catalog/view/common/header/before”, “catalog/controller/product/product/before”, "admin/controller/catalog/product/before" 等。你可以使用这些事件来修改 OpenCart 行为或者添加自定义功能。

OpenCart 的事件系统允许你创建易于安装和删除的扩展,使得软件开发和维护更加容易。

事件系统和 ocmod 的不同?

事件和 ocmod 是扩展 OpenCart 功能的两种不同机制。

事件用于对系统中发生的某些事件作出反应,例如,当产品添加到购物车或创建订单时。在系统中注册的事件处理程序可以在这些事件发生时执行某些操作。事件不会更改 OpenCart 的核心代码,因此它的使用是安全的,不会影响系统的稳定性。

另一方面,允许您通过对现有代码打补丁来修改核心 OpenCart 代码。这可能会影响系统的稳定性,特别是在更新到新版本时。而使用 ocmod 允许你修改系统核心代码,因此它有更深入的能力来扩展系统功能。

事件和 ocmod 指定最大不同是,事件允许你在系统中做出反应,而 ocmod 允许你修改系统的主代码。这两种机制各有优缺点,应根据项目的需要和情况使用。但在 OpenCart 4 的扩展中,不再支持 ocmod,因此从这个分支开始,您只需要使用事件系统(Events)。

事件的优势:

  1. 更灵活的方式来修改代码:使用事件系统时,你不需要修改 OpenCart 的主要代码或者安装 ocmod,这使得扩展更加灵活,更容易开发和维护。
  2. 速度:事件系统允许你注册事件句柄并且在事件发生时执行,这比安装 ocmod 并编辑文更为迅速。
  3. 兼容性:事件系统通常保留了前一个 OpenCart 版本的兼容性,而 ocmod 可能在不同 OpenCart 版本中存在安装或者运行问题。 
  4. 易于使用:事件系统允许开发者在没有开发经验情况下,添加新功能或者修改 OpenCart 的行为。

事件系统在 OpenCart 中非常有用,可以扩展功能和改变行为,而无需修改 OpenCart 代码或安装 ocmod。同时,ocmod可以用于对 OpenCart 代码进行更深入的更改。

 

事件的缺点:

  1. 限制 HTML 页面的修改:使用事件系统,您不能更改页面的 HTML 代码,这可以使用 ocmod 完成。
  2. 复杂性:某些类型的事件使用起来可能更复杂,需要高级编程技能来开发和维护。
  3. 需要访问数据库:事件系统需要数据库访问才能注册事件处理程序,这可能会带来一些安全问题。
  4. 可能降低性能:事件系统在执行事件处理程序时可能会影响 OpenCart 的性能,从而导致性能下降。

与 ocmod 相比,事件系统有其局限性和缺点,ocmod 可用于对 OpenCart 代码进行更深入的更改。但事件系统对于扩展功能和改变行为非常有用,而无需修改 OpenCart 代码或安装 ocmod。

在 OpenCart 4 中新建事件 handler

在OpenCart中,事件处理 handler 或钩子是当系统中发生特定事件时自动执行的函数。例如,在创建订单或将新产品添加到目录时。

在软件编程和开发中,钩子是一种机制,允许您通过插入特定代码在程序执行的特定点执行特定功能,在程序或系统中采取行动。钩子可以用于连接附加功能或在不更改源代码的情况下更改程序的行为。例如,代码编辑器的插件可以使用 Hooks 为用户提供额外的功能,如代码自动补全、函数提示或有关代码结构的额外信息。

在 OpenCart 中,由于某些原因,钩子被称为事件,它们用于将模块和扩展连接到平台的不同代码执行点。这允许您扩展 OpenCart 的功能并添加新功能,而无需修改主要的平台代码。你可以在 Extensions > Events 中查看事件列表。

要创建钩子或者事件 handler,你需要在系统中对其进行注册。为此,我们需要创建一个 $event 数组并将其传给 addEvent 方法。及至 OpenCart 4.0.1.1,addEvent 方法需要三个参数,顺序如下:$code、$trigger、$action。

因此要注册的 $event 数组必须有以下元素:

  • 'code' - 钩子的唯一代码
  • 'trigger' - 触发器,即事件
  • 'action' - 事件 handler 方法的 action 及地址
  • 'description' - 钩子的简述
  • 'sort_order' - 钩子启动的排序
  • 'status' - 钩子的状态 (enabled/disabled)

要清楚地显示如何在 OpenCart 中创建事件 handler,我们将提供一个示例,在 <body> 标签之后添加自己的代码。因此,我们注册了事件 handler:

$this->load->model('setting/event');
$event = [
 'code' => 'my_first_event',
 'trigger' => 'catalog/view/common/header/after',
 'action' => 'extension/opencartbot/module/my_module.myEventHandler',
 'description' => 'My first Event in OpenCart 4',
 'sort_order' => 1,
 'status' => true
];
$this->model_setting_event->addEvent($event);

注册完钩子后,我们可以在后台事件清单中查看它。

现在,在模块的控制器文件中,我们将添加一个方法来处理事件:

public function myEventHandler(string &$route, array &$data, mixed &$output): void {
 $module = $this->load->view('extension/opencartbot/module/my_module', $data);
 $output = str_replace('<body>',  '<body>' . $module,  $output);
}

传入到该方法可能的清单包括:

  • &$route - 包含事件路径的数据;
  • &$data - 包含事件操作的数据数组,比如,对于视图文件,这是从控制器转换到视图的数据
  • &$output - 包含事件结果,比如视图文件 - 它是 twig 模板的内容

对于控制器,模型,视图,语言,传入到  handler 的参数集是相同的:

  • 使用 before: &$route, &$data
  • 使用 after: &$route, &$data, &$output

也就是说,如果 handler 在事件的之前运行,handler 像这样: 

public function myEventHandler(string &$route, array &$data): void {
 $data['my_param'] = 'My value;'
}

删除事件的示例:

$this->load->model('setting/event');
$this->model_setting_event->deleteEventByCode('my_first_event');

要在系统中检测事件 handler 是否存在,你可以使用如下代码:

$this->load->model('setting/event');
if ($this->model_setting_event->getEventByCode('my_first_event')) {
 // The event exists
} else {
 // The event does not exist
}

当然,这只是 OpenCart 4.0 事件系统的基本信息。不过,你可以借此了解操作的原理,用以执行更为复杂的操作。