JController and its subclass usage overview
From Joomla! Documentation
Revision as of 12:27, 18 May 2012 by Mcormier
You should be familiar with Joomla! 1.5 MVC pattern before starting reading this topic. If you are not, please read other topics on this wiki.
In Joomla! 1.6, lots of MVC improvements were added. These improvements make a developer's task easier. In Joomla! 1.5, there is only one class for Controller named JController. In Joomla! 1.6, there are JControllerAdmin and JControllerForm as sublcass of JController. So there is a different usage for these three classes in Joomla! component development. This is a pattern used by most of Joomla! core components such as com_content and com_banners.
If you look at com_content backend, you will found two places for controller classes. The first one is in the root folder of component and the second one is in 'controllers' folder. In the root folder there is a file named 'controller.php', this is a master controller of the component. It is a directly subclass of JController. In controllers folder, there are many files named according to entities in the component e.g. article and articles. These controllers subclass from JControllerAdmin or JControllerForm.
The master controller found in the root folder is only responsible for display task. This is default task for JController. If you look at JController::getInstance in com_content/content.php, only component name was passed as parameter. In JController, it use task variable (from request) to handle how to load Controller class. If task varible contains 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 task does not come in dot format, JController will load master controller located in root folder as mentioned before. To simplify, we will refer to controllers in 'controllers' folder as subcontroller. You may notice that in master controller, default view is also specified there. If there is no view variable in the URL request, this one will be used. So in general, we can conclude that:-
- To use master controller, specify view varaible as view name to use or default one will be used.
- To use subcontroller, specify task varible in form of controller.task, clearly specified CONTROLLER_NAME.CONTROLLER_METHOD.
We can categorised display into two types, the first one is presenting list of records or list view and the later one is showing record of item for user e.g. edit form. If we look at articles view for com_content which displays list of records to user, we may notice that toolbar buttons were added according to user rights. For example, article edit, its task variable is article.edit. Recall that this request will load article subcontroller and execute its edit method. You may have a question, this mean we will display edit form to user. That is right! for general we do that but in Joomla! 1.6 core component, it just set article id to be edit in user session and redirect it to 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 need 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.
- 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.
- 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.
When master controller creates view, it normally loads a model having the same name as the view and pushes model into the view. Then 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 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.
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 core component for Joomla! 1.6, they did not do like 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.
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.