Voici un retour d’expérience sur un cas assez courant dans le développement de code custom pour Drupal 8.
Un module contient un contrôleur dont vous voulez surcharger une des méthode parce que vous avez besoin de modifier la logique de celle-ci et que le code ne vous fourni aucun moyen pour ça (un hook par exemple).
Mais cette classe qui implémente ControllerBase fait déjà usage de l'injection de dépendance, (et de ce fait le plus souvent annule tout ou partie des méthode disponibles avec ControllerBase, mais c'est un autre sujet).
Un exemple concret avec le module Message subscribe, le sous module message_subscribe_ui utilise un contrôleur SubscriptionController, une des méthode getView()
permet d'appeler une vue (views) pour afficher des pages d'administration.
Problème, le module se base sur une règle de nom de la vue avec nom d'un flag :
Seulement voila, pour divers raison cela ne me convient pas, dans mon cas actuel j'utilise PostreSQL et les vues utilisés ne fonctionnent pas ! Je souhaite donc modifier ce code et surcharger cette méthode pour utiliser des vues différentes avec ma propre règle de nommage.
Le contrôleur utilise la méthode tab()
pour créer un onglet de page qui ensuite appelle getView()
pour afficher la vue.
La solution va donc être de surcharger dans Drupal cette méthode tab()
et de pouvoir ainsi modifier getView()
, pour cela je doit utiliser RouteSubscriber pour modifier la route et le contrôleur associé comme expliqué dans la documentation Drupal.
La première étape est d'avoir un nouveau service avec le fichier my_module.services.yml
:
Et de remplacer le contrôleur de la route :
Maintenant je peux mettre en place ma classe, mais j'ai besoin d'injecter un nouveau service pour mon code, pour y arriver je dois utiliser l'injection de dépendance déjà existante dans le constructeur de la classe et ajouter mon service.
C'est là qu'on ne trouvera pas beaucoup de documentation, voici mon exemple avec les commentaires réduits :
Plutôt simple au final, il suffit d'appeler le constructeur parent depuis mon constructeur et d'ajouter mon service et d'ajouter celui-ci dans ma méthode create()
.