Skip to content
continga edited this page Nov 9, 2017 · 5 revisions

The Model is where the bulk of your business logic is implemented. Its job is to act on its state and either modify it or return something back to the View (or Controller) which called it. Please notice the very important distinction between state and request: the Model acts based on the data found in its state. It doesn't directly read data from the request! This allows it to be called from anywhere, in any context. If you ever find yourself using $this->input->get() instead of $this->getState() in your models then you're doing something wrong.

Model vs DataModel vs TreeModel

Unlike FOF 1.x and 2.x, FOF now comes with different Model classes, FOF30\Model\Model and FOF30\Model\DataModel (and its child, TreeModel). The Model class is used for models which do not talk directly to a database table. For example it could be your component's configuration, a file manager etc. The DataModel / TreeModel classes, on the other hand, are used for data-aware models, i.e. models which talk directly to a database table. This separation makes it easier to handle non-data models.

This page talks about the plain Model. You may want to also read the documentation on the data-aware DataModel and its child, the nested set TreeModel.

Class and file naming conventions

The Model class files are found inside your component's Model directory. Like all FOF classes, the Model class' name is the same as the filename and the namespace depends on what is the namespace of your component and which section (frontend, backend) you're talking about.

Considering a component com_example with namespace prefix Acme\Example and a backend Model named Makers, the file administrator/components/com_example/Model/Makers.php has the following contents:

<?php

namespace Acme\Example\Admin\Model;

class Makers extends \FOF30\Model\Model
{
    // Model implementation goes here
}

Customising your Model

You should only need to create new methods to handle your business logic.

Please remember that FOF will automatically trigger onBefore and onAfter events before and after calling your model methods. For example the events onBeforeDoSomething and onAfterDoSomething will be triggered before and after the execution of the doSomething method. You can handle them in this and children classes by creating protected methods, e.g.

protected function onBeforeDoSomething()
{
    // Do something here...
}

These events can also be handled by Joomla! plugins. Please read the page on using Joomla! plugins for FOF events.

Tip: You can see all the events called by a FOF class, e.g. FOF30\Model\DataModel, by opening its code and searching for triggerEvent. Remember to also check its parent class, e.g. FOF30\Model\Model, in case some of the events are defined there.

Getting Model object instances

In general, Model object instances are retrieved through the Factory object of your component's Container. For example:

// Get the Container of com_example
$container = FOF30\Container\Container::getInstance('com_example');
// Get an instance of the MyModel model of com_example 
$model = $container->factory->model('MyModel');

This creates a new Model object instance every single time you call it. That's why it's called a Factory: it creates new objects. Please note that you MUST NOT instantiate model objects directly.

If you are inside a Controller and want to always refer to the same object instance you can use:

$model = $this->getModel('MyModel');

which always returns the same object instance. The same holds true for the View but you need to explicitly push named models to the View from your Controller using the setModel method of the View. Please refer to the DocBlocks of the Controller and View methods for more information.

The state and the Model object instances

Every FOF model will automatically populate its state from the Joomla! user session and the request (or, more precisely, the input object of the Container). The Model state will be written back to the Joomla! user session.

The model state variables are stored in the global session using a key prefixed with the state hash, as returned by the getHash() method. Typically this is com_example.modelName. where com_example is your component's name and modelName is the name of the Model, NOT the name of the Controller (i.e. it has nothing to do with the view parameter you pass as a GET or POST variable). In FOF 3.0.0 to 3.1.1 inclusive you need to override getHash() to change this behavior. Since FOF 3.1.2 you can pass the hash option to the Model's constructor to create a custom hash. You can alternatively pass hash_view to create a view-and-model-specific state hash instead, e.g. com_example.viewName.modelName. This is the recommended course of action and can be enabled at the Controller level using the preventStateBleedover flag.

While this works very well for MVC, in most cases where you get a Model object instance you don't want that to happen. FOF Model gives you a lot of options to tell it precisely what you want it to do.

$model->tmpInstance() will return a new Model object instance which is set up to not save the model state to the user session and ignore the user session and the request (the Container's input object) when populating its state. Only explicitly set state variables will be taken into account. Furthermore, the tmpInstace() will return a model object with an empty state and, in the case of a DataModel or TreeModel, the field values and relations reset to their default state.

$model->savestate(false) tells the Model to not save its state to the Joomla! user session. Conversely, $model->savestate(true) tells the Model to save its state to the Joomla! user session. This takes effect for state variables which are set or read after calling this method.

$model->setIgnoreRequest(true) tells the Model to ignore the Joomla! user session and the request (the input object of the Container) when you are getting a model state variable. This takes effect for state variables which are read after calling this method.

$model->clearState() clears the Model's state. All model state variables are immediately unset.

For DataModel and TreeModel objects you can also use the $model->reset() method to reset the fields and relations of the model. Please consult its DocBlock for more information.

Clone this wiki locally