The Joomla MVC classes
Written by Administrator   
Wednesday, 03 March 2010
Article Index
The Joomla MVC classes
JController
JModel
JView
The MVC calling sequence

JController

The controller class is usually the first to be created and so the natural place to start.

Banner

Tasks

JController's main duty is to keep track of the possible tasks that an instance of controller can perform and map these to method calls.

A task is simply a method that can be called as a result of the a parameter or some other command usually coded as part of the URL used to invoke your application.

The base class builds a list of available tasks as part of its construction. Available tasks are defined as public methods that belong to the derived class, i.e. the base class methods are not listed as potential tasks.

Each task is created using the name of the method. That is if you define a method called MyMethod then there will be a task in the task map corresponding to the MyMethod task which calls the MyMethod method.

The controller keeps a map of task names and method names. Initially all of the public methods in the base class are added as tasks with the same name but you can add to this list using the register task method. For example,

registerTask("dosomething", 
"MyMethod");

adds the task dosomething to the list and associates it with MyMethod. You can only add public methods to the task map. Also notice that as a public method MyMethod will already be in the task map associated with the MyMethod task. There is no standard way to remove a task from the task map but you can always supply your controller with one if you need to trim the task map. For example:

class myController extends JController
{
private function removeTask($task){
unset($this->_taskMap[$task]);
}
...

removes tasks from the taskMap by task name.

The controller base class also provides a method to execute any task in the task map. That is, execute(task) will call the method corresponding to task on the active controller and return its result. Following the previous registerTask you can call MyMethod using:

execute("dosomething");

This mechanism allows you to use standard names for tasks and map them to methods with potentially different names.

The main use of this is to allow you to associate methods with standard user interface items.

For example, a Save menu item or button might be set up to return the parameter "&task=save" as part of the URL as an indication of the task that the controller should perform. To make the controller respond to this you first register the task name, i.e. "save", and the method that should be called to implement it, e.g. MySave:

registerTask("save", "MySave");

Following this you can execute the MySave method in response to the parameter in the URL using something like:

$task=$this->getTask();
$this->execute($task);

There are many variations on how to actually call a task and it isn't uncommon to see a task "hardwired":

$task=$this->getTask();
if($task=='save')$this->save();

but this isn't as flexible nor as easy to change as your application grows in size.

Another approach is halfway between using the task map and hardwiring the method call. In this case the tasks are registered but they all call a single method which then contains a switch statement to route the call to the method that actually handles the task. For example,

registerTask("save", "MyMethod");
registerTask("cancel", "MyMethod");
registerTask("edit", "MyMethod");

and MyMethod works out which task it has to complete:

function MyMethod(){
$task=$this->getTask();
switch($task){
case "save":
$this->save();
break;
case "cancel":
$this->cancel();
break;
case "edit":
$this->edit();
break;
}
}

In many ways this seems the worst of all options as it half uses the task map, so complicating the issue, but then hardwires the method calls, so not getting any of the advantages.

The task map also allows different implementations of the controller object to register different methods to respond to the same task. That is, in a different instance of the controller "dosomething" might be associated with MyAlternative method.

You can also register a default task using registerDefaultTask which is equivalent to

registerTask('_default', method);

If you try to execute a task that doesn't exist then the default task is executed, if defined.

There are also some utility methods provided to help you work with tasks.

The getTask method has already been used as part of the example and it will return the current task. Notice that this is simply the parameter provided by the URL that caused your application to be loaded. It doesn't indicate that the task has yet to be performed or has been performed. The getTask's method returns an array of all of the public methods of the controller instance, i.e all of the methods in the task map.

Model and View

One of the controller's main tasks is to keep track of the possible models and views in use.

It does this by maintaining stacks of default paths that you can also add to using the addModelPath and addViewPath methods. If you store the model in the models subdirectory and the view in the views directory then you don't have to add any extra paths as these are the defaults.

If you need to get a reference to the Model or the View you can use getModel and getView. Both of these will load the object if it hasn't already been created. You can also specify additional parameters:

  • $name - the view name defaults to the controller name property which can be retrieved using the getName method.
  • $type - the view type (view only)
  • $prefix - the class prefix
  • $config - an array of parameters to pass to the constructor.

In most cases you can allow these parameters to take their default values as long as the model and control that you are using have their default names.

There is also the display method which is a minimal implementation of a call to the View's default display method. This sets up the call by setting the basic parameters such as view type, name and layout and it creates and connects instances of the View and Model. By the time it finally passes on the call to the View's display method everything is correctly initialised.

You should always use the controller's display method to call the View's display method rather than calling it directly. If you override the Controller's display method then always remember to call the base display method. Notice also that the View has its own display method which it is very easy to confuse with the Controller's display method - especially since the Controller's display method is just another way of calling the View's display method!

Banner

Finally the Controller has a redirect method which allows it to redirect the browser to another URL. Before calling the redirect method you need to set the URL using setRedirect and optionally set the message that will be passed with the redirect.

There are also some security methods but to explain how these are used would take us into the details of Joomla security.

<ASIN:184719804X>

<ASIN:0981642101>

<ASIN:1847196209>

<ASIN:1847197167>

<ASIN:3527703357@DE>



Last Updated ( Wednesday, 03 March 2010 )