phpBB

Development Wiki

Difference between revisions of "Add Listeners"

From phpBB Development Wiki

Line 6: Line 6:
  
 
==Creating a subscriber==
 
==Creating a subscriber==
To create a subscriber, you should create a file like <pre>ext/&lt;vendor&gt;/&lt;extname&gt;/event/<subscribername>_listener.php</pre>
+
To create a subscriber, you should create a file like <pre>ext/&lt;vendor&gt;/&lt;extname&gt;/event/<subscribername>.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.
+
Note that the file must be in the 'event/' subdirectory of your extension directory or it will not work. Also, do not place any .php files in this subdirectory that aren't subscribers.
  
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:
+
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>). 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>
 
<php>
 
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  
class phpbb_ext_phpbb_karma_event_main_listener implements EventSubscriberInterface
+
class phpbb_ext_phpbb_karma_event_subscriber implements EventSubscriberInterface
 
{
 
{
 
static public function getSubscribedEvents()
 
static public function getSubscribedEvents()
Line 39: Line 39:
  
 
==Putting it together==
 
==Putting it together==
As a whole, the <tt>phpbb_ext_phpbb_karma_event_main_listener</tt> class looks like this:
+
As a whole, the <tt>phpbb_ext_phpbb_karma_event_subscriber</tt> class looks like this:
 
<php>
 
<php>
 
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  
class phpbb_ext_phpbb_karma_event_main_listener implements EventSubscriberInterface
+
class phpbb_ext_phpbb_karma_event_subscriber implements EventSubscriberInterface
 
{
 
{
 
static public function getSubscribedEvents()
 
static public function getSubscribedEvents()

Revision as of 12:42, 19 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>.php

Note that the file must be in the 'event/' subdirectory of your extension directory or it will not work. Also, do not place any .php files in this subdirectory that aren't subscribers.

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>). 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_subscriber 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_subscriber class looks like this:

use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class 
phpbb_ext_phpbb_karma_event_subscriber 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;
        }
    }
}