phpBB

Development Wiki

Difference between revisions of "Add Listeners"

From phpBB Development Wiki

(Add service definition)
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>.php</pre>
+
To create a subscriber, you should create a file like <pre>ext/&lt;vendor&gt;/&lt;extname&gt;/event/listener.php</pre>
 
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.
 
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.
  
Line 12: Line 12:
  
 
<php>
 
<php>
 +
 +
namespace vendor\extname\event;
 +
 
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  
class phpbb_ext_phpbb_karma_event_subscriber implements EventSubscriberInterface
+
class listener implements EventSubscriberInterface
 
{
 
{
 
static public function getSubscribedEvents()
 
static public function getSubscribedEvents()
Line 24: Line 27:
 
}
 
}
 
</php>
 
</php>
 +
 +
To autoloaded the subscriber file you should create a service definition with the <code>event.listener</code> tag.
 +
To create a service definition, create the file <pre>ext/&lt;vendor&gt;/&lt;extname&gt;/config/services.yml</pre> and add the following code:
 +
<pre>services:
 +
    vendor.extname.listener:
 +
        class: vendor\extname\event\listener
 +
        tags:
 +
            - { name: event.listener }
 +
</pre>
  
 
==Creating a listener==
 
==Creating a listener==

Revision as of 20:34, 29 April 2015

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/listener.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:

namespace vendor\extname\event;

use 
Symfony\Component\EventDispatcher\EventSubscriberInterface;

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

To autoloaded the subscriber file you should create a service definition with the event.listener tag.

To create a service definition, create the file
ext/<vendor>/<extname>/config/services.yml
and add the following code:
services:
    vendor.extname.listener:
        class: vendor\extname\event\listener
        tags:
            - { name: event.listener }

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