logo

Extra Block Types (EBT) - Neue Erfahrung im Layout Builder❗

Extra Block Types (EBT) - gestylte, anpassbare Blocktypen: Diashows, Registerkarten, Karten, Akkordeons und viele andere. Eingebaute Einstellungen für Hintergrund, DOM Box, Javascript Plugins. Erleben Sie die Zukunft der Layouterstellung schon heute.

Demo EBT-Module EBT-Module herunterladen

❗Extra Absatztypen (EPT) - Erfahrung mit neuen Absätzen

Extra Paragraph Types (EPT) - analoger, auf Absätzen basierender Satz von Modulen.

Demo EPT-Module EPT-Module herunterladen

Scroll

9.12. Event Dispatcher, benutzerdefinierter Code für bestimmte Ereignisse

27/05/2025, by Ivan

Das Event-System ermöglicht es Ihnen, komplexere Systeme zu erstellen, bei denen die Funktionalität durch benutzerdefinierten Code für bestimmte Ereignisse geändert werden kann. Viele Hooks aus Drupal 7 wurden durch Events ersetzt. Dies ermöglichte eine Vereinheitlichung der Arbeit vieler Teile von Drupal und zusätzlicher Kopiermodule. Das Event-System selbst stammt von Symfony und besteht aus folgenden Teilen:

Event Subscribers – „Abonnenten“ für bestimmte Events sind Funktionen oder Methoden, die bei bestimmten Ereignissen ausgelöst werden. Im Code ist es eine Klasse, die die Schnittstelle implementiert:

\Symfony\Component\EventDispatcher\EventSubscriberInterface

Event Registry – Sammelt und sortiert Event Subscribers entsprechend der Reihenfolge ihrer Auslösung. Das Registry für Subscriber wird als Array mit Schlüssel-Wert-Paaren aus Eventnamen und Priorität im Event Dispatcher Objekt gespeichert. Wenn ein Event als Service registriert ist, ist es als global verfügbarer Dispatcher registriert.

Event Dispatcher – Der Mechanismus, bei dem das Event ausgelöst wird und der es ermöglicht, Event Subscribers zum richtigen Zeitpunkt aufzurufen. Meistens wird mindestens eine Instanz des Event Dispatchers als Service bereitgestellt. Die Event Dispatcher Klasse implementiert:

\Symfony\Component\EventDispatcher\EventDispatcherInterface

Event Context – Viele Events benötigen einen spezifischen Datensatz, der für den Event Subscriber wichtig sein kann. Dies kann ein einfacher Wert sein, der an den Subscriber übergeben wird, oder eine Klasse, die die nötigen Daten enthält. Die Event Context Klasse erweitert die Klasse:

\Symfony\Component\EventDispatcher\Event

Schauen wir uns Beispiele zur Arbeit mit Events an, um zu verstehen, wie das funktioniert.

Ich habe den gesamten Code auf GitHub im Modul drupalbook_examples hinzugefügt, Sie können das Modul herunterladen und auf Ihrer Webseite hinzufügen:

https://github.com/levmyshkin/drupalbook8

Drupal 8 hat den hook_init() nicht mehr:

https://www.drupal.org/node/2013014

Jetzt können Sie den notwendigen Code beim Laden der Seite mit einem Event Subscriber ausführen:

Datei: modules/custom/drupalbook_examples/drupalbook_examples.services.yml

services:
  drupalbook_examples.event_subscriber:
    class: Drupal\drupalbook_examples\EventSubscriber\DrupalbookExamplesSubscriber
    tags:
    - {name: event_subscriber}

Um einen Event Subscriber zu verbinden, müssen Sie den Service in der Moduldatei *.services.yml hinzufügen. Hier beschreiben wir, welche Klasse der Event Subscriber sein wird und schreiben den Namen event_subscriber in die Tags. Nun müssen wir die Event Subscriber-Klasse erstellen:

Datei: modules/custom/drupalbook_examples/src/EventSubscriber/DrupalbookExamplesSubscriber.php

<?php
 
namespace Drupal\drupalbook_examples\EventSubscriber;
 
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 
class DrupalbookExamplesSubscriber implements EventSubscriberInterface {
 
  public function checkForRedirection(GetResponseEvent $event) {
    if ($event->getRequest()->query->get('redirect-me')) {
      $event->setResponse(new RedirectResponse(\Drupal::url('<front>', [], ['absolute' => TRUE])));
    }
  }
 
  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    $events[KernelEvents::REQUEST][] = array('checkForRedirection');
    return $events;
  }
 
}

Sehen wir uns die wichtigsten Punkte dieses Codes an. Die Klasse unseres Event Subscribers implementiert die Schnittstelle EventSubscriberInterface, die Hauptmethode dieser Schnittstelle ist getSubscribedEvents(), die bestimmt, auf welche Events unser Subscriber reagiert und welche Methoden aufgerufen werden, falls das Event eintritt. In unserem Fall wird ein Event ganz am Anfang der Drupal-Arbeit nach der Verarbeitung der Anfrage ausgelöst. Hier rufen wir die Methode checkForRedirection() auf, wenn das Event eintritt. In der Methode selbst wird bei Vorhandensein des Parameters redirect-me eine Weiterleitung zur Startseite (example.com) ausgelöst.

Dieser Code wird immer ausgeführt, wenn Sie eine Seite laden, oder fast immer. Der Grund ist, wenn Ihre Seite zwischengespeichert (cached) ist, wird sie möglicherweise direkt aus dem Cache geliefert und Drupal führt nicht alle Codeabschnitte aus, der Cache arbeitet sofort.

In diesem Fall können Sie den Hook hook_boot() analog verwenden, der wie hook_init() aus Drupal 8 entfernt wurde:

https://www.drupal.org/node/1909596

Fügen wir eine weitere Methode redirectBeforeWithoutCache() hinzu

Datei: modules/custom/drupalbook_examples/src/EventSubscriber/DrupalbookExamplesSubscriber.php:

<?php
 
namespace Drupal\drupalbook_examples\EventSubscriber;
 
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 
class DrupalbookExamplesSubscriber implements EventSubscriberInterface {
 
  public function checkForRedirection(GetResponseEvent $event) {
    if ($event->getRequest()->query->get('redirect-me')) {
      $event->setResponse(new RedirectResponse(\Drupal::url('<front>', [], ['absolute' => TRUE])));
    }
  }
 
  public function redirectBeforeWithoutCache(GetResponseEvent $event) {
    if ($event->getRequest()->query->get('redirect-me')) {
      $event->setResponse(new RedirectResponse(\Drupal::url('<front>', [], ['absolute' => TRUE])));
    }
  }
 
  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    $events[KernelEvents::REQUEST][] = array('checkForRedirection');
    $events[KernelEvents::REQUEST][] = array('redirectBeforeWithoutCache', 300);
    return $events;
  }
 
}

In der Methode getSubscribedEvents() haben wir die Reaktion auf dasselbe KernelEvents::REQUEST Event registriert, nur setzen wir diesmal die Priorität auf 300, was erlaubt, dass diese Methode früher ausgeführt wird als Methoden mit niedrigerer Priorität, die für dasselbe Event ausgelöst werden. Nun funktioniert die Weiterleitung auch für eine gecachte Seite.

In Drupal gibt es viele Events, die zu einem Subscriber hinzugefügt werden können. Weitere Beispiele finden Sie in der offiziellen Dokumentation:

https://www.drupal.org/docs/8/creating-custom-modules/event-systems-overview-how-to-subscribe-to-and-dispatch-events