phpBB

Development Wiki

Difference between revisions of "Add Listeners"

From phpBB Development Wiki

(Created page with "NOTE: This article is a WIP by Unknown Bliss ==What are listeners?== Listeners are a way of injecting code and manipulating variables in the code where events exist without e...")
 
Line 1: Line 1:
NOTE: This article is a WIP by Unknown Bliss
 
 
 
==What are listeners?==
 
==What are listeners?==
 
Listeners are a way of injecting code and manipulating variables in the code where events exist without editing the code. Numerous listeners form part of a subscriber. The listener is a method within your subscriber class in your extension, which is then identified as to which event it corresponds to by an identifying method. This sounds daunting but it a lot simpler in practice.  They are part of the [[listeners]] system added in 3.1
 
Listeners are a way of injecting code and manipulating variables in the code where events exist without editing the code. Numerous listeners form part of a subscriber. The listener is a method within your subscriber class in your extension, which is then identified as to which event it corresponds to by an identifying method. This sounds daunting but it a lot simpler in practice.  They are part of the [[listeners]] system added in 3.1
  
 
==What are subscribers?==
 
==What are subscribers?==
A subscriber is a class which includes a set of listeners as methods, each of which can listen for an even to be triggered. They are 'linked' with the event by an identification method. You can have as many listeners inside a subscriber as you wish. You should only need 1 subscriber per extension however if you have a large number you may choose to split it up into several files.
+
A subscriber is a class which includes a set of listeners as methods, each of which can listen for an event to be triggered. They are 'linked' with the event by an identification method. You can have as many listeners inside a subscriber as you wish. You should only need 1 subscriber per extension however if you have a large number you may choose to split it up into several files.
  
 
==Creating a subscriber==
 
==Creating a subscriber==
Explain the file name, directory to put it in, identifier method, which class to extend etc.
+
To create a subscriber, you should create a file like <pre>ext/&lt;vendor&gt;/&lt;extname&gt;/event/<subscribername>_listener.php</pre>
 +
Note that the file must be in the 'event/' subdirectory of your extension directory and that it must end in '_listener.php'. It will not work otherwise.
 +
 
 +
Inside the file, create a class that <tt>implements EventSubscriberInterface</tt> (you need to import it from Symfony; see the example below). As with all classes in extensions, it should follow the class naming conventions (i.e. phpbb_ext_&lt;vendor&gt;_&lt;extname&gt;_event_<subscribername>_listener). Inside the class, create a <tt>static public function getSubscribedEvents()</tt> that returns an array, the keys of which contain event names and the values of which contain listener function names. An example:
 +
 
 +
<php>
 +
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 +
 
 +
class phpbb_ext_phpbb_karma_event_main_listener implements EventSubscriberInterface
 +
{
 +
static public function getSubscribedEvents()
 +
{
 +
return array(
 +
'core.viewtopic_cache_user_data' => 'viewtopic_body_add_karma_score_to_user_cache_data',
 +
);
 +
}
 +
}
 +
</php>
  
 
==Creating a listener==
 
==Creating a listener==
Explain how it injects and how to manipulate variables.
+
A listener is simply a <tt>public function</tt> in the subscriber class, referred to in the array returned by <tt>getSubscribedEvents()</tt>. It takes one argument, <tt>$event</tt>. This parameter allows you to access and modify the variables that are given to the event in the code. To illustrate this, here is the <tt>viewtopic_body_add_karma_score_to_user_cache_data</tt> listener method belonging with the example above:
 +
<php>
 +
public function viewtopic_body_add_karma_score_to_user_cache_data($event)
 +
{
 +
$user_cache_data = $event['user_cache_data'];
 +
$user_cache_data['karma_score'] = $event['row']['user_karma_score'];
 +
$event['user_cache_data'] = $user_cache_data;
 +
}
 +
</php>
 +
Note how the <tt>user_cache_data</tt> event variable is first copied by assigning it to a local variable, then modified, and then copied back. This shortcut does not work: <php>$event['user_cache_data']['karma_score'] = $event['row']['user_karma_score'];</php>
 +
This is because the event variables are overloaded (see [http://area51.phpbb.com/phpBB/viewtopic.php?p=254993#p254993 this discussion on Area51]).
  
 
==Putting it together==
 
==Putting it together==
Example of a subscriber file including 2 listeners
+
As a whole, the <tt>phpbb_ext_phpbb_karma_event_main_listener</tt> class looks like this:
 +
<php>
 +
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 +
 
 +
class phpbb_ext_phpbb_karma_event_main_listener implements EventSubscriberInterface
 +
{
 +
static public function getSubscribedEvents()
 +
{
 +
return array(
 +
'core.viewtopic_cache_user_data' => 'viewtopic_body_add_karma_score_to_user_cache_data',
 +
'core.viewtopic_modify_post_row' => 'viewtopic_body_add_postrow_user_karma_score',
 +
);
 +
}
 +
 
 +
public function viewtopic_body_add_karma_score_to_user_cache_data($event)
 +
{
 +
$user_cache_data = $event['user_cache_data'];
 +
$user_cache_data['karma_score'] = $event['row']['user_karma_score'];
 +
$event['user_cache_data'] = $user_cache_data;
 +
}
 +
 
 +
public function viewtopic_body_add_postrow_user_karma_score($event)
 +
{
 +
global $user;
 +
 
 +
if ($event['row']['user_id'] != ANONYMOUS)
 +
{
 +
// Load the karma language file
 +
$user->add_lang_ext('phpbb/karma', 'karma');
 +
 
 +
$post_row = $event['post_row'];
 +
$post_row['POSTER_KARMA_SCORE'] = $event['user_poster_data']['karma_score'];
 +
$event['post_row'] = $post_row;
 +
}
 +
}
 +
}
 +
</php>
  
 
[[Category:Events and Listeners]]
 
[[Category:Events and Listeners]]

Revision as of 15:02, 12 August 2013

What are listeners?

Listeners are a way of injecting code and manipulating variables in the code where events exist without editing the code. Numerous listeners form part of a subscriber. The listener is a method within your subscriber class in your extension, which is then identified as to which event it corresponds to by an identifying method. This sounds daunting but it a lot simpler in practice. They are part of the listeners system added in 3.1

What are subscribers?

A subscriber is a class which includes a set of listeners as methods, each of which can listen for an event to be triggered. They are 'linked' with the event by an identification method. You can have as many listeners inside a subscriber as you wish. You should only need 1 subscriber per extension however if you have a large number you may choose to split it up into several files.

Creating a subscriber

To create a subscriber, you should create a file like
ext/<vendor>/<extname>/event/<subscribername>_listener.php

Note that the file must be in the 'event/' subdirectory of your extension directory and that it must end in '_listener.php'. It will not work otherwise.

Inside the file, create a class that implements EventSubscriberInterface (you need to import it from Symfony; see the example below). As with all classes in extensions, it should follow the class naming conventions (i.e. phpbb_ext_<vendor>_<extname>_event_<subscribername>_listener). Inside the class, create a static public function getSubscribedEvents() that returns an array, the keys of which contain event names and the values of which contain listener function names. An example:

use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class 
phpbb_ext_phpbb_karma_event_main_listener implements EventSubscriberInterface
{
    static public function 
getSubscribedEvents()
    {
        return array(
            
'core.viewtopic_cache_user_data' => 'viewtopic_body_add_karma_score_to_user_cache_data',
        );
    }
}

Creating a listener

A listener is simply a public function in the subscriber class, referred to in the array returned by getSubscribedEvents(). It takes one argument, $event. This parameter allows you to access and modify the variables that are given to the event in the code. To illustrate this, here is the viewtopic_body_add_karma_score_to_user_cache_data listener method belonging with the example above:

public function viewtopic_body_add_karma_score_to_user_cache_data($event)
{
    
$user_cache_data $event['user_cache_data'];
    
$user_cache_data['karma_score'] = $event['row']['user_karma_score'];
    
$event['user_cache_data'] = $user_cache_data;
}
Note how the user_cache_data event variable is first copied by assigning it to a local variable, then modified, and then copied back. This shortcut does not work:
$event['user_cache_data']['karma_score'] = $event['row']['user_karma_score'];

This is because the event variables are overloaded (see this discussion on Area51).

Putting it together

As a whole, the phpbb_ext_phpbb_karma_event_main_listener class looks like this:

use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class 
phpbb_ext_phpbb_karma_event_main_listener implements EventSubscriberInterface
{
    static public function 
getSubscribedEvents()
    {
        return array(
            
'core.viewtopic_cache_user_data'    => 'viewtopic_body_add_karma_score_to_user_cache_data',
            
'core.viewtopic_modify_post_row'    => 'viewtopic_body_add_postrow_user_karma_score',
        );
    }

    public function 
viewtopic_body_add_karma_score_to_user_cache_data($event)
    {
        
$user_cache_data $event['user_cache_data'];
        
$user_cache_data['karma_score'] = $event['row']['user_karma_score'];
        
$event['user_cache_data'] = $user_cache_data;
    }

    public function 
viewtopic_body_add_postrow_user_karma_score($event)
    {
        global 
$user;

        if (
$event['row']['user_id'] != ANONYMOUS)
        {
            
// Load the karma language file
            
$user->add_lang_ext('phpbb/karma''karma');

            
$post_row $event['post_row'];
            
$post_row['POSTER_KARMA_SCORE'] = $event['user_poster_data']['karma_score'];
            
$event['post_row'] = $post_row;
        }
    }
}