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
27/05/2025, by Ivan

In früheren Artikeln sind wir bereits auf Hooks gestoßen. In diesem Artikel werfen wir einen genaueren Blick auf Hooks, die Ihnen bei der Arbeit mit Entitäten helfen.

In diesem Artikel können Sie allgemein lesen, was Hooks sind und warum sie benötigt werden:

http://drupalbook.org/drupal/92-what-hook-drupal-8

Wir verwenden Hooks, um unseren eigenen Code hinzuzufügen, der bei bestimmten Ereignissen im Zusammenhang mit Entitäten ausgelöst wird: hinzufügen, löschen, aktualisieren.

Alle Drupal-Hooks können Sie auf dieser Seite einsehen:

https://api.drupal.org/api/drupal/core!core.api.php/group/hooks/8.2.x

Wir werden nur einen Teil davon behandeln, die am häufigsten in benutzerdefinierten Modulen zur Arbeit mit Inhalten vorkommen.

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

https://github.com/levmyshkin/drupalbook8

hook_entity_presave()

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21entity.api.php/function/hook_entity_presave/8.6.x

/**
 * Implementiert hook_entity_presave().
 */
function drupalbook_examples_entity_presave(Drupal\Core\Entity\EntityInterface $entity) {
  if ($entity->getEntityTypeId() == 'node' && $entity->getType() == 'article') {
    $entity->title->value = $entity->title->value . ' by ' . date('d-m-Y');
  }
}

Hook_entity_presave() wird jedes Mal ausgelöst, wenn eine Entität gespeichert wird.

Sie müssen $entity->save() innerhalb des Hooks nicht aufrufen, da das Entitätsobjekt vor dem Speichern verändert wird. In diesem Beispiel fügen wir dem Titel des Artikels das aktuelle Datum hinzu, an dem der Node gespeichert wurde. Wenn wir den Artikel am nächsten Tag aktualisieren, wird das neue Datum erneut hinzugefügt. Wenn Sie das Datum nicht vor dem Speichern aus dem Titel löschen, wird der Titel nach erneutem Speichern immer länger und enthält immer mehr Daten. Meistens prüfen wir beim Speichern, ob bestimmte Werte für Felder in der Entität vorhanden sind, oder Sie können eine E-Mail mit einer Benachrichtigung über die Änderung im Artikel senden.

Beachten Sie, dass wir zuerst den gewünschten Entitätstyp prüfen, da der Code in hook_entity_presave() für alle Entitäten funktioniert: Inhalte, Blöcke, Kommentare, Taxonomie-Begriffe. Außerdem prüfen wir das benötigte Bundle der Nodes.

hook_entity_insert()

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21entity.api.php/function/hook_entity_insert/8.6.x

/**
 * Implementiert hook_entity_insert().
 */
function drupalbook_examples_entity_insert(Drupal\Core\Entity\EntityInterface $entity) {
  if ($entity->getEntityTypeId() == 'node' && $entity->getType() == 'page') {
    $node = Node::create([
      'type'        => 'article',
      'title'       => 'Neue Seite erstellt: ' . $entity->title->value,
    ]);
    $node->save();
  }
}

Hook_entity_insert() wird aufgerufen, wenn eine neue Entität hinzugefügt wird. Zum Beispiel wird beim Erstellen einer neuen Seite auf einer Website ein Artikel erstellt. Und wenn Sie den vorherigen Hook haben, wird das Datum dem Titel des erstellten Artikels hinzugefügt.

Es ist anzumerken, dass es einen Unterschied zwischen den Hooks hook_entity_insert() und hook_entity_presave() gibt. Hook_entity_insert() wird nur einmal ausgelöst, wenn eine Entität hinzugefügt wird, und ändert die Werte der Entitätsfelder nicht. Wenn Sie also den Code aus dem ersten Hook in den zweiten einfügen, funktioniert dieser Code auch nicht:

/**
 * Implementiert hook_entity_insert().
 */
function drupalbook_examples_entity_insert(Drupal\Core\Entity\EntityInterface $entity) {
  if ($entity->getEntityTypeId() == 'node' && $entity->getType() == 'article') {
    $entity->title->value = $entity->title->value . ' by ' . date('d-m-Y');
  }
}

Natürlich können Sie das Speichern des Wertes des Nodes erreichen:

function your_module_entity_insert(Drupal\Core\Entity\EntityInterface $entity){
  if ($entity->getType() == 'article') {
    drupal_register_shutdown_function('_your_module_post_insert', $entity);
  }
}
 
function _your_module_entity_insert(Drupal\Core\Entity\EntityInterface $entity) {
  if ($entity) {
      $entity->save();
  }
}

Aber das ist nicht ratsam, es ist am besten, hook_entity_presave() zu verwenden, um die Entität selbst beim Speichern zu ändern, und hook_entity_insert(), um andere Entitäten oder Aktionen zu ändern.

hook_entity_update()

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21entity.api.php/function/hook_entity_update/8.2.x

/**
 * Implementiert hook_entity_update().
 */
function drupalbook_examples_entity_update(Drupal\Core\Entity\EntityInterface $entity) {
  if ($entity->getEntityTypeId() == 'node' && $entity->getType() == 'page') {
    \Drupal::messenger()->addMessage('Seite wurde geändert: ' . $entity->title->value);
  }
}

Hook_entity_update() wird jedes Mal ausgelöst, wenn eine Entität aktualisiert wird. Hier ist es gleich zu erwähnen, dass es nicht ratsam ist, die Felder des $entity-Objekts zu aktualisieren. Dieser Hook, wie auch hook_entity_insert(), dient dazu, bestimmte Aktionen auszuführen, die nichts mit den Daten der Felder der aktualisierten Entität zu tun haben. Dieser Hook sollte erneut für Logging, das Senden von Nachrichten oder andere Aktionen verwendet werden.

Auch sollte $entity->save() nicht ausgeführt werden, um zu vermeiden, dass hook_entity_update() erneut aufgerufen wird. Wenn Sie es doch tun, sollten Sie sicherstellen, dass Sie $entity->save() nicht erneut aufrufen und keine Schleife entsteht.

hook_entity_delete()

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21entity.api.php/function/hook_entity_delete/8.6.x

Ein weiterer Hook für das Logging und Ausführen von Aktionen nach dem Löschen von Entitäten.

hook_entity_access()

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21entity.api.php/function/hook_entity_access/8.2.x

<?php

use Drupal\Core\Access\AccessResult;
 
...
 
/**
 * Implementiert hook_entity_access().
 */
function drupalbook_examples_entity_access(\Drupal\Core\Entity\EntityInterface $entity, $operation, \Drupal\Core\Session\AccountInterface $account) {
  if ($entity->getEntityTypeId() == 'node' && $entity->getType() == 'article' && $operation == 'view' && in_array('administrator', $account->getRoles())) {
    AccessResult::forbidden();
  }
}

?>

In diesem Beispiel blockieren wir den Zugriff auf Artikel für alle Benutzer, die nicht die Rolle Administrator haben. Natürlich, wenn die standardmäßigen Rollenzugriffsberechtigungen ausreichen, um den Zugang zu Inhalten zu differenzieren, ist es besser, die Berechtigungseinstellungen zu verwenden. Hook_entity_access() wird benötigt, um den Zugriff auf Inhalte flexibel zu konfigurieren, zum Beispiel nach einem Zeitplan, beim Erfüllen bestimmter Bedingungen durch Userpoint, Karma, Benutzerlevel usw. Außerdem, wenn Sie eine übliche Zugriffsrestriktion auf bestimmte Inhalte über diesen Hook implementieren, indem Sie die Standardzugriffsrechte überschreiben, kann das zu Verwirrung bei anderen Programmierern führen, die das Projekt fortführen. Daraus ergibt sich der Hauptnachteil von Hooks: die Nicht-Offensichtlichkeit der Ausführung von Drittanbieter-Code. Wenn wir annehmen, dass wir nichts von der Existenz eines Moduls mit implementierten Hooks wissen, wird es für uns ein Rätsel sein, warum sich der Titel unseres Artikels beim Speichern ändert. Natürlich wissen wir, dass es Hooks gibt, und daher muss man bei einem solchen Verhalten, z.B. beim Aktualisieren eines Nodes, das ganze entity_presave- oder entity_update-Projekt durchsuchen. Oft halten sich Programmierer an den Codeguide und hinterlassen Kommentare zu den Hooks wie "Implements hook_entity_presave()", so dass man nach dem Namen des Hooks suchen kann, aber bedenken Sie, dass nicht alle Programmierer den Codeguide befolgen, besonders wenn Sie ein Projekt von einem vorherigen Team übernommen haben, das das Projekt nicht erfolgreich abgeschlossen hat.

Wir haben nur wenige Hooks betrachtet, aber ich denke, Sie sollten eine gewisse Vorstellung davon haben, wo man Hooks verwenden kann. Je mehr Drupal-Aufgaben Sie erledigen, desto öfter werden Sie auf die Notwendigkeit stoßen, eigenen Code zu schreiben. Wenn einer der Hooks wie ein guter Ort aussieht, um Code hinzuzufügen, können Sie ihn bedenkenlos in Ihrem benutzerdefinierten Modul implementieren.