Supporting plugins in your component

From Joomla! Documentation

Revision as of 14:57, 6 November 2022 by Cmb (talk | contribs) (Some changes for Word2Watch compliance and other markup changes.)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Other languages:
Deutsch • ‎English • ‎Türkçe • ‎français • ‎中文(台灣)‎

The event system in Joomla! allows for a flexible method for Components, Modules and Plugins to communicate with other Plugins by following the Observer pattern. This pattern is most easily described as a simple communication mechanism. The basic premise is that zero or more "observers" or "listeners" register themselves with the system for a certain, known event. During a specific point in an application's lifecycle, the "communicator" (in our case a Component, Module or Plugin) fires the event, passing some information to all the observers. The observers can then act on the information passed to them and optionally return a result to the communicator.

Background[edit]

Joomla! Observer Implementation[edit]

Joomla! implements the Observer pattern at a global level through the JPlugin (Observer) and JEventDispatcher (Observable) classes. Anyone wanting to receive notification of events will create a Plugin that extends the JPlugin class. Subclasses of JPlugin will automatically register themselves to the global JEventDispatcher class when their Plugin category has been loaded (more on that later). The JEventDispatcher class is used as a dispatching mechanism that receives events from the communicators and forwards them to the listeners that have been loaded. For a full explanation of this read the Plugin Developer Overview

Why Become A Communicator[edit]

There may be times in your Component's lifecycle when it would be nice to notify others that some action has taken place. For example, let's say you have a compact disk (CD) library Component. You may decide that you would like to let others know when a new CD has been added to the library. In this case, you could document a well-known event (onCdAddedToLibrary for example) and at the appropriate time, 'trigger' the event passing in information about the new CD that was added to the library. All Plugins that have implemented that event will be notified with the information and can handle it as they see fit. Instant communication!

Implementation[edit]

How To Become A Communicator[edit]

Since all the dispatching is handled by the Joomla! core, it is easy to become a communicator. In fact, it's really just a matter of loading a certain set of Plugins and calling the trigger method of the JEventDispatcher class.

You may wonder how to know which set of Plugins to load. That's up to you. Plugins are managed at a group level that is defined in the Plugin's XML deployment file. There are eight predefined Plugin groups and each Plugin group is meant to handle a different set of tasks. For example, there is a search Plugin group that is meant to handle searching and a user Plugin group meant to handle user specific functions such as adding and removing a user from the Joomla! system. These Plugin groups are only loaded when they are needed, namely by the communicator. So you can create your own Plugin group and call it whatever you want. Because your Component is well-defined, all listeners will know exactly which Plugin group and events they should be listening for.

How To Trigger Events[edit]

This leads us to the meat of this article: how to trigger events so implementing Plugins can act on them. The first thing you need to do is to load your Plugin group. This is done via this code:

JPluginHelper::importPlugin( 'myPlugingroup' );

This will load all enabled Plugins that have defined themselves as part of your group. The next thing is get an instance of the JEventDispatcher class:

$dispatcher = JEventDispatcher::getInstance();

Notice two things here. First, we are using the getInstance() method, not new, to create a new instance. That is because we need to get the global singleton instance of the JEventDispatcher object that contains a list of all the Plugins available.

Next, we need to trigger our custom event:

$results = $dispatcher->trigger( 'onCdAddedToLibrary', array( &$artist, &$title ) );

Here we have triggered the event onCdAddedToLibrary and passed in the artist name and title of the track. Which and how many parameters you pass is up to you. Passing parameters by reference (using an &) allows the Plugins to change the variables passed in. All Plugins will receive these parameters, process them and optionally pass back information. The calling code can access the returned values via the array $results (each element corresponds to the result of one Plugin).

Caveats[edit]

You Are Defining An API[edit]

By offering events for Plugins to respond to, you are effectively creating an API. Proper planning is extremely important – once you release your code, other developers will start to depend on your events' names and parameters. Changing them later will break compatibility with all the Plugins that use them.

Load The Right Plugin Group[edit]

One thing to notice about the trigger method is that there is nothing defining which group of Plugins should be notified. In actuality, all Plugins that have been loaded are notified regardless of the group they are in. It's important to make sure you have an event name that does not conflict with any other Plugin group's event name. Most of the time this is not an issue because your Component is the one that is loading the Plugin group, so you know which ones are loaded. However be aware that the system Plugin group is loaded very close to the beginning of the request. Make sure you don't have any event naming conflicts with the system events.