phpBB

Development Wiki

Difference between revisions of "Add Listeners"

From phpBB Development Wiki

m (Update the file header so it maches the example with service definition)
(moved to new docs)
 
Line 1: Line 1:
==What are listeners?==
+
This documentation has been moved to the new phpBB Development Documentation.
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?==
+
[https://area51.phpbb.com/docs/dev/31x/extensions/tutorial_events.html#php-core-events-listeners Extensions: PHP Core Events & Listeners].
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 <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.
+
 
+
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>
+
 
+
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',
+
);
+
}
+
}
+
</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==
+
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==
+
As a whole, the <tt>listener</tt> class looks like this:
+
<php>
+
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',
+
'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]]
+

Latest revision as of 18:44, 5 December 2016

This documentation has been moved to the new phpBB Development Documentation.

Extensions: PHP Core Events & Listeners.