joomla!的controller竟然有两类

时间:2021-05-24 20:56:28

Introduction

In Joomla! 2.5 and 3.x, lots of MVC improvements were added. These improvements make a developer's task easier. In Joomla! 1.5, there is only one Controller class named JController. In Joomla! 2.5, JControllerAdmin and JControllerForm have been added as subclasses ofJControllerLegacy. So there is a different usage for these three classes in Joomla! component development. This is a pattern used by most of the Joomla! core components such as com_content and com_banners.

joomla!的controller竟然有两类 joomla!的controller竟然有两类 joomla!的controller竟然有两类 and newer
JController JController

(since 2.5.5 use JControllerLegacy for forward compatibility)

JControllerLegacy
  JControllerAdmin JControllerAdmin
  JControllerForm JControllerForm
    JControllerBase (new MVC)

If you look at the admin code for com_content, you will find controller classes located in two places: the root folder and the controllers folder. In the root folder there is a file named 'controller.php', this is the master controller of the component. It is a direct subclass of JControllerLegacy. In the controllers folder, there are many files named according to entities in the component e.g. article and articles. These controllers subclass either JControllerAdmin or JControllerForm.

Master Controller

The master controller found in the root folder is only responsible for the display task. 主控制器只负责显示任务。This is the default task for JControllerLegacy. If you look at JControllerLegacy::getInstance in com_content/content.php, only the component name was passed as a parameter. In JControllerLegacy, it uses the task variable (from the request) to determine what Controller class to load. If the task variable contains a dot (.), it assumes that this variable is in the form of controller.task or controller.method. You should know that task variable specifies method of controller to run. Then in this case, it will load controller class in controllers folder and rewrite task variable to real task. If the task does not contain a dot (.), JControllerLegacy will load the master controller located in the root folder. To simplify, we will refer to controllers in 'controllers' folder as subcontroller. You may notice that in the master controller, a default view is also specified. If there is no view variable in the URL request, this one will be used. So in general, we can conclude:

  • To use the master controller, specify a view variable as view name to use or the default one will be used.
  • To use a subcontroller, specify the task variable in the form of controller.task, clearly specified CONTROLLER_NAME.CONTROLLER_METHOD.
主控制器的作用
  • 主控制器指定view的名字,或者使用默认的
  • 使用子控制器,task的形式是CONTROLLER_NAME.CONTROLLER_METHOD

We can categorize display into two types: presenting a list of records (list view) and showing a detailed record item to the user (e.g. edit form). If we look at the articles view in com_content which displays a list of records to the user, we may notice that toolbar buttons are added according to user rights.

$JOOMLA_INSTALL/administrator/components/com_content/views/articles/view.html.php

 protected function addToolbar()
{
...

if (($canDo->get('core.edit')) || ($canDo->get('core.edit.own'))) {
JToolBarHelper::editList('article.edit');
}

...
}

For example, to edit an article the task variable would be article.edit. This will cause the article subcontroller to be loaded and the edit method to be executed. You may have a question, this mean we will display edit form to user. That is right! In general we do that, but in Joomla! 2.5 core component, it just sets the article id to be edit in the user session and redirects it to an URL like &view=article&layout=edit. And this will be handled by master controller and edit form will be presented to user. So in this case, all display will be handled by master controller and needed views.

  • If a view name is not defined in URL, default view is used and a default task (display) will be executed. We use this to display a list of records. For example, index.php?option=com_content.
  • URL中没有view变量,用默认的view来执行display任务
  • If a view is defined but the task is not, master controller loads specified view and executes display method. This is also used to display a list of records. For example, index.php?option=com_content&view=articles.
  • 有view没有task,显示特定的view来执行display
  • If a view is specified with a task (but not in the dot format), master controller loads the specified view and executes method specified by task. This case is used to display edit form, or to present one item of record to user. An example is index.php?option=com_content&view=article&layout=edit.
  • 如果一个view是特为一个任务的,主控制器会加载这个view然后执行任务的方法

When the master controller creates a view, it normally loads a model having the same name as the view and pushes model into the view. Then the view's display method is called. Doing this, in view we can get data from model using function like $this->get("Items"). In this case, view will look for method getItems in model and execute it. Doing this, we can use one controller for display all information type in component. But many views still required. This reduces the controller class and, of course, reduces code produced by developer.

Subcontrollers

Subcontrollers will handle all CRUD tasks. For tasks such as save, delete & publish that clearly do not need a view, the subcontroller just deletes or updates records and redirects the user back to list view. In this case the user must select at least one item of record, and we usually give the name of the controller in plural form such as "articles.delete", "articles.publish_up" or "articles.publish_down". This subcontroller is generally inherited from JControllerAdmin which suppress display method by default.

JControllerAdmin 执行能批量执行的任务,如 "articles.delete", "articles.publish_up" or "articles.publish_down".

The other type of CRUD, such as add or edit, at a first glance should prepare data and present the form to user. But in the core component for Joomla! 2.5, they did not do that. Looking at this kind of subcontrollers (for example ContentControllerArticle) one can see that they always are inherited from JControllerForm. But no form was presented to user in this request, it just stores item (the ID of the article) in user's session variable and redirects to master controller. As a task variable was not specified, the display method is executed as a default task.

JControllerForm执行需要Form的任务。

For example: first request being processed by subcontroller may contain task=article.edit and cid[]=3. Subcontroller will create URL like "index.php?option=com_content&view=article&layout=edit" and redirect the user to master controller.