joomla2.5 MVC剖析

MVC结构

Joomla整个系统,由core, component, module, plugin组成,而component是唯一拥有数据结构特征的部分,所以joomla把它设计为MVC结构,让数据结构表现更清晰。并且componentjoomla扩展开发中最复杂的部分。
  一个基本的组件将包含以下内ː文件目录
  • 一个HTML文件,只是一个背景颜色ː安全文件index.html
  • 一个PHP文件,代表了控制器本身ːcontroller.php
  • 一个PHP文件加载控制器类ː<component_name>.php
  • 一个PHP文件,代表模型本身ːmodels/<component_name>.php
  • 背景控制ː另一个HTML文件模特。
  • 一个包含默认视图ːPHP文件views/<component_name>/tmpl/default.php
  • 添加一个菜单项类型ːXML文件views/<component_name>/tmpl/default.xml
  • 背景控制ː另一个HTML文件views/<component_name>/tmpl/index.html
  • 背景控制ː另一个HTML文件views/<component_name>/index.html
  • 显示视图ːPHP文件views/<component_name>/view.html.php
Joomla 提供了 MVC 的基类: JView, JModel, JController, JTable 。一个完整的 joomla MVC ,必须从这四个类或者其派生类继承,而 Joomla2.5 有更丰富的派生类,来满足 joomla2.5 更多的新特征。可以阅读 com_content 的代码来了解这个关系。

JView: 视图,包括模板与数据输出逻辑。典型的view.html.php就是JView的一个实现,它的工序是从Model中得到数据,并输出到模板中。

JController: 控制器,一个组件可以有多个控制器,每个控制器会有多个task,它是程序的入口,想要joomla为你做什么,就得给它一个task.例如user.edit, user.save。

JTable: 数据表,它直接与数据库打交道,把数据库表抽象为一个JTable对象。它给Model提供可操作数据,并可以对表操作进行预处理。例如在写入表时title不很空值的判断。一般情况下,它只与Model交互,其它部分最好不要直接使用JTable。

JModel:模型,为系统提供更抽象的数据管理,它的存在,可以使开发人员不必关心数据库操作。
如: index.php?option=组件名 &view=视图名 &controller=控制器名 &layout=视图分页名
注:Task Controller 下的分支,没有 Task 时用默认处理。
    建立了 View 可以用  index.php?option=com_test&view=?  来显示,不需要写 Controller ,但必需有 Controller 存在

MVC 类命名规则
      Controller       

                   类名:控制器名Controller, 控制器名随时,但会影响ViewModel的命名

                   文件名随时,由主文件调用
  1. 主控制器AController -> 子控制器AControllerB  关联(AModelBTableBAViewB
  2. 而TableB这个命名容易与其它组件名称冲突,所以一般会在AModelB中给它指定前缀,把TableB改为ATableB。
  3. JController成员名对应task名

         View

                   类名:控制器名View视图名

                   放在views目录下,以视图名作为目录名,主文件为view.html.php,模板页在tmpl

         Model

                   类名:控制器名Model视图名

                   放在models目录下,以视图名为文件名
  1. 继承JModel,所有以get开头的成员函数都作用参数。
  2. 比如 getXXX(),  View 中可以用 $this->get('xxx') 获取返回值
MVC之类的关系是自动建立的,不需要额外声明。例如在AViewB中使用getModel,系统会自动获取AModelB,在AModelB使用getTable,会自动获取TableB。刚接触Joomla开发的人,可能会因为写错了类名而出现报错。
     Field下面的helloworld.php的命名
class  JFormFieldHelloWorld  extends JFormFieldList
常量说明

_JEXEC = 1                          入口文件标记
DS = DIRECTORY_SEPARATOR            目录分隔符
JPATH_BASE                          Joomla 的基础目录(绝对路径)
JPATH_ROOT                          Joomla 根目录(与 JPATH_BASE 一样)
JPATH_SITE                          Joomla 网站目录(与 JPATH_BASE 一样)
JPATH_ADMINISTRATOR                 管理系统目录(/administrator)
JPATH_LIBRARIES                     库目录(/libraries)
JPATH_PLUGINS                       插件目录(/plugins)
JPATH_THEMES                        主题目录(/templates)
JPATH_CACHE                         缓存目录(/cache)
JPATH_MANIFESTS                     (/administrator/manifests)
JPATH_PLATFORM                      libraries 的绝对路径
IS_WIN           是否 Windows 系统
IS_MAC           是否 MAC 系统
IS_UNIX          是否 Unix 系统
JREQUEST_NOTRIM = 1
JREQUEST_ALLOWRAW = 2
JREQUEST_ALLOWHTML = 4

从零架构一个组件是比较头痛的,因为架构代码也十分多,幸好有在线组件生成器:

http://www.notwebdesign.com/joomla-component-creator/component/combuilder/components

使用它可以根据你定义的表结构生成组件安装包,安装后就能立即拥有后台功能,省去大量的架构时间。

MVC之间的关系

table是数据结构,它是数据库上存储数据的结构原型。它只能代表一个表。joomla的每个表都必须拥有对应的JTable继承,它给model提供表的细节。只要JTable继承类建好,一般只有在model中会操作它,其它地方不必操作JTable实例。

 

JModel中要得到一个JTable

$table = $this->getTable('Users', 'UsersTable');

 

如果有必要域跨组件访问table,可以使用以下方法加载其它table路径

JTable::addIncludePath(JPATH_ADMINISTRATOR . DS . 'tables');

 

model是数据模型,有了它,用户不必了解数据存储的细节,只告诉model你要怎么操作数据,例如你要得到一个users列表;或者删除一个user,告诉它,它会完成你想要的操作。一般要得到某个组件的数据,你先要找到它的JModel继承类,直接与它交互。

 

ControllerModel有直接关系,所以JController中得到一个JModel有捷径:

$model = $this->getModel('Active', 'UsersModel');

 

model中,可能需要使用其它组件的model,例如contentcategorymodel内部得到其它model的方法


JModel::addIncludePath(JPATH_ADMINISTRATOR .DS . 'components' . DS. 'com_content' . DS . 'models');

$model = JModel::getInstance('Articles', 'ContentModel', array('ignore_request' => true));

调用 model 例子:
$model = JModel::getInstance('Articles', 'ContentModel', array('ignore_request' => true));

$model->setState('filter.state', 1);

$model->setState('list.ordering', 'publish_up');

$items = $model->getItems();

PS: 如果有ignore_request,就不会调用populateState,即不会从前端提供中得到state

 

State

model进行交互,最标准的方法就是用state,它是一种类内置的数据结构。


$model = $this->getModel('Active', 'UsersModel');

$model->setState('limit', 5);

$model->getItems();

子控制器

joomla2.5支持一个组件多个子控制器

调用方法:task=控制器后缀名.方法名,即task=user.save, task=users.delete, task=user.edit

如有一子控制器UsersControllerUser,有方法save,调用就为task=user.save

 

拥有管理功能的控制器

JControllerForm主要用于编辑页面

JControllerAdmin主要用于管理列表页面

列表页使用JControllerAdmin,编辑页使用JControllerForm

子控制器的task表达:task=控制器名.方法名,即task=user.save, task=users.delete, task=user.edit

JControllerForm主要的taskedit, add, save

JControllerAdmin主要的taskdelete, publish, saveorder

假如有一个JControllerForm派生类UserController,那它的添加地址是:index.php?option=com_user&task=user.add

修改地址是:index.php?option=com_user&task=user.edit&id=1

它的Edit Form中必须有task=user.save

同理,JControllerAdmin的派生类UsersController,就有task=users.delete, task=users.publish

注意:不要试图使用其它访问地址,如果不使用JControllerFormtask,系统将认为操作来源不可信,会禁止你的操作


拥有管理功能的模型类

JModelAdminJModelForm的派生类,对于实现一个完善的管理功能,可以只使用JModelAdmin

使用JModelForm至少需要重写save,getItemloadFormDatagetForm

save: 数据存取时的操作

getItem: 用于提取Item数据用于Form

getForm: 得到表单对象,一般做法是返回loadForm结果,loadForm会读取生成的jform数据,即form目录下的xml文件

loadFormData: 用于生成JForm的默认值,用于Edit Form的数据

使用JModelAdmin只需要重写getItemsloadFormDatagetForm

注意:form需要必须带有token, <?php echo JHtml::_('form.token'); ?>

 

另外,介绍几个Joomla新增的派生类:

 

JModelList

在大多数CMS中,分页与排序列表已经是标配功能,开发人员不必浪费时间在分页与排序上,JModelList都已经实现这两项功能。

getItems:得到列表数据,一般Model都用它来得到列表,继承自JModelList就不必对它重载。

getListQuery:抽象方法。查询字串或查询器,这是JModelList独有的方法,供getItems查询数据,order的查询语句必须写在此方法内,limitpager就不用写。

populateState:在getState时被调用,用于处理前端提交数据,实现用户交互。JModelList已经对它扩展了排序和分页的交互,如需要更多的交互性,可以再重载它。

 

PS:如果使用model前没有调用getState,将无法接收用户提交的state

 

JModelForm

优化modelform能力

loadForm:加载form。(这里的form是joomla2.5的jform,一种用XML定义一个form的技术,所以这个XML文件必须先建好)

getForm:抽象方法。得到一个form实例,通常是通过调用loadForm来得到form实例,再对它进行加工。

loadFormData:抽象方法。给Edit Form提供数据,可以直接使用getItem的数据。

 

PSform需要必须带有token, <?php echo JHtml::_('form.token'); ?>,token是一个form的认证签名,为了防止form被跨域提交。

 

JModelAdmin

功能很丰富的用于管理数据的 model ,继承自 JModelForm ,有 form save, delete,publish,saveorder,batch,checkin,checkout 等功能

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值