Listen to events¶
You can listen to any event in CiviCRM with the Symfony Event Listener or Symfony Event Subscriber method.
There are multiple ways on how you can listen to a certain event. A convenient way is to implement an autoregistered service your extension.
Which events are available
Not all events are documented (yet) and extensions can implement their own events as well. But to give you an idea of the events in Core CiviCRM, see All Events
For a general introduction or background on EventDispatcher, consult the Symfony documentation.
Use an autoregisterd service (convenient method)¶
One way to listen to events is to implement a autoregistered service in your extension.
In the autoregistered service you implement the Symfony EventSubscriberInterface
to subscribe to one or more events.
Below is an example to listen to the civi.token.list event.
namespace Civi\MyExtension;
use Civi\Core\Service\AutoSubscriber;
use Civi\Token\Event\TokenRegisterEvent;
class TokensInMyExtension extends AutoSubscriber {
public static function getSubscribedEvents() {
return [
'civi.token.list' => 'onRegisterTokens'
];
}
public function onRegisterTokens(TokenRegisterEvent $e) {
$e->entity('profile')
->register('viewUrl', ts('Profile View URL'))
->register('viewLink', ts('Profile View Link'));
}
}
The class extends the Civi\Core\Service\AutoSubscriber. This will tell CiviCRM there are event listeners in this class.
There is more to a service container class then only this. You can read more about it in the Service Container Chapter
The method getSubscribedEvents is required. And returns a list of events to listen to and the name of the class method of the listener function.
The getSubscribedEvents method can also return a priority. An higher number gets executed first. The priority is default 0 and can be negative. To run our event listener quite early we give it a high priority by returning the following return ['civi.token.list' => ['onRegisterTokens', 9999]];
Enable
If you are developing an extension with auto-registered services, then you must enable the scan-classes mixin. This can be done with civix:
civix mixin --enable='scan-classes@1.0.0'
Listen to an event as a function in myextension.php¶
Each extension in CiviCRM comes with a myextension.php file. In this file you can add a function myextension_civicrm_config (if it is not present). In this function you tell the Symfony Event Dispatcher to which event you want to listen to and which function is the listener function.
// myextension.php
function myextension_civicrm_config(&$config) {
// ...
// existing code in this function above
// This hook sometimes runs twice
if (isset(\Civi::$statics[__FUNCTION__])) {
return;
}
\Civi::$statics[__FUNCTION__] = 1;
// Declare your listener
\Civi::dispatcher()->addListener('civi.token.list', 'myextension_register_tokens', 0);
}
function myextension_register_tokens(Civi\Token\Event\TokenRegisterEvent $e) {
$e->entity('profile')
->register('viewUrl', ts('Profile View URL'))
->register('viewLink', ts('Profile View Link'));
}
The function myextension_civicrm_config could be called more than once. And we only want to add our listener to be called once.
So we had some magic \Civi::$statics[__FUNCTION__]) to make sure the function we only add the listener once.
With \Civi::dispatcher()->addListener we add a listener to the Symfony Event Dispatcher. The first parameter is the event we listen to. The second parameter is the function name. And there is an optional third parameter for the priority.