Supporting plugins in your component
From Joomla! Documentation
Revision as of 13:23, 22 April 2008 by Joatmon
The event system in Joomla! 1.5 allows for a flexible method for components, modules and plug-ins to communicate with other plug-ins 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 plug-in) 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 back to the communicator.
Joomla! 1.5 Observer Implementation
Joomla! 1.5 implements the Observer pattern at a global level through the JPlugin (Observer) and JDispatcher (Observable) classes. Anyone wanting to receive notification of events will create a plug-in that extends the JPlugin class. Subclasses of JPlugin will automatically register themselves to the global JDispatcher class when their plug-in category has been loaded (more on that later). The JDispatcher class is used as a dispatching mechanism that receives events from the communicators and forwards them on to the listeners that have been loaded.
Why Become A Communicator
There may be certain 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 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 plug-ins that have implemented that event will be notified with the information and can handle it as they see fit. Instant communication!
How To Become A Communicator
Since all of the dispatching is handled by the Joomla! core, it is pretty easy to become a communicator. In fact it's really just a matter of loading a certain set of plug-ins and calling the trigger method of the JDispatcher class.
You may wonder how to know which set of plug-ins to load. Well, really that's up to you. Plug-ins are managed at a group level that is defined in the plug-in's XML deployment file. There are eight predefined plug-in groups and each plug-in group is meant to handle a different set of tasks. For example, there is a "search" plug-in group that is meant to handle searching and an "user" plug-in group meant to handle user specific functions such as adding and removing a user from the Joomla! system. These plug-in groups are only loaded when they are needed, namely by the communicator. So, you can create your own plug-in group and call it whatever you want. Because your component is well defined, all listeners will know exactly which plug-in group and events they should be listening for.
How To Trigger Events
This leads us to the meat of this article. How to trigger events so implementing plug-ins can act on them. Well, the first thing you need to do is to load your plug-in group. This is done via the following code:
JPluginHelper::importPlugin( 'myplugingroup' );
This will load all enabled plug-ins that have defined themselves as part of your group. The next thing you need to do is get an instance of the JDispatcher class like so:
$dispatcher =& JDispatcher::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 JDispatcher object which contains a list of all the plug-ins available. Second, we are using the =& construct to make sure we have a reference to the instance of the JDispatcher and not a copy. Of course this really only applies to PHP version 4, but since you are a good cross-version developer, you will allow for PHP 4 users.
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. All plug-ins will receive these parameters, process them and optionally pass back information. You can then handle that information however you like.
One thing to notice about the trigger method is that there is nothing defining which group of plug-ins should be notified. In actuality, all plug-ins that have been loaded are notified regardless of the group they are in. So, it's important to make sure you have an event name that does not conflict with any other plug-in group's event name. Most of the time this is not an issue because your component is the one that is loading the plug-in 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, so you have to make sure you don't have any event naming conflicts with the system events.