Quick links: Content - sections - sub sections
EN FR

Jelix implements a simple inter-module communication system. It is based on events, and is called jEvent.

Anywhere in the code, it's possible to emit an event, to let the modules respond, and to use the response.

The jEvent component is similar to the client-server scheme. The client (your code) emits a request (an event). The server (the listeners in the modules) waits for a request, treats it, and returns something (a response).

So basically we have, on the one hand, the jEvent class that emits events and that gathers and return the responses, and on the other hand, some Listener classes, located in modules, that treat and respond to events.

Emiting an event

To emit an event, we use jEvent's static method notify().

jEvent::notify accepts two arguments. The first one is the name of the event you want to send (alphanumeric characters only), and the second one is an array of event parameters. As with most functions accepting parameters, the second argument is optional.

jEvent::notify returns a jEvent object, containing all the related responses. Responses are some data returned by the listeners (don't confuse with the jResponse objects returned by controllers). The structure and value of responses depend solely on each event, the number of modules that responded and how the data is structured in the listeners.

For example:


   //first way
   $authCLEventParams = array('user' => $userObject);
   $authCLEvent = jEvent::notify('authCanLogin', $authCLEventParams);

   //second way
   $authCL2Event = jEvent::notify('authCanLogin2');

To get access to the responses returned by the modules, use the getResponse method of the jEvent object that was returned after the emission.


  $reponses = $authCLEvent->getResponse();

The result is an array containing all data returned by listeners.

Responding to an event

Since there is no default listener in the modules, each module that wants to respond to events need to create a listener and declare it in the events.xml file of the same module. There is no limit in the number of listeners. The creation of the listener is broken down in two parts: the creation of the listener and the declaration of the listener.

Create a listener

First, choose a name. We will use 'auth' as an example. Then create a listener class. Note that the class name is a concatenation of the name and of 'Listener', so in our case, 'authListener'. Put that class in a file called {name}.listener.php, so auth.listener.php for us, in the classes folder of your module. Remember, your listener class must inherit from jEventListener.

The listener needs to implement one method for each event it is supposed to respond to. Those methods should follow this convertion : 'on' + 'event name'. They need to accept as single argument a jEvent object.

Example:


//file auth.listener.php

class authListener extends jEventListener{

   function onAuthCanLogin ($event) {
        //retrive user parameter
        $user = $event->getParam('user');

        //the actual processing
        $ok = true;
        if(isset($user->active)){
            $ok = ($user->active == '1');
        }
        $ok = $ok && ($user->password != '');

        //the response
        $event->Add(array('canlogin'=>$ok));
   }
}

This example demonstrates a listener responding to the AuthCanLogin event. First, the onAuthCanLogin method retrieves an 'user' parameter from the event object. Next, it does it's internal processing, and finally, it adds some data to the response by calling $event->Add.

Note: the convention of the name of methods and the calling of methods corresponding to events can be changed by redefining the method performEvent.

Declare a listener

The final step to setup a listener is to declare it. This is done through the events.xml file located in your module root folder. For example:


<events xmlns="http://jelix.org/ns/events/1.0">
   <!-- We have 2 listeners each listening for some events. However, both of them will respond to the AuthCanViewUser event. -->
   <listener name="auth">
       <event name="AuthCanLogin" />
       <event name="AuthCanViewUser" />
   </listener>
   <listener name="auth2">
       <event name="AuthCanLogin2" />
       <event name="AuthCanViewUser" />
   </listener>
</events>

A listener can listen to more than one event. Since it would take too much resources to load all the listeners one by one and check what events do they respond to, you also need to list all the events that you want a listener to listen to. Remember that two listener can also respond to the same event, and that there isn't a conventional structure for the responses.

Disabling listeners

When we use a vendor module, for any reason, we could want to deactivate one of its listener about a specific events.

It is possible by indicating them into the [disabledListeners] section in the main configuration. Keys are event name, values are selector of listeners.


[disabledListeners]
authLogin="aModule~theListener"

In this example, the listener theListener of the module "aModule" won't be called when the event authLogin will be emited.

If you deactivate several listeners for a same event, just use [] to indicate an array:


[disabledListeners]
authLogin[]="aModule~theListener"
authLogin[]="otherModule~otherListener"