zoukankan      html  css  js  c++  java
  • Joomla 2.5 MVC剖析

    Joomla整个系统,由core, component, module, plugin组成,而component是唯一拥有数据结构特征的部分,所以joomla把它设计为MVC结构,让数据结构表现更清晰。并且component是joomla扩展开发中最复杂的部分。

    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:模型,为系统提供更抽象的数据管理,它的存在,可以使开发人员不必关心数据库操作。

    MVC类命名规则

    默认情况下,主控制器AController -> 子控制器AControllerB关联(AModelB,TableB,AViewB)

    而TableB这个命名容易与其它组件名称冲突,所以一般会在AModelB中给它指定前缀,把TableB改为ATableB。

    MVC之类的关系是自动建立的,不需要额外声明。例如在AViewB中使用getModel,系统会自动获取AModelB,在AModelB使用getTable,会自动获取TableB。刚接触Joomla开发的人,可能会因为写错了类名而出现报错。

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

    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继承类,直接与它交互。

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

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

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

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

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

    PS:由于PHP很简单很灵活,可以很多PHPer都不注重开发规范,这样长期下去的结果是项目质量的下降。例如在joomla中想操作数据库,大多数人会直接写SQL,读取写入。这在Joomla1.5中或许没有多大关系,因为joomla1.5的表关联不太紧密。但在Joomla2.5中关联表就很多,例如ACL功能、User group,都有大量的关联表,单纯写入一个表,系统有可能识别不了。在MVC的体系中,Model是专门写数据库打交道的部分,所有SQL应该写在Model,要使用数据时,就调用Model的方法。

    调用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主要的task有edit, add, save

    JControllerAdmin主要的task有delete, 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

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

    拥有管理功能的模型类

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

    使用JModelForm至少需要重写save,getItem,loadFormData与getForm

    save: 数据存取时的操作

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

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

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

    使用JModelAdmin只需要重写getItems,loadFormData与getForm

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

    拥有管理功能的模型类

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

    使用JModelForm至少需要重写save,getItem,loadFormData与getForm

    save: 数据存取时的操作

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

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

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

    使用JModelAdmin只需要重写getItems,loadFormData与getForm

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

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

    JModelList

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

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

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

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

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

    JModelForm

    优化model的form能力

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

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

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

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

    JModelAdmin

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

    转自:http://www.cnblogs.com/catcat811/archive/2012/07/22/2590738.html

  • 相关阅读:
    GO语言(golang)官方网站!
    Android官方网站!
    如何使用Gmail的别名功能?
    函数指针
    单例 ------ JAVA实现
    网络通信方案 ------ 以太网通信软硬件实现方案
    nginx的启动和关闭
    FineReport软件
    nginx的MainLine version、Stable version、Legacy versions
    linux常用命令
  • 原文地址:https://www.cnblogs.com/houtaoliang/p/5196304.html
Copyright © 2011-2022 走看看