-
Notifications
You must be signed in to change notification settings - Fork 0
Model behaviors
Models can implement complex, reusable functionality using behaviours. Model Behaviors are a handy way to alter the workflow of a Model. It's based upon the standard Observer pattern.
One or more Behavior classes are assigned ("listen") to the Model's events. The Model events are triggered before and after certain Model actions. It's exactly what you handle in the onBefore/onAfter methods and through Joomla! plugins. The difference between Model behaviors and Joomla! plugins is that whereas plugins listen to all Models' events, behaviors only listen to events coming from the specific model they are attached to.
It's possible to register different behaviors per model; they can be added in the contructor or even on the fly, after the model has been created.
FOF provides behavior classes for a lot of common tasks. These can be used by any DataModel object. They can be found in the Model/DataModel/Behavior directory of FOF. None of them is loaded by default.
You can override the constructor of your model and add the behaviours you want in the behaviours
key of the $config
array, e.g.
public function __construct(Container $container, array $config = array())
{
$config['behaviours'] = array('Filters', 'ContentHistory');
parent::__construct($container, $config);
}
Likewise, you can set the behaviours
key when getting a model instance through the factory
$model = $this->container->factory->model('Items', array('behaviours' => array('Filters', 'ContentHistory')));
You can insert behaviour dynamically in an already loaded model:
$model->addBehaviour('Filters');
Or you can attach a behaviour object instance:
$model->getBehavioursDispatcher()->attach($behaviourObject);
Finally, if you're using the Magic or MagicSwitch factory you can add behaviours through the fof.xml file.
As you saw above, you tell DataModel to load a behaviour by name, e.g. "Filter". How does it know which class to load?
FOF will automatically look for the following class names. The first of these classes found wins.
- componentNamespace\Model\Behaviour\currentModelName\behaviourName
- componentNamespace\Model\Behaviour\behaviourName
- FOF30\Model\DataModel\Behaviour\behaviourName
where:
- componentNamespace is the namespace prefix for your component
- currentModelName is the name of the current Model class
- behaviourName is the name of the behaviour you are adding.
For example, consider a component com_example which is under the namespace Acme\Example
, in the back-end, its Items model and adding the Filters behaviour like in the following code:
FOF30\Container\Container::getInstance('com_example')
->factory->model('Items', array('behaviours' => array('Filters')))->
The classes which FOF will look for are:
- Acme\Example\Admin\Model\Behaviour\Items\Filters
- Acme\Example\Admin\Model\Behaviour\Filters
- FOF30\Model\DataModel\Behaviour\Filters
This allows you to customise or define different behaviours per component and per model of the component.
FOF comes with a few pre-defined behaviours for common tasks.
Adding this behaviour to a model object filters the items list by the viewing access levels the currently logged in user has.
Important This behaviour requires the filters behaviour. If you have not added the "Filters" behaviour it will not have any effect on browse views. It will, however, work on edit and read views.
This behaviour relies on the existence of the access
magic field.
This behavior manages the Joomla! ACL assets for a record if the asset_id
field exists in the table.
This behavior manages the content history related to the current record.
Important This behavior requires a parameter save_history
in your component's config.xml
.
Adding this behaviour to a model object will extent the filters behavior and allows FOF to filter against explicitly set zero values. For example, if you pass &foobar=0 in the URL then the SQL query used to fetch the items list will be filtered by the rows where the foobar column is set to 0. Without this behavior the filter for column foobar will be considered as empty and no filtering will be performed against this column.
Important This behaviour requires the filters behavior.
Adding this behaviour to a model object filters the items list to include only the items which are published (enabled = 1).
This behaviour relies on the existence of the enabled
magic field.
Important This behaviour only works on browse views.
Adding this behaviour to a model object allows FOF to magically apply filters based on the input data. For example, if you pass &foobar=1
in the URL, or –more generally speaking– have a foobar
state variable with a value of 1 then the SQL query used to fetch the items list will be filtered by the rows where the foobar
column is set to 1.
The filters behaviour is smart enough to recognise the type of your table fields and apply the correct type filter each time. There are several different filtering methods per field type. Besides the default filtering method which is used when you only use a plain value in the state variable you can select a different method. To do that you need to pass a hash (keyed) array in the state variable like this array('method' => 'between', 'from' => 1, 'to' => 10)
or, in URL query format, &foobar[method]=between&foobar[from]=1&foobar[to]=10
.
So, let's discuss the available match types per field type.
For numeric fields you can use the following filtering methods:
exact
This is the default method. You can just pass the value you want to search. If you want to use the hash array format you have the following keys:
- method : exact
- value : the value you want to search
partial
For numeric fields this is just an alias to exact.
between
Returns records whose field value is inside the space between two numbers, inclusive. You have the following keys:
- method : between
- from : Left barrier of the number space
- to : Right barrier of the number space
For example from=1 and to=10 will search for any value between 1 to 10, including 1 and 10.
outside
Returns records whose field value is outside the space between two numbers, exclusive. You have the following keys:
- method : outside
- from : Left barrier of the number space
- to : Right barrier of the number space
For example from=1 and to=10 will search for any value lower than 1 or greater than 10, excluding 1 and 10.
interval
Returns records whose field value is inside the space between two numbers, inclusive, based on value and interval. You have the following keys:
- method : interval
- value : The starting value of the number space
- interval : The interval of the number space
For example value=5 interval=2 will search for any value between 3 to 7, including 3 and 7.
range
Returns records whose field value is inside the space in a range, inclusive. You have the following keys:
- method : range
- from : Left barrier of the number space
- to : Right barrier of the number space
For example from=1 will search for any value greater than 1, including 1. And from=1 and to=10 will search for any value between 1 to 10, including 1 and 10.
modulo
Returns records whose field value is following an modulo interval (arithmetical progression)
- method : modulo
- value : The starting value of the interval
- interval : The interval period
For example value=7 interval=3 will search for values 7, 10, 13, 16 and so on.
For boolean (tiny integer) fields you can use the following methods:
exact
This is the default method. You can just pass the value you want to search. If you want to use the hash array format you have the following keys:
- method : exact
- value : the value you want to search
For text fields you can use the following methods:
partial
This is the default method. You can just pass the value you want to search. The records returned have that value somewhere in their fields (partial text search). If you want to use the hash array format you have the following keys:
- method : partial
- value : the partial phrase you want to search
exact
Performs an exact search. The fields' values must be exactly equal to the value you use here. You have the following keys:
- method : exact
- value : the exact phrase you want to search
For date and date/time fields you can use the following methods:
exact
This is the default method. Performs an exact search. The fields' values must be exactly equal to the value you use here. You have the following keys:
- method : exact
- value : the exact phrase you want to search
partial
You can just pass the value you want to search. The records returned have that value somewhere in their fields (partial text search). If you want to use the hash array format you have the following keys:
- method : partial
- value : the partial phrase you want to search
between
Returns records whose field value is inside the space between two dates, inclusive. You have the following keys:
- method : between
- from : Left barrier of the date space
- to : Right barrier of the date space
outside
Returns records whose field value is outside the space between two dates, exclusive. You have the following keys:
- method : outside
- from : Left barrier of the number space
- to : Right barrier of the number space
interval
Please note that this method currently only works with MySQL. Returns records whose field value is following an interval (arithmetical progression).
- method : interval
- value : The starting value of the interval
- interval : The interval period. The interval can either be a string or an array. As a string it contains a sign (+ to go to the future or - to go to the past), the numeric portion of the interval period and the actual interval (days, months, years, weeks). For example:
+1 month
to search for values every one month in the future or-1 month
to search for values every one month in the past. As an array it can look like this array('sign' => '+', 'value' => '1', 'unit' => 'month')
range
Returns records whose field value is inside the space in a date range, inclusive. You have the following keys:
- method : range
- from : Left barrier of the date space
- to : Right barrier of the date space
Adding this behaviour to a model object filters items list by language, displaying only the items whose language matches the currently enabled language. Obviously this only has an effect on the front-end of "multilanguage" sites when the Joomla! language filter plugin is enabled.
Important This behaviour requires the language
magic field.
This was called "private" in FOF 2. It was renamed since "private" is a reserved PHP word.
Adding this behaviour to a model object filters the items list by the created_by
user, showing only items that have been created by the currently logged in user. Items not created by the current user will not be displayed.
Adding this behaviour to a model object pushes Joomla! page parameters to the model state. This is especially useful
in conjunction with the Filters behaviour. Create a menu item parameter in your Joomla! view XML file (e.g.
component/com_example/views/MyView/tmpl/default.xml
) with the same name as a table field. If the site owner sets this
parameter the PageParametersToState behaviour will push that value to the model's state, therefore automatically
filtering the view based on the page parameter setting.
Obviously, this behaviour only has effect when used in the front-end of your component. This is the only case you have page parameters.
This behaviour is required by the has()
method of DataModel and is added automatically when you use the has()
method.
This behavior deals with Joomla! Tags related to the record. It will be applied only if the _has_tags
property is set to true (or you run $model->setHasTags(true)
against your model object). Check the howto for more details.
All FOF events issued by the Model are handled both internally, with specific object methods, any by automatically triggering the behaviour observer events. The observer methods have the same name as the Model even handlers, with an added first parameter $model
which has a reference to the calling model.
For example, let's consider the onBeforeSave
event of the DataModel. When you create a method handler in your DataModel object the method signature is:
protected method onBeforeSave(&$data);
When creating a behaviour event handler the method signature is:
protected method onBeforeSave(DataModel $model, &$data);
The $model
parameter holds a reference to the model object instance which triggered the event you're handling in this plugin event handler.
FOF (Framework on Framework) and its documentation are Copyright © 2010-2020 Nicholas K. Dionysopoulos / Akeeba Ltd.
FOF is Open Source Software, distributed under the GNU General Public License, version 2 of the license, or (at your option) any later version.
The FOF Wiki content is provided under the GNU Free Documentation License, version 1.3 of the license, or (at your option) any later version.
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license can be found on the GNU site.