logo

Types de blocs supplémentaires (EBT) – Nouvelle expérience de Layout Builder❗

Types de blocs supplémentaires (EBT) – types de blocs stylisés et personnalisables : diaporamas, onglets, cartes, accordéons et bien d’autres. Paramètres intégrés pour l’arrière-plan, la boîte DOM, les plugins JavaScript. Découvrez dès aujourd’hui le futur de la création de mises en page.

Démo des modules EBT Télécharger les modules EBT

❗Types de paragraphes supplémentaires (EPT) – Nouvelle expérience Paragraphes

Types de paragraphes supplémentaires (EPT) – ensemble de modules basé sur les paragraphes analogiques.

Démo des modules EPT Télécharger les modules EPT

Défilement

Restreindre l’accès au vocabulaire des termes de taxonomie en utilisant un Event Subscriber

21/06/2025, by Ivan

Menu

Parfois, vous avez besoin de Catégories fixes et permanentes sur le site, qui ne doivent être mises à jour qu'accidentellement. Dans ce cas, vous pouvez utiliser un code personnalisé avec un Event Subscriber.

Ajoutons une nouvelle classe Event Subscriber dans un module personnalisé.

drupalbook_custom.services.yml

services:  
  drupalbook_custom.tag_redirect_subscriber:
    class: Drupal\drupalbook_custom\EventSubscriber\TagRedirectSubscriber
    arguments:
      - '@entity_type.manager'
      - '@current_user'
    tags:
      - { name: event_subscriber }

Et incluez notre Event Subscriber dans drupalbook_custom/src/EventSubscriber/TagRedirectSubscriber :

<?php

namespace Drupal\drupalbook_custom\EventSubscriber;

use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Routing\TrustedRedirectResponse;
use Drupal\Core\Session\AccountProxyInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;

/**
 * Redirige les non-administrateurs des pages d’administration du vocabulaire Tag.
 *
 * Un subscriber au niveau de la requête s’exécute tôt, nous permettant d’interrompre
 * la requête et de renvoyer une réponse de redirection avant l’exécution du contrôleur associé.
 */
class TagRedirectSubscriber implements EventSubscriberInterface {

  /**
   * Le service gestionnaire de types d’entités.
   *
   * Conservé comme exemple de dépendance ; pas strictement nécessaire pour la
   * logique actuelle mais utile si des améliorations futures requièrent le chargement d’entités.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected EntityTypeManagerInterface $entityTypeManager;

  /**
   * Le service proxy de l’utilisateur courant.
   *
   * Utilisé pour vérifier rapidement les rôles afin d’éviter la redirection pour
   * les administrateurs.
   *
   * @var \Drupal\Core\Session\AccountProxyInterface
   */
  protected AccountProxyInterface $currentUser;

  /**
   * Constructeur du subscriber.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   Le gestionnaire de type d’entité.
   * @param \Drupal\Core\Session\AccountProxyInterface $current_user
   *   L’utilisateur effectuant actuellement la requête.
   */
  public function __construct(
    EntityTypeManagerInterface $entity_type_manager,
    AccountProxyInterface $current_user,
  ) {
    $this->entityTypeManager = $entity_type_manager;
    $this->currentUser = $current_user;
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents(): array {
    // La priorité 32 garantit que les paramètres de route sont disponibles,
    // mais que le contrôleur n’a pas encore été exécuté.
    return [
      KernelEvents::REQUEST => ['onKernelRequest', 32],
    ];
  }

  /**
   * Effectue la redirection lorsqu’un non-administrateur accède aux routes d’administration des tags.
   *
   * @param \Symfony\Component\HttpKernel\Event\RequestEvent $event
   *   L’événement kernel portant la requête.
   */
  public function onKernelRequest(RequestEvent $event): void {
    // Agir uniquement sur la requête principale.
    if (!$event->isMainRequest()) {
      return;
    }

    // Laisser passer les administrateurs sans redirection.
    if ($this->currentUser->hasRole('administrator')) {
      return;
    }

    $request = $event->getRequest();
    $route_name = $request->attributes->get('_route');

    // Destination pour toutes les tentatives bloquées.
    $redirect_to = 'https://drupalbook.org/admin/structure'
      . '/taxonomy/manage/tag/overview';

    switch ($route_name) {
      case 'entity.taxonomy_vocabulary.overview_form':
      case 'entity.taxonomy_vocabulary.overview_terms':
      case 'entity.taxonomy_term.add_form':
        // Vérifie que nous sommes sur le vocabulaire "tag".
        $vocabulary = $request->attributes->get('taxonomy_vocabulary');
        if (!empty($vocabulary) && $vocabulary->id() === 'tag') {
          $event->setResponse(new TrustedRedirectResponse($redirect_to));
        }
        return;

      case 'entity.taxonomy_term.edit_form':
      case 'entity.taxonomy_term.delete_form':
        /** @var \Drupal\taxonomy\Entity\Term|null $term */
        $term = $request->attributes->get('taxonomy_term');
        // bundle() retourne le nom machine du vocabulaire.
        if ($term && $term->bundle() === 'tag') {
          $event->setResponse(new TrustedRedirectResponse($redirect_to));
        }
        return;

      default:
        return;
    }
  }

}

La classe TagRedirectSubscriber est un Event Subscriber personnalisé pour Drupal, conçu pour restreindre l’accès aux pages d’administration d’un vocabulaire de taxonomie spécifique (ici, « tag ») aux non-administrateurs. Voici une explication de sa structure et des points clés :

1. Objectif et cas d’utilisation

  • But : Empêcher les mises à jour accidentelles ou non autorisées du vocabulaire « tag » en redirigeant les utilisateurs non-admin hors de ses routes d’administration.
  • Avantage : Offre une couche de contrôle d’accès basée sur l’interface pour des vocabulaires de taxonomie critiques, garantissant la stabilité de catégories fixes.

2. Structure de la classe et dépendances

  • La classe implémente EventSubscriberInterface, la rendant compatible avec le système d’événements Symfony utilisé par Drupal.
  • Dépendances injectées via le constructeur :
    • EntityTypeManagerInterface : inclus pour des opérations potentielles sur les entités. Non requis pour la logique actuelle mais facilite l’extensibilité future.
    • AccountProxyInterface : utilisé pour récupérer et vérifier efficacement les rôles de l’utilisateur courant.
    L’injection de dépendances garantit que le subscriber est testable, réutilisable, et conforme aux bonnes pratiques du conteneur de services Drupal.

3. Événements souscrits

  • La classe souscrit à l’événement KernelEvents::REQUEST avec une priorité de 32.
    Cette priorité garantit :
    • Les paramètres de la route sont disponibles (le routage est résolu).
    • Le contrôleur de la route n’a PAS encore été exécuté, permettant au subscriber d’intercepter et d’interrompre la requête avec une redirection si nécessaire.

4. Logique de redirection

  • La méthode onKernelRequest() réalise tous les contrôles d’accès et la logique de redirection :
    • Agit uniquement sur les requêtes principales : évite la gestion multiple lors des sous-requêtes.
    • Laisse passer les administrateurs : si l’utilisateur a le rôle administrator, l’accès est toujours autorisé.
    • Vérifie les noms de route : seules certaines routes liées au vocabulaire de taxonomie ou à ses termes sont considérées.
    • Redirige les non-admins :
      • Pour les routes d’aperçu, d’ajout ou de liste (entity.taxonomy_vocabulary.overview_form, entity.taxonomy_vocabulary.overview_terms, entity.taxonomy_term.add_form), il vérifie si le vocabulaire est tag.
      • Pour les routes de modification et suppression (entity.taxonomy_term.edit_form, entity.taxonomy_term.delete_form), il vérifie si le bundle() du terme (nom machine du vocabulaire) est tag.
    • Utilise une redirection de confiance : si les conditions sont remplies, l’utilisateur est redirigé vers une page d’aperçu sûre pour le vocabulaire « tag ».
  • Extensibilité : la logique est facilement extensible pour gérer d’autres vocabulaires ou rôles en ajustant les conditions.

5. Sécurité et bonnes pratiques

  • Interception précoce : en s’exécutant lors de l’événement de requête, le subscriber peut appliquer l’accès avant tout traitement ou affichage de données sensibles.
  • Contournement basé sur les rôles : vérifie efficacement les rôles utilisateurs pour ne pas bloquer les administrateurs ou constructeurs de site.
  • Séparation claire des responsabilités : maintient la logique de routage, les vérifications utilisateur et la redirection bien distinctes pour faciliter la maintenance.

6. Améliorations potentielles

  • Puisque EntityTypeManagerInterface est injecté, vous pouvez facilement ajouter des contrôles basés sur les entités dans le futur (par exemple, des permissions basées sur des propriétés spécifiques d’un terme ou du contenu lié).
  • Vous pourriez généraliser la classe pour gérer plusieurs vocabulaires ou fournir des redirections personnalisables via la configuration.

7. Points clés à retenir

  • Ce Event Subscriber illustre une approche pratique de contrôle d’accès dans Drupal, tirant parti de l’architecture événementielle de Symfony pour un traitement précoce et efficace des requêtes.
  • L’approche est idéale pour protéger des vocabulaires de taxonomie qui doivent être gérés uniquement par des utilisateurs de confiance, réduisant ainsi le risque de modifications accidentelles.