Events

Last updated on
14 December 2022

In Drupal 7, events are defined in hook_rules_event_info() and are dispatched using rules_invoke_event(). If you are already familiar with Rules events in Drupal 7, then Porting Events will show you how D7 Rules events correspond to D8 Rules events. The remainder of this page does not assume prior knowledge of Rules in Drupal 7.

In Drupal 8, events are no longer defined through a hook. Instead, they are defined in a class and declared in a YML file, then dispatched using a function call on the core Drupal event_dispatcher service.

Rules uses the Symfony event dispatching system in Drupal 8 to trigger events and invoke reaction rules when an event occurs. A module that wants to provide events can do so without declaring a module dependency on Rules - dispatching standard Symfony events in code is enough.

Rules understands core Drupal events as well as all entity-related events (entity deleted, entity saved, etc.). But in order to make other module-specific events known to Rules a <modulename>.rules.events.yml file has to be provided to declare the event(s) as Rules events. An example from Rules itself:

rules_user_login:
  label: 'User has logged in'
  category: 'User'
  context_definitions:
    account:
      type: 'entity:user'
      label: 'Logged in user'

This entry registers an event called "rules_user_login" which has one context variable called "account" which is a User entity.

Next, an event class which extends \Drupal\Component\EventDispatcher\Event should be declared (you can instead simply use an instance of Symfony's \Symfony\Component\EventDispatcher\GenericEvent directly, but an explicit class is encouraged):

namespace Drupal\rules\Event;

use Drupal\Component\EventDispatcher\Event;
use Drupal\user\UserInterface;

/**
 * Event that is fired when a user logs in.
 *
 * @see rules_user_login()
 */
class UserLoginEvent extends Event {

  const EVENT_NAME = 'rules_user_login';

  /**
   * The user account.
   *
   * @var \Drupal\user\UserInterface
   */
  protected $account;

  /**
   * Constructs the object.
   *
   * @param \Drupal\user\UserInterface $account
   *   The account of the user logged in.
   */
  public function __construct(UserInterface $account) {
    $this->account = $account;
  }

}

The values for the specified context parameters have to be available as properties with the same names and data types as the context parameters specified in <modulename>.rules.events.yml file for this event. The EVENT_NAME constant, although not strictly required, is a convenient place to store the event name, which should match the name defined in <modulename>.rules.events.yml file. You may of course add any methods you wish to your event class - this example just shows the minimum required for Rules.

Invoking or dispatching the event looks like this:

$event = new UserLoginEvent($account);
\Drupal::service('event_dispatcher')->dispatch($event, $event::EVENT_NAME);

An instance of the UserLoginEvent class is created, passing along the $account user object as context parameter. The core Drupal event dispatching service is used to notify all event subscribers that this event has occurred. Rules itself is among those subscribers - its GenericEventSubscriber class will trigger all reaction rules that are configured for this event.

Note: If you are dispatching events from a controller or some other class, then you should inject the event_dispatcher service rather than using the static \Drupal::service() call.

Help improve this page

Page status: No known problems

You can: