Actions

J1.5

Difference between revisions of "Supporting plugins in your component"

From Joomla! Documentation

(3 intermediate revisions by 3 users not shown)
Line 1: Line 1:
{{review}}
+
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 [[wikipedia:Observer_pattern|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 to the communicator.
  
== Introduction ==
+
== Background ==
  
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 [[wikipedia:Observer_pattern|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 [http://api.joomla.org/Joomla-Framework/Plugin/JPlugin.html JPlugin] (Observer) and [http://api.joomla.org/Joomla-Framework/Event/JDispatcher.html JDispatcher] (Observable) classes. Anyone wanting to receive notification of events will create a plug-in that extends the <code>JPlugin</code> class. Subclasses of <code>JPlugin</code> will automatically register themselves to the global JDispatcher class when their plug-in category has been loaded (more on that later). The <code>JDispatcher</code> class is used as a dispatching mechanism that receives events from the communicators and forwards them on to the listeners that have been loaded.
  
== Joomla! 1.5 Observer Implementation ==
+
=== Why Become A Communicator ===
 +
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 (<code>onCdAddedToLibrary</code> 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!
  
Joomla! 1.5 implements the Observer pattern at a global level through the [http://api.joomla.org/Joomla-Framework/Plugin/JPlugin.html JPlugin] (Observer) and [http://api.joomla.org/Joomla-Framework/Event/JDispatcher.html 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.
+
== Implementation ==
  
== Why Become A Communicator ==
+
=== How To Become A Communicator ===
 +
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 plug-ins and calling the trigger method of the <code>JDispatcher</code> class.
  
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!
+
You may wonder how to know which set of plug-ins to load. 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 <tt>search</tt> plug-in group that is meant to handle searching and an <tt>user</tt> 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 Become A Communicator ==
+
=== 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. The first thing you need to do is to load your plug-in group. This is done via the following code:
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:
+
  
 
<source lang="php">
 
<source lang="php">
Line 27: Line 23:
 
</source>
 
</source>
  
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:
+
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 <code>JDispatcher</code> class:
  
 
<source lang="php">
 
<source lang="php">
Line 33: Line 29:
 
</source>
 
</source>
  
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.
+
Notice two things here. First, we are using the <code>getInstance()</code> method, not <code>new</code>, to create a new instance. That is because we need to get the global singleton instance of the JDispatcher object that contains a list of all the plug-ins available. Second, we are using the <code>=&</code> construct to make sure we have a reference to the instance of the JDispatcher and not a copy. (This really only applies to PHP version 4.)
  
 
Next, we need to trigger our custom event:
 
Next, we need to trigger our custom event:
Line 41: Line 37:
 
</source>
 
</source>
  
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.
+
Here we have triggered the event <code>onCdAddedToLibrary</code> 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 <code>&</code>) allows the plug-ins to change the variables passed in. All plug-ins will receive these parameters, process them and optionally pass back information. The calling code can access the returned values via the array <code>$results</code> (each element corresponds to the result of one plugin).
  
 
== Caveats ==
 
== Caveats ==
  
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.
+
=== You Are Defining An API ===
 +
 
 +
By offering events for plugins to respond to, you are effectively creating a [[wikipedia:API|API]]. Proper planning is extremely important &ndash; 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.
  
[[Category:Development]]
+
=== Load The Right Plugin Group ===
 +
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. 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 <tt>system</tt> plug-in 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.
 +
<noinclude>
 +
[[Category:Tutorials]]
 +
[[Category:Component Development]]
 +
[[Category:Plugins]]
 +
</noinclude>

Revision as of 12:39, 5 July 2012

Replacement filing cabinet.png
This Namespace has been archived - Please Do Not Edit or Create Pages in this namespace. Pages contain information for a Joomla! version which is no longer supported. It exists only as a historical reference, will not be improved and its content may be incomplete.

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 to the communicator.

Contents

Background

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 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 plug-ins that have implemented that event will be notified with the information and can handle it as they see fit. Instant communication!

Implementation

How To Become A Communicator

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 plug-ins and calling the trigger method of the JDispatcher class.

You may wonder how to know which set of plug-ins to load. 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. 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:

$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 that 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. (This really only applies to PHP version 4.)

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 plug-ins to change the variables passed in. All plug-ins 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

You Are Defining An API

By offering events for plugins to respond to, you are effectively creating a 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

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. 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 plug-in 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.