13

我已经搜索了很多关于 opencart 触发器的信息,但没有找到合适的示例。在 opencart 2.0 中,开发人员可以使用触发器来挂钩功能并执行类似于 wordpress 操作和过滤器的操作。例如在

catalog/model/checkout/order.php

有一个触发器$this->event->trigger('post.order.history.add', $order_id)

有人可以帮我把我的功能挂在上面的触发器上吗?

4

3 回答 3

14

我认为这个问题应该更新,因为 OpenCart v2.3.x OC 事件的更新发生了巨大变化。

在他们类似于 Wordpress 方法之前。您将拥有一个带有beforeafter触发器的预定义事件列表。

从 2.3.x 版本开始,然后在 3.x 版本中进行了一些更改,OC 事件变得更加动态,其中触发器是根据文件的路径结构动态定义的。

使用事件有什么好处。

  1. 少了很多冲突。使用修改系统,您正在更改代码本身,而使用事件,您正在修改传递的数据,即数组、对象或字符串。
  2. 您可以轻松更新事件逻辑。由于事件代码位于一个简单的控制器文件中,因此您可以更新文件以更新事件,这与 OCmod 不同,您需要删除旧的 Ocmod 文件并上传新文件。
  3. 更多地控制您的数据。因为您更改的是数据而不是代码,所以您对它拥有更大的权力。
  4. 更简洁的代码。好吧,因为你只是在写 php.ini。没有xml和东西。
  5. 让您更轻松地升级您的 OpenCart。OpenCart 可以更改代码,但不会从根本上更改数据。因此,在大多数情况下,您的事件会正常运行。

当然,也有一些缺点:

  1. 很难学习和理解。
  2. 事件仅适用于控制器、模型、视图、库和配置。如果您想编辑其他内容,则必须使用 OCmod。

我建议尽可能使用事件,并回退到事件无法访问的 OCmod。

OpenCart 活动如何运作

当通过加载器类加载控制器(模型、视图、库或语言)时,如下所示:

$this->load->controller('common/header');

controller()文件中的方法system/engine/loader.php执行以下操作

  1. 首先触发before路线的事件common/header
$trigger = $route;

$result = $this->registry->get('event')->trigger('controller/' . $trigger . '/before', array(&$route, &$data));
  1. 然后运行加载控制器的代码
$action = new Action($route);
$output = $action->execute($this->registry, array(&$data));
  1. 最后触发after路线的事件common/header
$result = $this->registry->get('event')->trigger('controller/' . $trigger . '/after', array(&$route, &$data, &$output));

这对于模型、语言、库和配置来说非常相似。

什么是 OpenCart 事件触发器

OpenCart 将当前加载的控制器路由(就像我们上面加载的那样)common/header(模型、视图、语言和配置也是如此)与系统中注册的事件相匹配。

当您注册您的活动时,您将添加一个触发器。

common/home加载前目录中的控制器

触发器将如下所示: catalog/controller/common/home/before

对于目录sale/order中的方法模型,它会加载getOrderafter

触发器将如下所示: catalog/model/sale/order/getOrder/after

重要的是,在模型中,您将始终为方法设置触发器,这与控制器不同,在控制器中,默认方法index通常会被丢弃

对于catalog/product_form.twig在管理员中查看之后

触发器将如下所示: admin/view/catalog/product_form/after

请记住,在之后将事件添加到视图时,您将修改 &$output 验证,它现在不是树枝文件,而是完全编译的 HTML。所以代码中不再有 twig 标签。

如果使用PHP Simple HTML Dom Parser修改视图的最佳方法

如何注册活动

注册 OpenCart 活动有三个选项。

  1. 通过模型注册 $this->model_setting_event->addEvent(); (受到推崇的)
  2. system/config/catalog通过编辑中的配置文件注册$_['action_event']
  3. 在 d_event_manager 模块的帮助下通过管理员注册。

我将向您展示如何通过模型添加,因为这是推荐的方式。

  1. 添加用于在状态更新时注册事件的代码。

在你的文件中admin/controller/extension/module/my_module.php


$this->load->model('setting/event');
$this->model_setting_event->deleteEventByCode('my_module');
if($this->request->post['module_my_module_status']){
    $this->model_setting_event->addEvent('my_module', 
    'admin/view/catalog/product_form/before', 
    'extension/module/my_module/view_catalog_product_form_before');
}

请注意,我首先删除了所有事件,然后检查状态是否为真并添加事件。这样我可以确定不会添加旧的或意外的事件。

  1. 删除卸载时的所有事件
public function uninstall(){
    $this->load->model('setting/event');
    $this->model_setting_event->deleteEventByCode('my_module');
}

如果正在卸载模块,最好在模块之后删除所有事件。

我在哪里编写 OpenCart 事件函数?

现在你知道有些事件有触发器。但是触发器实际上做了什么?

他们只是加载事件的控制器并通过引用传递数据。

这就是为什么:

  1. 您将始终将事件逻辑添加到管理员或目录文件夹中的控制器中。(即使您正在为配置或库设置事件)
  2. 使用事件函数,您可以修改事件的 $route 和 $data 以及事件before的 $route 和 $outputafter

这是文件中事件函数的示例admin/controller/extension/module/my_module.php

public function view_catalog_product_form_before(&$route, &$data){
    if($data && isset($this->request->get['product_id'])){
        $product_id = $this->request->get['product_id'];
        $this->load->model('extension/module/my_module');

        $product_info = $this->model_extension_module_my_module->getMoreProductInfo($product_id);

        if($product_info){
            //here I am modifying the $data and it will pass on to the view with this new data because it was passed to this function by referance. 
            $data['more_info'] = $product_info;
        }
    }
    //there is no result returned in Event functions. 
    //if you do return a result, you will override the default result that can cause unexpected consequences. best to avoid it. 
}

享受!如果您有任何问题,请在https://dreamvention.com给我们留言

于 2019-03-11T20:51:25.620 回答
5

重要提示:此答案适用于 OC >2.0.xx 和 <2.2.xx

这里的问题是使用(和搜索)一个错误的词 - 您应该搜索的正确词是event,并从中派生事件侦听器和触发事件(不幸的是,在尝试搜索这些时没有运气和2.0 的文档仍然缺失)。

现在我相信整个背景更容易理解,特别是如果您对来自其他框架(可能是jQuery?)的事件有一些了解,但这里只是一个快速指南如何处理事件(在 OC 2.0 中):

  • 首先我们需要注册一个事件监听器,像这样:

    $this->event->register('post.order.history.add', 'checkout/order/send_email');

  • 在某些地方触发事件,例如

    $this->event->trigger('pre.order.history.add', $order_id);

    $this->event->trigger('post.order.history.add', $order_id);

  • 如果事件(由其名称标识post.order.history.add)侦听器已注册,它将在触发器上调用

有关更多信息或自行解决,您可以查看system/engine/event.php(目前没有更多可使用的)。

于 2014-10-20T07:53:41.490 回答
5

重要提示:此答案适用于 OC >2.0.xx 和 <2.2.xx

事件系统的工作方式如下:

  1. OpenCart 从数据库加载一个包含所有已注册事件处理程序的列表。这发生在 index.php 文件的末尾。
  2. 然后在 $event 对象中注册事件处理程序,该对象是 Event 类的一个实例(system/engine/event.php)
  3. 然后从系统的不同部分调用 $event->trigger() 方法。trigger 方法接受事件名称作为参数,并且正在执行为该事件名称注册的所有事件处理程序。

您可以使用 $event 对象在运行时注册事件处理程序或触发事件,但仅在特殊情况下这样做。请记住,您很可能需要通过 $this->event 而不是 $event 访问 $event 对象(取决于您需要它的位置)。

大多数情况下,您只需使用扩展/事件模型在 db 表中注册一次事件处理程序。例如,您可以在管理控制器的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');
}

事件处理程序是 addEvent() 方法的第三个参数,它们采用标准路由的形式。

您可以在此处找到有关事件系统的更多信息:http: //isenselabs.com/posts/opencart2-event-system-tutorial。这是一个解释事件系统如何工作的教程,并有一些简单的例子向你展示如何在你的扩展中使用它。

于 2014-12-15T21:55:20.207 回答