opencart 模块开发详解

xiekanxiyang » 2013年 7月 11日 10:17 pm

opencart 将页面分成若干模块, 每个模块可以有多个实例(可能这样说不是很恰当) 每个实例可以指定它出现在哪个页面 这样更好的实现了代码的可重用性,可以达到更好的页面布局的可调节性. Opencar内置了几个模块,但实际应用中我们经常要根据需要开发自己模块,现在我给大家介绍下opencart的模块开发的细节

开发步骤:
首先:模块代码也分前台,后台. 后台功能是模块的安装,编辑,模块实例参数的设置等,而前台代码相对简单些就是将内容调出来显示在指定位置.
OC
是MVC+L设计 所以我们加一个功能时候通常会有四个文件 也就是:控制器(C)、模型(M)、视图(V)和 语言文件(L)
今天我们讲的模块有点特殊它的数据是存放在setting表里的,这样所有的模块model用setting的model就可以了 不需要另外写了,
这样我们开发新的模块,有这3个文件就可以了 前后台都一样,文件分别是 C+V+L;
它们分别放在各自文件下的module文件夹里,如果开发的话找个oc内置模块的将这3个文件复制份简单的替换下,如果新加的字段加上就可以了 ,
就能制作个新的模块。前台同样也有3个文件复制小改下就ok!这样一个新的模块就完成了。

模块安装:
在OC后台
Extensions > Moules 是模块管理页,
打开这个页它会检索admin\controller\module的所有文件,提取文件名作为模块名称
所以在这文件夹中的所有文件他都会认为是一个模块.
然后在数据库的oc_extension表中查询type为module中的记录,其中code字段就是已安装的模块名称。
也就是说在文件夹里的文件是所有的模块, 如果同时存在于oc_extension中,就认为是已安装的模块。 如果没有安装点击
安装后模块名插入此表。

模块后台代码分析:
以account模块为例,控制器代码如下 我加了注释供大家参考

    <?php
class ControllerModuleAccount extends Controller {
private $error = array(); public function index() {
$this->language->load('module/account'); //导入语言文件 $this->document->setTitle($this->language->get('heading_title')); //将语言文件里的 heading_title 设为标题 $this->load->model('setting/setting'); //加载 setting model 因为模型的实例的参数是放到oc_setting表中的 if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validate()) { //如果有POST数据 并且检测用户权限通过
$this->model_setting_setting->editSetting('account', $this->request->post); //将数据更新到oc_setting表 $this->session->data['success'] = $this->language->get('text_success'); $this->redirect($this->url->link('extension/module', 'token=' . $this->session->data['token'], 'SSL'));//更新完成跳回模型管理页
} //以下内容为语言文件的内容赋值到相应变量
$this->data['heading_title'] = $this->language->get('heading_title'); $this->data['text_enabled'] = $this->language->get('text_enabled');
$this->data['text_disabled'] = $this->language->get('text_disabled');
$this->data['text_content_top'] = $this->language->get('text_content_top');
$this->data['text_content_bottom'] = $this->language->get('text_content_bottom');
$this->data['text_column_left'] = $this->language->get('text_column_left');
$this->data['text_column_right'] = $this->language->get('text_column_right'); $this->data['entry_layout'] = $this->language->get('entry_layout');
$this->data['entry_position'] = $this->language->get('entry_position');
$this->data['entry_status'] = $this->language->get('entry_status');
$this->data['entry_sort_order'] = $this->language->get('entry_sort_order'); $this->data['button_save'] = $this->language->get('button_save');
$this->data['button_cancel'] = $this->language->get('button_cancel');
$this->data['button_add_module'] = $this->language->get('button_add_module');
$this->data['button_remove'] = $this->language->get('button_remove'); if (isset($this->error['warning'])) {
$this->data['error_warning'] = $this->error['warning'];
} else {
$this->data['error_warning'] = '';
} $this->data['breadcrumbs'] = array(); //面包屑导航
$this->data['breadcrumbs'][] = array(
'text' => $this->language->get('text_home'),
'href' => $this->url->link('common/home', 'token=' . $this->session->data['token'], 'SSL'),
'separator' => false
); $this->data['breadcrumbs'][] = array(
'text' => $this->language->get('text_module'),
'href' => $this->url->link('extension/module', 'token=' . $this->session->data['token'], 'SSL'),
'separator' => ' :: '
); $this->data['breadcrumbs'][] = array(
'text' => $this->language->get('heading_title'),
'href' => $this->url->link('module/account', 'token=' . $this->session->data['token'], 'SSL'),
'separator' => ' :: '
); //post提交链接
$this->data['action'] = $this->url->link('module/account', 'token=' . $this->session->data['token'], 'SSL');
//取消按键的链接
$this->data['cancel'] = $this->url->link('extension/module', 'token=' . $this->session->data['token'], 'SSL'); $this->data['modules'] = array(); //获取模型的参数
if (isset($this->request->post['account_module'])) {
$this->data['modules'] = $this->request->post['account_module'];
} elseif ($this->config->get('account_module')) {
$this->data['modules'] = $this->config->get('account_module');
} $this->load->model('design/layout'); //获取布局
$this->data['layouts'] = $this->model_design_layout->getLayouts(); //导入模板文件
$this->template = 'module/account.tpl';
$this->children = array(
'common/header',
'common/footer'
); $this->response->setOutput($this->render());
} //检测用户权限
protected function validate() {
if (!$this->user->hasPermission('modify', 'module/account')) {
$this->error['warning'] = $this->language->get('error_permission');
} if (!$this->error) {
return true;
} else {
return false;
}
}
}
?>

图片是模块参数在setting表中的记录 其中value就是参数数组序列化后的字符串

语言文件和模板就很简单了 这里就不说了

前台代码也很简单只是查出数据显示出来 一看就明白 也就不说了

模块前台显示机制:
模块设置时候会有个位置(position)选项 也就是模块在你指定页中的位置 有四个选项:content Top 、content Bottom 、column Left 、column Right四个选项。这里你选择哪个选项就会在哪个位置调用。

四个选项对应会有四个文件(控制器)
在前台控制器中catalog\controller\common这个路径下的同名文件便是,这里就是调用的地方。拿content
Top为例所有位置为content Top的模块都在 content_top.php文件中调用。 你指定的布局页会调用这四个文件
,所以就会调用你设定的模块了

Content Top 核心内容我加了注释 代码如下:

    <?php
class ControllerCommonContentTop extends Controller {
protected function index() {
$this->load->model('design/layout');
$this->load->model('catalog/category');
$this->load->model('catalog/product');
$this->load->model('catalog/information'); if (isset($this->request->get['route'])) {
$route = (string)$this->request->get['route'];
} else {
$route = 'common/home';
} $layout_id = 0; if ($route == 'product/category' && isset($this->request->get['path'])) {
$path = explode('_', (string)$this->request->get['path']); $layout_id = $this->model_catalog_category->getCategoryLayoutId(end($path));
} if ($route == 'product/product' && isset($this->request->get['product_id'])) {
$layout_id = $this->model_catalog_product->getProductLayoutId($this->request->get['product_id']);
} if ($route == 'information/information' && isset($this->request->get['information_id'])) {
$layout_id = $this->model_catalog_information->getInformationLayoutId($this->request->get['information_id']);
} if (!$layout_id) {
$layout_id = $this->model_design_layout->getLayout($route);
} if (!$layout_id) {
$layout_id = $this->config->get('config_layout_id');
} $module_data = array(); //加载extension model
$this->load->model('setting/extension'); //读取所有安装的模块
$extensions = $this->model_setting_extension->getExtensions('module'); foreach ($extensions as $extension) {
//读出每个模块的参数配置 模块参数是放到setting表中的 setting表中所有的数据在初始化时候就全读到config类里了 所有这里不需要读数据库
$modules = $this->config->get($extension['code'] . '_module'); if ($modules) {
foreach ($modules as $module) {
//过滤掉不是content_top的模块
if ($module['layout_id'] == $layout_id && $module['position'] == 'content_top' && $module['status']) {
$module_data[] = array(
'code' => $extension['code'],
'setting' => $module,
'sort_order' => $module['sort_order']
);
}
}
}
} $sort_order = array(); foreach ($module_data as $key => $value) {
$sort_order[$key] = $value['sort_order'];
}
//排序 这里大家明白了吧 排序在在整个位置排序 所有模块按sort_order排序 并不是每个模块单独排序! 这里大家一定要主要不然就会出乱子了!
array_multisort($sort_order, SORT_ASC, $module_data); $this->data['modules'] = array(); //$module_data里现在放的就是 content_top里所有的模块了 循环调用他们的控制器 就是module里模块对应的控制器 $module['setting']作为参数传入
foreach ($module_data as $module) {
//module 返回的html代码
$module = $this->getChild('module/' . $module['code'], $module['setting']); if ($module) {
$this->data['modules'][] = $module;
}
} //加载content_top的模板 模板很代码非常简单 就是循环输出 $module 也就是模块返回的html代码
if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/common/content_top.tpl')) {
$this->template = $this->config->get('config_template') . '/template/common/content_top.tpl';
} else {
$this->template = 'default/template/common/content_top.tpl';
} $this->render();
}
}
?>

最后总结下 因为模块参数是放到setting表中的所以后台存的时候不需要设置模型 用setting的模型就可以了
前台setting数据会在OC初始化的时候就读入config类里边了 所以连加载setting模型都省了 。另外排序的有效范围是按位置来分的,
比如content Top中所有的模块实例排序,并不是模块实例间排序!

这样是不是来龙去脉都打通了! 再设计模块就会很轻松了吧 。

opencart 模块开发详解的更多相关文章

  1. STM32开发 -- 4G模块开发详解(转)

    STM32开发 -- 4G模块开发详解(1) STM32开发 -- 4G模块开发详解(2) STM32开发 -- 4G模块开发详解(3) STM32开发 -- 4G模块开发详解(4)

  2. Springboot分模块开发详解(1):建立父工程

    基础服务,见下: base是父工程,base-entity是实体层,base-dao是DAO层,base-service是业务层,base-controller是WEB控制器层,base-web是页面 ...

  3. Springboot分模块开发详解(2):建立子工程

    1.创建base-entity 选中base工程,右键创建一个新的maven工程 自动选择了base这个目录存放子工程 创建后,pom.xml修改成如下内容: <?xml version=&qu ...

  4. EasyPR--开发详解(6)SVM开发详解

    在前面的几篇文章中,我们介绍了EasyPR中车牌定位模块的相关内容.本文开始分析车牌定位模块后续步骤的车牌判断模块.车牌判断模块是EasyPR中的基于机器学习模型的一个模块,这个模型就是作者前文中从机 ...

  5. 基于H5的微信支付开发详解

    这次总结一下用户在微信内打开网页时,可以调用微信支付完成下单功能的模块开发,也就是在微信内的H5页面通过jsApi接口实现支付功能.当然了,微信官网上的微信支付开发文档也讲解的很详细,并且有实现代码可 ...

  6. ****基于H5的微信支付开发详解[转]

    这次总结一下用户在微信内打开网页时,可以调用微信支付完成下单功能的模块开发,也就是在微信内的H5页面通过jsApi接口实现支付功能.当然了,微信官网上的微信支付开发文档也讲解的很详细,并且有实现代码可 ...

  7. AngularJS模块的详解

    AngularJS模块的详解 在讲angularjs的模块之前,我们先介绍一下angular的一些知识点: AngularJS是纯客户端技术,完全用Javascript编写的.它使用的是网页开发的常规 ...

  8. Xamarin+Prism开发详解七:Plugin开发与打包测试

    有了上章[Xamarin+Prism开发详解六:DependencyService与IPlatformInitializer的关系]的基础,现在来理解Plugin开发就简单了. 本文实例代码地址:ht ...

  9. ***PHP基于H5的微信支付开发详解(CI框架)

    这次总结一下用户在微信内打开网页时,可以调用微信支付完成下单功能的模块开发,也就是在微信内的H5页面通过jsApi接口实现支付功能.当然了,微信官网上的微信支付开发文档也讲解的很详细,并且有实现代码可 ...

随机推荐

  1. 【zz】C++中struct与class的区别

    转载来源:http://blog.sina.com.cn/s/blog_48f587a80100k630.html C++中的struct对C中的struct进行了扩充,它已经不再只是一个包含不同数据 ...

  2. 直接将视频文件原码流转换成YUV,输出到屏幕显示

    #include "stdafx.h" #define inline _inline#ifndef INT64_C#define INT64_C(c) (c ## LL)#defi ...

  3. Xmanager连接CentOS的远程桌面

    本文主要介绍通过Xmanager连接CentOS远程桌面时,在CentOS系统上需要做的一些配置. 1. Xmanager简介 Xmanager是一个运行于 Windows平台上的高性能的X Serv ...

  4. Win8/Win7系统下用IE11浏览器调试js脚本

    作为一个web开发者,调试js脚本是工作中的一部分,但是并不是所有的浏览器都会很好的兼容js脚本的.随着win8系统的发布,ie11也慢慢进入了大家的视野,ie11的众多优点及新特性就不必多说了(全面 ...

  5. U盘安装 OSX

    首先,刚从app store下载完的OS X Lion会放在屏幕下方的Dock中. 用鼠标将Mac OS X Lion 10.7文件从Dock中拖放到桌面. 右键单击Mac OS X Lion 10. ...

  6. HDU --2665

    Kth number Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  7. [转]让程序在崩溃时体面的退出之Unhandled Exception

    原文地址:http://blog.csdn.net/starlee/article/details/6613424 程序是由代码编译出来的,而代码是由人写的.人非圣贤,孰能无过.所以由人写的代码有缺陷 ...

  8. 高清摄像头MIPI接口与ARM处理器的连接

    MIPI摄像头常见于手机.平板中,支持500万像素以上高清分辨率.它的全称为“Mobile Industry Processor Interface”,分为MIPI DSI 和MIPI CSI,分别对 ...

  9. VShell破解版

    VShell破解版 VShell破解版

  10. 【转】Gabor 入门

    Computer Vision Tutorials Search Primary Menu Skip to content Tutorials Search for:   Gabor Filters ...