joomla/joomla-cms — pull request #4308 by amazeika (2014-09-19 14:49:33+00:00)
Title: Fixed event dispatching inconsistencies leading to incomplete API

# Reason

Incomplete API. We spotted inconsistencies on some component models which are not properly triggering events as expected. This results in an incomplete and inconsistent API for developers. For example in our case we would like to be able to keep track of extension events, which is currently not possible.

# Problem

Some model’s methods are being overridden without calling their parent method. By not calling the parent the event dispatching process is being bypassed.

# Example

[MenusModelItem::save](https://github.com/joomla/joomla-cms/blob/3.3.3/administrator/components/com_menus/models/item.php#L1141) does not trigger the before/after save events because it does not call its parent.

# Patch

This patch includes the following fixes and enhancements:

- It aims to solve the issue by properly taking care of the dispatching process on model actions.
- It also improves JModelAdmin a bit by reducing the amount of required code in some cases, e.g. extending JModelAdmin and wanting to trigger events on plugins other than content.
- Additionally event support was also added to com_config component save actions.

# The API

Extreme care has been taken in order to provide full backwards compatibility, meaning that no API change has been introduced in this patch. However, we would like to report some anomalies that are a direct consequence of the previous inheritance approach being used.

Delete and state change actions from [PluginsModelPlugin](https://github.com/joomla/joomla-cms/blob/3.3.3/administrator/components/com_plugins/models/plugin.php) are inherited from [JModelAdmin](https://github.com/joomla/joomla-cms/blob/3.3.3/libraries/legacy/model/admin.php). This means that until now, the events being triggered for these actions are onContent(Before/After)Delete and onContentChangeState respectively.

On the other hand, onExtension(Before/After)Save events are triggered on [PluginsModelPlugin::save](https://github.com/joomla/joomla-cms/blob/3.3.3/administrator/components/com_plugins/models/plugin.php#L309) calls. This introduces inconsistencies in the API.

One possible approach to fix this would be to use extension events for the delete and change state actions, i.e. onExtension(Before/After)Delete and onExtensionChangeState respectively.

However, and in order to keep things clean while ensuring backward compatibility, we decided not to introduce these changes, but to report them.

This same behavior can be observed on [ModulesModelModule](https://github.com/joomla/joomla-cms/blob/3.3.3/administrator/components/com_modules/models/module.php) and [LanguagesLanguage](https://github.com/joomla/joomla-cms/blob/3.3.3/administrator/components/com_modules/models/module.php).

onExtension(After/Before)Delete events have been introduced on [ModulesModelModule::delete](https://github.com/nooku/joomla-cms/blob/staging/administrator/components/com_modules/models/module.php#L377) and [TemplatesModelStyle::delete](https://github.com/nooku/joomla-cms/blob/staging/administrator/components/com_templates/models/style.php#L87) calls. Since no events were previously triggered on these calls, triggering these new events does not introduce an API change which might lead to backward compatibility problems.

# Tests

In order to properly test this patch, we have developed a small package for catching events. We have called it Catcher.

The package includes a library and set of configurable plugins. These plugins catch events and reports them (optionally with event data) to the UI using the Joomla! messaging queue.

The Catcher package may be found in the following repo:

[https://github.com/nooku/joomla-catcher](https://github.com/nooku/joomla-catcher)

The package may be installed in using composer or by building a package.

## Composer install

This is the easiest way to install the Catcher. The first step is to [download composer](https://getcomposer.org/download/) on your Joomla! site root path. Then create a new composer.json file (also in the root directory of the site) with the following content:

```
{
"require": {
"nooku/pkg_catcher": "1.*"
}
}
````

The next and last step is to run the following command from your terminal while located in the site root directory:

```
php composer.phar install
```

## Package install

For convenience, a [phing](http://www.phing.info/) script for building the package is also available under the [/scripts/build](https://github.com/amazeika/catcher/tree/master/scripts/build) folder of the repo.

After the package is installed, make sure to enable the plugins and configure them to catch and report events.

Thanks in advance for considering this patch.

The Timble team.
[http://www.timble.net](http://www.timble.net)