今天,我们将讨论OpenCart最酷的功能之一-脚本通知。 尽管自OpenCart 2.x版本发布以来便已提供这些功能,但它们在最新版的OpenCart 2.2.xx中得到了增强。模块。
介绍
作为开发人员,无论是向框架添加新功能还是增强现有工作流程,您通常都需要更改核心框架行为的流程。 无论哪种情况,您都需要控制工作流程,以便可以使用该功能并实现所需的行为。
让我们尝试通过一个简单的例子来理解它。 如果您经营一家受欢迎的在线商店,那么您商店中最受欢迎的产品很可能很快就会被抢购一空。 在这种情况下,最好得到有关它的通知并采取相应的措施。
因此,在上述示例中,您可以做的是寻找下订单时调用的方法。 接下来,您可以进入订单创建流程,以便控制何时下订单。 这样,您就可以在被调用事件的上下文中执行一段随机的代码。 那就是事件通知出现的地方,允许我们运行任意代码并修改结果。
什么是脚本通知?
根据官方的OpenCart文档:
在2.2+中,我们添加了一个新的事件系统,这些钩子可以在诸如控制器方法调用,模型方法调用或加载模板之类的事件之前和之后调用。 它们使您能够操纵输入法参数和返回的输出。
这确实非常强大,因为您可以从字面上迷上任何方法调用并更改该方法返回的输出。 但是,如果您要负责修改调用的结果输出,则在实现挂钩时应格外小心。 这是因为如果您的实现返回任何值,它将停止设置为被调用的任何其他事件动作。
实现脚本通知需要什么? 以下是必要的步骤:
注册您的活动
在OpenCart中注册事件时,是在告诉OpenCart您要监视xyz
操作,如果发生,请在bar控制器文件中执行foo操作。 这样做时,有两个选项可供选择-之前和之后。
如果选择before选项,OpenCart将在受监视的动作之前运行foo动作,对于after选项,它将在动作之后执行foo。 在使用before选项的情况下,需要特别注意的是,如果foo方法返回任何内容,则OpenCart将根本不会执行正在监视的原始方法代码。
在本文的后面,我们将看到如何在自定义模块实现期间注册事件。
实施目标行动
接下来,您需要在第一步中实现与事件关联的控制器和相应的操作方法。 那是您的自定义代码应放入的地方。OpenCart将上下文特定的参数发送到foo方法,以便您可以在需要时使用它。
因此,这只是脚本通知功能的一瞥。
我们还需要OCMOD吗?
如果您熟悉vQmod或OCMOD,则很可能会因事件通知功能而袖手旁观。 毕竟,您可以通过上述优点来实现所有事情,而这些事情无论如何都可以通过事件通知来完成。
对于不熟悉vQmod或OCMOD的用户,下面列出了不错的介绍性文章,以对其进行解释。
因此,问题是,如果可以使用vQmod或OCMOD更改核心文件,为什么还要使用脚本通知? 这是因为可能存在多个试图修改同一代码的OCMOD插件,这可能会导致冲突。 对于事件,因为每个事件都以特定顺序执行,所以没有冲突的机会。
因此结论是,如果可以使用事件,那就去做吧。 另一方面,如果您觉得用例没有可用的事件,那么使用OCMOD完全可以。
创建一个后端模块
在本节中,我们将构建一个模块,该模块演示如何在OpenCart中使用事件通知。 我假设您已经了解了OpenCart中的基本模块开发过程,因为我们将逐步介绍这些基础知识。 如果您不了解它,这是一篇不错的文章 ,可以快速阅读。
在继续实施之前,让我们了解用例。 假定您有一个商店,该商店从第三方API后端获取目录信息。 您已经建立了一个cron,可以定期获取信息并将其插入OpenCart数据库中,以便可以在前端显示该信息。 尽管您已经设置了一个cron来定期更新信息,但是您仍要确保前端显示的信息必须是实时的。
在前端,OpenCart在显示产品详细信息页面时调用getProduct
函数。 因此,如果API信息已更改,那么它是您挂接和更新数据库的理想人选。
因此,让我们首先开始创建后端文件。
继续并使用以下内容创建admin/controller/module/demoevent.php
文件。
<?php
// admin/controller/module/demoevent.php
class ControllerModuleDemoevent extends Controller {
private $error = array();
public function install() {
$this->load->model('extension/event');
$this->model_extension_event->addEvent('event_product_info', 'catalog/model/catalog/product/getProduct/before', 'custom/product/info');
}
public function uninstall() {
$this->load->model('extension/event');
$this->model_extension_event->deleteEvent('event_product_info');
}
}
正如我们前面讨论的,您要做的第一件事是事件的注册。 这是我们将要使用的安装挂钩,因为它将在安装模块时执行。
我们在扩展目录下使用了事件模型的addEvent
方法,该方法具有三个参数。
第一个参数event_product_info是事件的名称。 您可以给它起任何名字,但要确保它是唯一的。
第二个参数非常重要,它指出了您想使用的方法。 在我们的情况下,我们必须选择目录目录下产品模型的getProduct
方法。 因此,层次结构为model/catalog/product/getProduct
。 除此之外,它还应以Catalog或admin为前缀,代表应用程序。 在我们的例子中,它是目录,因为我们迷上了前端方法。 最后,它将在前后固定后缀,告诉OpenCart相应地运行我们的代码。
第三个参数指向触发事件时将触发的控制器动作 。 它设置为custom/product/info
,因此您将不得不在custom目录下使用info
方法创建一个Product控制器,稍后我们将做。
最后,在模块卸载期间,使用uninstall方法删除事件。
接下来,让我们在admin/language/en-gb/module/demoevent.php
为我们的自定义模块创建一个语言文件,其中包含以下内容。
<?php
// admin/language/en-gb/module/demoevent.php
// Heading
$_['heading_title'] = 'Custom Event (Script Notification) Demo Module';
我们已经完成了后端文件设置。 现在,您应该能够在OpenCart后端的扩展>模块下看到我们的模块。 继续安装。 现在,我们将继续在前端创建文件。
使用以下内容创建模型文件catalog/model/custom/product.php
。 根据OpenCart结构,这是典型的模型文件。
<?php
// catalog/model/custom/product.php
class ModelCustomProduct extends Model {
function getProductLastModifiedInfo($product_id) {
$query = $this->db->query("SELECT date_modified FROM " . DB_PREFIX . "product WHERE product_id = '" . (int)$product_id . "'");
return $query->row;
}
function updateProductInfo($product_id, $data) {
include_once __DIR__.'../../../admin/model/catalog/product.php';
$modelCatalogProduct = new ModelCatalogProduct();
$modelCatalogProduct->editProduct($product_id, $data);
}
}
它实现了两种重要的方法。 getProductLastModifiedInfo
方法用于获取产品的最后修改日期,而updateProductInfo
方法用于更新数据库中的产品信息。 稍后,我们将看到如何使用这些方法。
最后,让我们用以下内容创建本文最重要的文件之一catalog/controller/custom/product.php
。 这是一个控制器文件,该文件实现了info
操作方法,该方法设置为在调用产品模型的getProduct
方法时调用的方法。
<?php
// catalog/controller/custom/product.php
class ControllerCustomProduct extends Controller {
public function info($route, $product_id) {
// fetch product info from API (psudo code)
$product_api_info = api_call_to_fetch_product_info($product_id);
// fetch product info from database
$this->load->model('custom/product');
$product_modified_date = $this->model_custom_product->getProductLastModifiedInfo($product_id);
if ($product_modified_date['date_modified'] != $product_api_info['date_modified']) {
// api info has changed so first let's update db
// Note: you probably want to format $product_api_info as per the format required by editProduct method
$this->model_custom_product->updateProductInfo($product_id, $product_api_info);
// return latest/real-time product information
return array(
'product_id' => $product_api_info['product_id'],
'name' => $product_api_info['name'],
'description' => $product_api_info['description'],
'meta_title' => $product_api_info['meta_title'],
'meta_description' => $product_api_info['meta_description'],
'meta_keyword' => $product_api_info['meta_keyword'],
'tag' => $product_api_info['tag'],
'model' => $product_api_info['model'],
'sku' => $product_api_info['sku'],
'upc' => $product_api_info['upc'],
'ean' => $product_api_info['ean'],
'jan' => $product_api_info['jan'],
'isbn' => $product_api_info['isbn'],
'mpn' => $product_api_info['mpn'],
'location' => $product_api_info['location'],
'quantity' => $product_api_info['quantity'],
'stock_status' => $product_api_info['stock_status'],
'image' => $product_api_info['image'],
'manufacturer_id' => $product_api_info['manufacturer_id'],
'manufacturer' => $product_api_info['manufacturer'],
'price' => ($product_api_info['discount'] ? $product_api_info['discount'] : $product_api_info['price']),
'special' => $product_api_info['special'],
'reward' => $product_api_info['reward'],
'points' => $product_api_info['points'],
'tax_class_id' => $product_api_info['tax_class_id'],
'date_available' => $product_api_info['date_available'],
'weight' => $product_api_info['weight'],
'weight_class_id' => $product_api_info['weight_class_id'],
'length' => $product_api_info['length'],
'width' => $product_api_info['width'],
'height' => $product_api_info['height'],
'length_class_id' => $product_api_info['length_class_id'],
'subtract' => $product_api_info['subtract'],
'rating' => round($product_api_info['rating']),
'reviews' => $product_api_info['reviews'] ? $product_api_info['reviews'] : 0,
'minimum' => $product_api_info['minimum'],
'sort_order' => $product_api_info['sort_order'],
'status' => $product_api_info['status'],
'date_added' => $product_api_info['date_added'],
'date_modified' => $product_api_info['date_modified'],
'viewed' => $product_api_info['viewed']
);
}
}
}
这里要注意的重要一点是OpenCart为您的方法提供了特定于上下文的参数。 第一个$route
参数告诉您与已触发事件关联的路由。 在我们的情况下,它应该是catalog/product/getProduct
。 第二个参数是产品ID,因为它是实际getProduct
方法的必需参数。
逻辑是这样的:我们将产品在OpenCart数据库中的修改日期与API回调返回的信息进行比较。
因此,第一步是从API加载实时产品信息。 请注意, api_call_to_fetch_product_info方法只是一个虚拟方法,您希望将其替换为实际的API调用。
接下来,我们使用在较早部分中创建的getProductLastModifiedInfo
方法,从OpenCart数据库中获取产品的修改日期。
最后,我们进行比较,如果日期不同,它将使用Model类中的updateProductInfo
方法使用最新产品信息更新OpenCart数据库。
我们还以实际getProduct
返回的相同方式以数组格式返回了产品信息。 重要的是要注意,由于我们已在挂钩中提供了返回值,因此它将不会再调用任何事件调用,包括对原始getProduct
方法的调用。
因此,您可以通过这种方式影响OpenCart中的执行流程。 这是更改核心功能的一种非常强大的方法。 但是,在使用此解决方案时应小心,因为它可以完全控制更改任何方法的结果输出。
结论
今天,我们讨论了OpenCart令人兴奋的功能之一,即脚本通知。 我们从对该主题的介绍开始,而本文的后半部分通过构建自定义事件模块演示了如何使用它们。
与往常一样,如果您正在寻找其他OpenCart工具,实用程序,扩展等,以便可以在自己的项目中使用或用于自己的教育,请不要忘记查看我们在市场上提供的产品 。
随时欢迎查询和评论!
翻译自: https://code.tutsplus.com/tutorials/the-enhanced-script-notifications-in-opencart-22xx--cms-26469