graffiti

Drupal 11 – Implementation des hooks

Dans Drupal 11, une syntaxe orientée objet (OO) a été introduite pour les hooks, permettant de les implémenter sous forme de méthodes dans des classes PHP. Cette approche remplace progressivement l’utilisation traditionnelle des fonctions globales, améliorant ainsi la lisibilité et l’organisation du code.

Nouveautés des Hooks en OO dans Drupal 11

  • Les hooks peuvent désormais être définis dans des classes marquées par des attributs PHP (comme #[Hook]).
  • Les classes doivent être déclarées comme des services dans le conteneur de services de Drupal.
  • Chaque méthode représentant un hook est associée à son événement spécifique.

Exemple de Hook OO dans Drupal 11

Prenons un exemple avec le hook hook_help (traditionnellement utilisé pour fournir des pages d’aide).

1. Création de la classe pour le hook

Voici un exemple d’implémentation OO pour le hook hook_help :

<?php

namespace Drupal\example\Hook;

use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Symfony\Component\DependencyInjection\Attribute\AsService;

/**
 * Exemple d'implémentation OO du hook_help.
 */
#[AsService]
class ExampleHelpHook {
  use StringTranslationTrait;

  /**
   * Implémentation du hook_help().
   */
  #[Hook('help')]
  public function provideHelp(string $route_name, RouteMatchInterface $route_match): array {
    if ($route_name === 'help.page') {
      return [
        '#markup' => $this->t('Ceci est une page d\'aide pour le module Example.'),
      ];
    }

    return [];
  }
}

2. Déclaration dans le conteneur de services

Les classes utilisant la nouvelle syntaxe orientée objet doivent être déclarées comme des services dans le conteneur de services de Drupal. Cela peut être fait automatiquement avec l’attribut #[AsService] ou manuellement dans un fichier YAML.

Déclaration automatique (grâce à #[AsService]) :

Si vous utilisez l’attribut #[AsService], aucune configuration supplémentaire n’est requise dans example.services.yml.

Déclaration manuelle :

Si vous préférez déclarer manuellement, ajoutez cette configuration dans le fichier example.services.yml :

services:
  Drupal\example\Hook\ExampleHelpHook:
    tags:
      - { name: hook }

Structure générale des Hooks en OO

Classe du Hook

  • La classe représente un ensemble de hooks.
  • Elle doit être enregistrée comme service et marquée avec un attribut ou un tag hook.

Méthodes des Hooks

  • Chaque méthode représente un hook spécifique.
  • Elle est annotée avec l’attribut #[Hook('<nom_du_hook>')].

Exemple avec plusieurs hooks

Voici une classe contenant plusieurs hooks dans le module example :

<?php

namespace Drupal\example\Hook;

use Drupal\Core\Extension\ModuleHandlerInterface;
use Symfony\Component\DependencyInjection\Attribute\AsService;

/**
 * Exemple de classe implémentant plusieurs hooks.
 */
#[AsService]
class ExampleHooks {

  /**
   * Implémentation du hook_cron().
   */
  #[Hook('cron')]
  public function onCron() {
    // Logique pour le hook_cron.
    \Drupal::logger('example')->info('Le hook_cron a été exécuté.');
  }

  /**
   * Implémentation du hook_entity_insert().
   */
  #[Hook('entity_insert')]
  public function onEntityInsert($entity) {
    // Logique pour le hook_entity_insert.
    if ($entity->getEntityTypeId() === 'node') {
      \Drupal::logger('example')->info('Un nouveau nœud a été créé.');
    }
  }
}

Avantages de la syntaxe OO pour les Hooks

  1. Modularité : Les hooks sont regroupés dans des classes spécifiques, ce qui améliore la gestion du code.
  2. Interopérabilité : Les classes de hooks peuvent injecter des services via le conteneur de services.
  3. Lisibilité : Le code est plus lisible et respecte les conventions modernes d’écriture orientée objet.

Transition depuis la syntaxe traditionnelle

Si vous migrez des hooks traditionnels vers cette nouvelle syntaxe, suivez ces étapes :

  1. Identifiez tous les hooks existants dans votre module.
  2. Regroupez-les dans des classes logiques basées sur leur fonctionnalité.
  3. Remplacez les fonctions globales par des méthodes annotées dans ces classes.
  4. Enregistrez les classes dans le conteneur de services si nécessaire.

Avec ces étapes, vous pouvez tirer pleinement parti des améliorations OO dans Drupal 11 pour une gestion plus propre et moderne des hooks !