0

0

第一部分:如何在 OpenCart 2.1.x.x 中创建自定义插件

WBOY

WBOY

发布时间:2023-09-08 23:05:13

|

825人浏览过

|

来源于php中文网

原创

作为一名开发人员,在任何框架中构建自定义内容总是令人兴奋的,对于 opencart 插件也是如此。

在这个由两部分组成的系列中,我将解释 OpenCart 中的自定义插件开发。我们将从新手开发者的角度来详细介绍 OpenCart 中的扩展开发细节。我们还将创建一个小型自定义插件来演示 OpenCart 插件结构的各个方面。

在第一部分中,我们将构建一个自定义插件,用于在商店前端显示最新产品,并且您将能够从后端本身配置产品数量。这就是本文的目的——开发一个带有配置表单的后端插件。

我假设您已经设置了最新版本的 OpenCart,在撰写本文时为 2.1.0.2。在我们继续开发实际的插件之前,我将在下一节中向您介绍 OpenCart 的基本插件架构。

MVCL 简介

OpenCart 是使用最流行的 Web 开发模式之一(MVC 模式)开发的,但有一些细微的变化,或者更确切地说,我会说这是一个补充。添加的形式是语言组件,使其成为 OpenCart 世界中的 MVCL。您可能听说过这种模式,但为了初学者,我将快速总结一下该模式的全部内容。

MVC 中的 M 代表模型,这是大部分业务逻辑所在的地方。在 OpenCart 的上下文中,它是与数据库抽象层交互的模型,以完成运行商店所需的所有繁重工作。您会发现自己大部分时间都在这个领域担任开发人员。

接下来,V代表View,它代表应用程序的表示层。顾名思义,它只处理任何页面的表示逻辑,并且大多数时候它接收其他层的输入并生成 XHTML 输出。应用程序的业务逻辑应该远离这一层;它应该只关心做什么而不是如何去做。

MVC 中的 C(控制器)位于所有内容的前面,负责处理每个请求并进行相应的处理。该区域包含大部分应用程序逻辑,从处理和验证用户输入到加载正确的模型和视图组件以准备页面输出。

最后,还有一个附加组件 L,代表语言。它使建立多语言网站变得轻而易举。

这是 OpenCart 架构的快速视图,当我们继续深入解释每个组件时,它会更有意义。

任何 OpenCart 插件的骨架

让我们快速浏览一下需要为自定义后端插件实现的文件列表。

  • admin/language/english/module/recent_products.php:这是一个保存在整个管理应用程序区域中使用的静态标签的文件。
  • admin/controller/module/recent_products.php:它是一个控制器文件,保存我们模块的应用程序逻辑。
  • admin/view/template/module/recent_products.tpl:这是一个视图模板文件,包含 XHTML 代码。

在下一节中,我们将创建上述每个文件,并进行深入说明。

按照惯例,我们需要将自定义插件文件放置在模块目录下。在这种情况下,当我们开发后端插件时,admin 下的目录将保存我们的文件。当然,根据上面所示的 OpenCart 架构,文件分布在不同的目录或组件中。

为后端插件创建文件

在本节中,我们将开始创建模块文件。首先,我们将创建一个语言文件 admin/language/english/module/recent_products.php ,其中包含以下内容。从 OpenCart 的角度来看,这是一个重要的文件,因为它是 OpenCart 检测到您的插件所必需的。


如您所见,我们将静态标签分配给 PHP 数组。稍后,当数组转换为 PHP 变量时,您将可以在视图模板文件中访问这些变量。

您可能还注意到,该文件是在 english 目录下创建的,因为它是商店的默认语言。当然,对于多语言网站,您需要确保也为其他语言创建它。例如,应在 admin/language/french/module/recent_products.php 创建同一文件的法语版本。

接下来,我们将创建最重要的插件文件之一——控制器文件。让我们继续创建包含以下内容的 admin/controller/module/recent_products.php

load->language('module/recent_products');

        $this->document->setTitle($this->language->get('heading_title'));

        $this->load->model('extension/module');

        if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validate()) {
            if (!isset($this->request->get['module_id'])) {
                $this->model_extension_module->addModule('recent_products', $this->request->post);
            } else {
                $this->model_extension_module->editModule($this->request->get['module_id'], $this->request->post);
            }

            $this->session->data['success'] = $this->language->get('text_success');

            $this->response->redirect($this->url->link('extension/module', 'token=' . $this->session->data['token'], 'SSL'));
        }

        $data['heading_title'] = $this->language->get('heading_title');

        $data['text_edit'] = $this->language->get('text_edit');
        $data['text_enabled'] = $this->language->get('text_enabled');
        $data['text_disabled'] = $this->language->get('text_disabled');

        $data['entry_name'] = $this->language->get('entry_name');
        $data['entry_limit'] = $this->language->get('entry_limit');
        $data['entry_status'] = $this->language->get('entry_status');

        $data['button_save'] = $this->language->get('button_save');
        $data['button_cancel'] = $this->language->get('button_cancel');

        if (isset($this->error['warning'])) {
            $data['error_warning'] = $this->error['warning'];
        } else {
            $data['error_warning'] = '';
        }

        if (isset($this->error['name'])) {
            $data['error_name'] = $this->error['name'];
        } else {
            $data['error_name'] = '';
        }

        $data['breadcrumbs'] = array();

        $data['breadcrumbs'][] = array(
            'text' => $this->language->get('text_home'),
            'href' => $this->url->link('common/dashboard', 'token=' . $this->session->data['token'], 'SSL')
        );

        $data['breadcrumbs'][] = array(
            'text' => $this->language->get('text_module'),
            'href' => $this->url->link('extension/module', 'token=' . $this->session->data['token'], 'SSL')
        );

        if (!isset($this->request->get['module_id'])) {
            $data['breadcrumbs'][] = array(
                'text' => $this->language->get('heading_title'),
                'href' => $this->url->link('module/recent_products', 'token=' . $this->session->data['token'], 'SSL')
            );
        } else {
            $data['breadcrumbs'][] = array(
                'text' => $this->language->get('heading_title'),
                'href' => $this->url->link('module/recent_products', 'token=' . $this->session->data['token'] . '&module_id=' . $this->request->get['module_id'], 'SSL')
            );
        }

        if (!isset($this->request->get['module_id'])) {
            $data['action'] = $this->url->link('module/recent_products', 'token=' . $this->session->data['token'], 'SSL');
        } else {
            $data['action'] = $this->url->link('module/recent_products', 'token=' . $this->session->data['token'] . '&module_id=' . $this->request->get['module_id'], 'SSL');
        }

        $data['cancel'] = $this->url->link('extension/module', 'token=' . $this->session->data['token'], 'SSL');

        if (isset($this->request->get['module_id']) && ($this->request->server['REQUEST_METHOD'] != 'POST')) {
            $module_info = $this->model_extension_module->getModule($this->request->get['module_id']);
        }

        if (isset($this->request->post['name'])) {
            $data['name'] = $this->request->post['name'];
        } elseif (!empty($module_info)) {
            $data['name'] = $module_info['name'];
        } else {
            $data['name'] = '';
        }

        if (isset($this->request->post['limit'])) {
            $data['limit'] = $this->request->post['limit'];
        } elseif (!empty($module_info)) {
            $data['limit'] = $module_info['limit'];
        } else {
            $data['limit'] = 5;
        }

        if (isset($this->request->post['status'])) {
            $data['status'] = $this->request->post['status'];
        } elseif (!empty($module_info)) {
            $data['status'] = $module_info['status'];
        } else {
            $data['status'] = '';
        }

        $data['header'] = $this->load->controller('common/header');
        $data['column_left'] = $this->load->controller('common/column_left');
        $data['footer'] = $this->load->controller('common/footer');

        $this->response->setOutput($this->load->view('module/recent_products.tpl', $data));
    }

    protected function validate() {
        if (!$this->user->hasPermission('modify', 'module/recent_products')) {
            $this->error['warning'] = $this->language->get('error_permission');
        }

        if ((utf8_strlen($this->request->post['name']) < 3) || (utf8_strlen($this->request->post['name']) > 64)) {
            $this->error['name'] = $this->language->get('error_name');
        }

        return !$this->error;
    }
}

它为我们的自定义插件定义了新类,该类扩展了基本 Controller 类。根据约定,类的名称应模仿文件所在的目录结构。因此,路径 controller/module/recent_products.php 会根据驼峰命名约定替换斜杠和下划线字符,转换为 ControllerModuleRecentProducts

接下来,有一个事实上的 index 方法,当插件加载到前端时会调用该方法。所以,它是一个索引方法,定义了插件的大部分应用逻辑。

在当前应用程序的上下文中,简写 $this->load->language 加载相应的语言文件。在我们的例子中,它加载前面部分中定义的语言文件。语法非常简单,您只需传递前缀为 module/ 的插件名称即可。语言变量可以通过 $this->language->get 方法访问。

接下来,它使用文档对象的 setTitle 方法设置页面标题。

Convai Technologies Inc.
Convai Technologies Inc.

对话式 AI API,用于设计游戏和支持端到端的语音交互

下载

继续,简写 $this->load->model 用于加载模块模型。它是模型类,提供实用方法来保存模块参数等。

接下来,有一个重要的代码片段,如下所示,用于检查是否是 POST 数据提交,并在这种情况下保存模块配置。

if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validate()) {
    if (!isset($this->request->get['module_id'])) {
        $this->model_extension_module->addModule('recent_products', $this->request->post);
    } else {
        $this->model_extension_module->editModule($this->request->get['module_id'], $this->request->post);
    }

    $this->session->data['success'] = $this->language->get('text_success');
    $this->response->redirect($this->url->link('extension/module', 'token=' . $this->session->data['token'], 'SSL'));
}

此外,我们还将 heading_titletext_edit 等语言标签分配给 $data 数组,以便我们可以使用它们在视图模板文件中。

接下来,有一个片段可以为配置页面构建正确的面包屑链接。

$data['breadcrumbs'] = array();

$data['breadcrumbs'][] = array(
    'text' => $this->language->get('text_home'),
    'href' => $this->url->link('common/dashboard', 'token=' . $this->session->data['token'], 'SSL')
);

$data['breadcrumbs'][] = array(
    'text' => $this->language->get('text_module'),
    'href' => $this->url->link('extension/module', 'token=' . $this->session->data['token'], 'SSL')
);

if (!isset($this->request->get['module_id'])) {
    $data['breadcrumbs'][] = array(
        'text' => $this->language->get('heading_title'),
        'href' => $this->url->link('module/recent_products', 'token=' . $this->session->data['token'], 'SSL')
    );
} else {
    $data['breadcrumbs'][] = array(
        'text' => $this->language->get('heading_title'),
        'href' => $this->url->link('module/recent_products', 'token=' . $this->session->data['token'] . '&module_id=' . $this->request->get['module_id'], 'SSL')
    );
}

如果模块之前已配置并处于编辑模式,则以下代码片段将填充默认模块配置。

if (isset($this->request->get['module_id']) && ($this->request->server['REQUEST_METHOD'] != 'POST')) {
    $module_info = $this->model_extension_module->getModule($this->request->get['module_id']);
}

最后,我们加载常见的页面元素,例如页眉、页脚和左侧边栏。另外,它是加载实际视图文件 recent_products.tpl 并显示配置表单的 $this->load->view 简写。

控制器文件中有一些重要的注释需要记住。您会看到很多类似 $this->load->ELEMENT 的调用,其中 ELEMENT 可以是视图、模型或语言。它加载相应的视图、模型和语言组件。

今天文章的下一个也是最后一个文件是视图模板文件admin/view/template/module/recent_products.tpl。继续创建它!



眼尖的用户已经注意到它只是显示从控制器文件传递的变量。除此之外,它是显示配置表单的简单 XHTML 代码,最重要的是它具有开箱即用的响应能力。

所以,这就是我们后端自定义插件的文件设置。

启用插件

前往 OpenCart 后端并导航至扩展 > 模块。您应该在列表中看到最近的产品。单击+符号安装模块,如以下屏幕截图所示。

第一部分:如何在 OpenCart 2.1.x.x 中创建自定义插件

安装后,您将看到一个编辑图标。单击该按钮可打开模块配置表单。

第一部分:如何在 OpenCart 2.1.x.x 中创建自定义插件

在配置表单中,您可以设置要在前端块中显示的最近产品的数量。另外,不要忘记将状态字段设置为启用!保存模块,它应该看起来像这样。

第一部分:如何在 OpenCart 2.1.x.x 中创建自定义插件

模块中有一个新条目,标题为最近的产品 > 我最近的块插件。原因是您可以为不同的页面多次复制它!

所以,我们快完成了!我们在 OpenCart 中制作了一个成熟的后端自定义插件。在下一部分中,我们将介绍它的前端对应部分,它在前端显示一个漂亮的产品块!

结论

今天,我们讨论了 OpenCart 中的自定义插件开发。在这个由两部分组成的系列的第一部分中,我们完成了后端插件开发并创建了一个提供配置表单的工作自定义插件。

如果您正在寻找可在自己的项目或自己的教育中使用的其他 OpenCart 工具、实用程序、扩展程序等,请查看我们在市场上提供的产品。

在下一部分中,我们将通过创建在前端显示产品列表的前端部分来完成该插件。如有任何疑问和反馈,请使用下面的评论源。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

2525

2023.09.01

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

1604

2023.10.11

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

1496

2023.10.11

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

952

2023.10.23

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

1416

2023.10.23

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

1234

2023.11.03

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1445

2023.11.09

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1306

2023.11.13

Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

61

2026.01.14

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号