jobsphp

Migration Drupal 10 : le défi technique de Marc

Open Source & Outils. Migration Drupal 10 : le défi technique de Marc

Le 5 janvier 2025, Drupal 7 a officiellement cessé de recevoir les correctifs de sécurité et les mises à jour communautaires. Après 14 ans d’existence, la branche est désormais hors cycle.

Migration Drupal 10: le défi technique de Marc

Une installation Drupal 7 encore exposée sur Internet n’est pas seulement ancienne: elle repose sur une pile logicielle qui ne bénéficie plus du même niveau de maintenance, alors que PHP, les bibliothèques et les exigences d’hébergement ont continué d’évoluer.

La migration Drupal 7 vers Drupal 10 n’est donc pas une mise à jour de version. Il n’existe pas de commande capable de transformer proprement un projet Drupal 7 complexe en application Drupal 10 sans réécriture. Le passage implique un changement d’architecture, de moteur de rendu, de modèle de configuration et de système de modules. Les données peuvent être transférées. Le site, lui, doit être reconstruit.

Le défi de Marc — le nom importe moins que la situation technique — consiste à séparer ce qui doit être conservé de ce qui doit être abandonné. Contenus, utilisateurs, taxonomies et fichiers ont une valeur fonctionnelle. Les modules obsolètes, les thèmes vieillissants et les adaptations spécifiques à Drupal 7 ne sont pas des actifs à déplacer tels quels.

Drupal 7 et Drupal 10 ne parlent pas la même langue

Drupal 7 repose sur une architecture historique, avec des conventions procédurales, une gestion de configuration fortement liée à la base de données et un système de rendu qui n’a plus la même place dans Drupal moderne. À partir de Drupal 8, le cœur a été profondément réorganisé autour de Symfony, de composants orientés objet et du moteur de templates Twig.

Ce changement touche directement le code personnalisé.

Un module Drupal 7 utilisant des fonctions globales, des hooks anciens et des accès directs à la base ne peut pas être copié dans le répertoire d’un site Drupal 10. Il doit être porté ou réécrit. Dans certains cas, il faut simplement remplacer une API. Dans d’autres, le module reproduit une logique métier devenue incompatible avec le nouveau modèle d’entités, le conteneur de services ou le système de routage.

Même diagnostic pour le thème. Un thème Drupal 7 basé sur PHPTemplate ne devient pas un thème Drupal 10 par changement de nom. Twig impose une nouvelle séparation entre logique applicative et présentation. Les fichiers de gabarit doivent être recréés, les suggestions de templates revues et les variables exposées par le preprocess adaptées.

Une migration Drupal 7 vers Drupal 10 transfère des données. Elle ne transporte pas automatiquement l’architecture.

Le terme de refonte n’est pas une exagération marketing. Il décrit une contrainte technique. Drupal 10 utilise Symfony et Twig; Drupal 7 ne peut pas être traité comme une version précédente immédiatement compatible. La stratégie correcte consiste à installer une base Drupal 10 propre, à définir son modèle cible, puis à importer les données avec les outils de migration.

Le périmètre réel se mesure avant la première commande

La durée d’une migration Drupal 10 ne dépend pas uniquement du nombre de pages. Un site avec quelques milliers de contenus peut être plus complexe qu’un portail beaucoup plus volumineux si son modèle de données contient des champs atypiques, des imports externes ou des modules développés sur mesure.

L’inventaire doit couvrir quatre couches distinctes:

  • Les contenus: types de contenus, champs, révisions, traductions, statuts de publication et relations entre entités.
  • La structure éditoriale: vocabulaires, termes de taxonomie, menus, blocs, vues et règles d’affichage.
  • Les dépendances techniques: modules contrib, modules personnalisés, bibliothèques JavaScript, intégrations tierces et tâches planifiées.
  • La couche visible: thème, gabarits Twig à produire, formulaires, parcours de recherche, affichage mobile et composants éditoriaux.

Cette cartographie évite une erreur fréquente: considérer la base de données comme le site. Elle n’en contient qu’une partie. Les fichiers publics et privés, les réglages du serveur web, les tâches cron, les certificats, les index de recherche et les connexions à des services externes doivent être traités séparément.

Un audit efficace produit au minimum une matrice de décision pour chaque composant:

Élément Drupal 7Décision cible Drupal 10Travail technique
Type de contenu standardConservationRecréation du type et migration des champs
Module contrib disponible en Drupal 10RemplacementInstallation, configuration et adaptation des données
Module sans équivalent maintenuRéécriture ou abandonAnalyse fonctionnelle et développement spécifique
Thème PHPTemplateRefonteNouveau thème Twig, CSS et composants
Vue ou affichage complexeReconstructionRecréation des vues et contrôle des résultats
Alias d’URLMigration dédiéeExécution de la migration d7_url_alias
Fichiers publics et privésTransfert contrôléCopie, vérification des chemins et permissions

Cette étape est souvent celle qui révèle le véritable coût du projet. Le volume de contenus produit une charge de traitement. Le volume de logique spécifique produit une charge de conception. Les deux ne se corrigent pas de la même manière.

Les outils de migration du cœur font le transfert, pas l’analyse

Drupal 10 fournit les briques nécessaires au transfert des données Drupal 7. Les modules du cœur Migrate, Migrate Drupal et Migrate Drupal UI permettent de définir et d’exécuter les migrations depuis la base existante. L’interface utilisateur est accessible via le chemin /upgrade.

Le fonctionnement est relativement direct:

1. Le site Drupal 10 est installé sur une infrastructure séparée.

2. La base Drupal 7 est rendue accessible à l’environnement de migration.

3. Les modules nécessaires sont activés.

4. Drupal détecte la source Drupal 7 et propose les migrations disponibles.

5. Les contenus, utilisateurs, taxonomies, fichiers et éléments de configuration compatibles sont importés.

6. Les erreurs sont analysées, corrigées, puis les migrations sont relancées.

La dernière étape est la plus importante. Une migration n’est pas validée parce que l’interface affiche un message de réussite. Il faut comparer les volumes, les relations et les sorties fonctionnelles. Un import peut terminer sans erreur bloquante tout en produisant des références manquantes, des champs vides ou des fichiers non résolus.

Pour les projets complexes, l’interface /upgrade sert surtout de point de départ. Les migrations doivent ensuite être contrôlées et parfois personnalisées avec des fichiers de configuration, des plugins de processus ou des scripts Drush. Le niveau de contrôle recherché dépend de la qualité des données source et du nombre de transformations nécessaires.

Le modèle de migration Drupal repose sur trois familles d’opérations:

  • La source, qui décrit l’origine des données Drupal 7.
  • Le processus, qui transforme les valeurs: renommage de champ, conversion de format, association à une taxonomie ou normalisation d’une date.
  • La destination, qui crée l’entité Drupal 10 correspondante.

Cette séparation est utile parce qu’elle rend les transformations répétables. Une importation manuelle dans la base peut sembler plus rapide sur un cas isolé, mais elle détruit la traçabilité et complique les répétitions. Une migration doit pouvoir être exécutée plusieurs fois sur un environnement de test, puis sur la préproduction, sans devenir une opération artisanale.

Le cas oublié des alias d’URL

L’importation par défaut des entités de contenu ne transfère pas automatiquement tous les alias d’URL historiques de Drupal 7. La table url_alias doit être traitée avec la migration dédiée d7_url_alias, qui permet de produire les entités path_alias de Drupal 10.

Ce point est fonctionnel et technique à la fois. Une URL perdue dégrade les liens entrants, les favoris, les résultats indexés et les parcours internes. Une page correctement importée mais inaccessible sous son ancienne adresse reste une régression.

La séquence doit donc inclure:

  • l’import des contenus;
  • l’import des alias avec d7_url_alias;
  • la vérification des langues et des préfixes;
  • la gestion des redirections nécessaires;
  • le contrôle des liens internes générés par le thème et les champs riches.

Il ne faut pas confondre alias et redirection. Un alias donne une adresse lisible à une entité. Une redirection traite une ancienne adresse qui ne correspond plus directement à la nouvelle structure. Les deux mécanismes peuvent être nécessaires.

Le code personnalisé concentre le risque

Un site Drupal 7 standard est rarement le problème principal. Le risque se situe dans les modules et les intégrations construits autour de ses particularités.

Le code doit être classé par fonction, pas seulement par nom de fichier. Un module personnalisé qui ajoute un champ ne présente pas le même risque qu’un module qui intercepte la publication, modifie les requêtes, appelle un ERP ou génère des exports nocturnes.

L’analyse doit notamment rechercher:

  • les appels directs à la base de données;
  • les fonctions supprimées ou remplacées dans Drupal moderne;
  • les variables globales utilisées comme stockage applicatif;
  • les hooks dont le comportement a changé;
  • les formulaires construits avec l’ancienne API;
  • les appels à des services externes sans gestion d’erreur;
  • les traitements exécutés pendant chaque requête;
  • les tâches cron qui supposent un volume de données faible;
  • les dépendances JavaScript intégrées directement dans le thème;
  • les règles d’accès codées en dehors du système de permissions.

La migration est l’occasion de réduire la dette technique. Porter chaque ligne à l’identique est rarement la meilleure stratégie. Une logique écrite en Drupal 7 peut être remplacée par une configuration Drupal 10, un module contrib maintenu ou un service dédié. Le portage mécanique conserve les défauts de conception et les comportements implicites.

Typage, services et allocation mémoire

Drupal 10 s’inscrit dans un environnement PHP moderne. Le code personnalisé doit être compatible avec les versions de PHP supportées par la cible et avec les pratiques actuelles de l’écosystème: classes autoloadées par Composer, injection de dépendances, interfaces explicites et typage strict lorsque le périmètre le permet.

Cela ne signifie pas que l’ajout de declare(strict_types=1); suffit à moderniser un module. Le typage révèle les incohérences existantes: valeurs nulles inattendues, tableaux hétérogènes, identifiants traités comme des chaînes ou retours variables selon le contexte. C’est un outil de détection, pas une opération cosmétique.

La consommation mémoire mérite la même attention. Les migrations qui chargent trop d’entités en mémoire échouent souvent sur les environnements modestes. Les traitements par lots, la pagination et la limitation des requêtes réduisent la pression sur l’allocation mémoire et le garbage collector de PHP. À l’inverse, une boucle qui reconstruit des objets complets pour chaque ligne peut saturer le processus sans produire d’erreur fonctionnelle claire.

Le problème n’est pas uniquement la rapidité d’une commande. Il faut observer:

  • la mémoire maximale utilisée par lot;
  • le temps d’exécution d’une migration;
  • le nombre d’erreurs et d’éléments ignorés;
  • la durée des requêtes SQL;
  • le volume de journalisation;
  • la stabilité des traitements après plusieurs relances.

Un transfert qui fonctionne sur 500 contenus mais échoue sur 500 000 n’est pas une migration terminée. C’est un prototype.

Le bon test n’est pas: « l’import passe-t-il? » Le bon test est: « peut-on le relancer, le mesurer et expliquer chaque élément non importé? »

Le thème doit être reconstruit sur une sortie contrôlée

La refonte du thème constitue un chantier autonome. La migration des données peut être correcte et le site rester inutilisable si la couche de présentation n’est pas traitée avec la même rigueur.

Twig limite volontairement la logique exécutée dans les templates. Cette contrainte est saine: les règles métier doivent rester dans le code applicatif, les preprocess ou les services appropriés. Un template ne doit pas devenir un second contrôleur contenant des conditions impossibles à tester.

Le travail porte sur plusieurs niveaux:

1. Le système de composants: boutons, formulaires, messages, cartes, listes, tableaux et éléments de navigation.

2. Les gabarits d’entités: nœuds, taxonomies, utilisateurs, vues et formulaires.

3. Les suggestions de templates: variantes par type de contenu, mode d’affichage ou contexte.

4. Les assets: feuilles de style, JavaScript, polices, images et dépendances.

5. Le rendu responsive: comportement sur les différentes largeurs, sans reproduire les défauts historiques.

6. L’accessibilité: structure HTML, navigation clavier, libellés de formulaires et contrastes.

Il faut éviter de porter le HTML existant sans examen. Un vieux thème accumule souvent des sélecteurs redondants, des dépendances implicites et des contournements liés à Drupal 7. Reproduire exactement le résultat visuel peut coûter plus cher que reconstruire les composants à partir des besoins actuels.

Les vues doivent également être testées sur les volumes réels. Une requête acceptable avec quelques centaines de lignes peut devenir coûteuse lorsqu’elle combine plusieurs relations, des filtres exposés et un tri sur un champ non indexé. Le cache améliore la latence observée, mais il ne corrige pas une requête structurellement inefficace.

Les tests déterminent la durée de migration

La durée d’une migration Drupal 10 ne peut pas être déduite sérieusement d’un nombre de pages. Elle dépend du périmètre fonctionnel, du nombre de migrations à personnaliser, de la qualité des données et du niveau de validation requis.

Un projet court peut être ralenti par une seule dépendance critique: un connecteur propriétaire, un module abandonné ou une structure multilingue mal documentée. À l’inverse, un volume important de contenus peut être traité de manière industrielle si le modèle est régulier et les transformations sont bien définies.

La validation doit s’effectuer à plusieurs niveaux.

Validation des données

Les volumes Drupal 7 et Drupal 10 doivent être comparés par type d’entité, statut, langue et période. Les relations entre contenus doivent être contrôlées, notamment les références d’entités et les termes de taxonomie.

Les fichiers nécessitent un contrôle spécifique. Il ne suffit pas de constater que le répertoire existe. Il faut vérifier que les URI enregistrées dans les champs correspondent aux fichiers présents et que les permissions empêchent l’exposition accidentelle des ressources privées.

Validation fonctionnelle

Les formulaires de connexion, de recherche, de contact et de contribution doivent être exécutés sur la cible. Les règles d’accès doivent être testées avec des rôles distincts. Les tâches cron et les imports externes doivent être lancés sur des données de test.

Le système de cache doit être purgé puis reconstruit. Une page qui fonctionne uniquement parce qu’elle provient d’un cache préparé n’est pas validée.

Validation de performance

Les mesures utiles sont comparatives. Il faut relever le temps de réponse, le nombre de requêtes SQL, la consommation mémoire et le comportement sous charge avant et après migration. Il n’existe pas de gain garanti simplement parce que Drupal 10 est plus récent.

Une architecture moderne offre de meilleurs leviers de scalabilité, mais elle peut aussi révéler des requêtes mal conçues ou des traitements qui étaient masqués par un cache agressif. La performance doit donc être mesurée sur les parcours qui comptent: recherche, listing filtré, page éditoriale lourde, connexion et soumission de formulaire.

Validation des adresses

Les anciennes URL doivent être comparées aux nouvelles. Les alias importés avec d7_url_alias ne couvrent pas nécessairement tous les cas historiques: changements de structure, contenus supprimés, URLs générées par des modules ou redirections déjà présentes dans le serveur web.

Une analyse des journaux HTTP permet de détecter les erreurs 404 après bascule. Le contrôle ne doit pas se limiter à la page d’accueil et aux contenus les plus visibles. Les URLs profondes, les documents et les pages multilingues concentrent souvent les régressions.

Ce qu’il faut faire de Drupal 7 après le 5 janvier 2025

Maintenir Drupal 7 en production après sa fin de vie officielle augmente l’exposition au risque. La branche ne reçoit plus les correctifs de sécurité gratuits de la communauté officielle. Les adaptations locales de PHP ne changent pas ce constat: elles peuvent maintenir le fonctionnement d’une application, pas recréer un cycle de maintenance du cœur et des modules.

Des programmes payants d’assistance de sécurité étendue existent auprès de vendeurs spécialisés, notamment HeroDevs et Tag1 Consulting. Ils peuvent fournir des correctifs temporaires pour certains composants. Ce dispositif est un délai supplémentaire, pas une stratégie de modernisation.

Il reste pertinent dans quelques situations contraintes: projet soumis à une dépendance réglementaire, refonte déjà financée mais non terminée, système isolé du réseau public ou calendrier de bascule impossible à avancer. Dans ces cas, la décision doit être documentée et limitée dans le temps. L’assistance étendue ne transforme pas Drupal 7 en plateforme durablement compatible avec l’écosystème PHP moderne.

Drupal 10 possède lui-même une date de fin de vie programmée au 9 décembre 2026. Ce calendrier doit être intégré dès la conception. Une migration lancée tardivement vers une branche proche de sa propre échéance recrée une dette à court terme. Il faut prévoir les mises à jour mineures, la maintenance Composer, les contrôles de compatibilité PHP et la capacité à évoluer vers la branche suivante.

Le plan d’exécution qui évite le retour arrière

Une migration robuste se déroule sur des environnements séparés. La production Drupal 7 reste stable pendant que la cible Drupal 10 est construite et alimentée par des imports reproductibles.

L’ordre opérationnel est généralement le suivant:

1. Geler le périmètre: identifier les fonctions réellement utilisées et supprimer les modules sans usage avant l’analyse.

2. Sauvegarder: base, fichiers, configuration serveur et éléments nécessaires à une restauration complète.

3. Construire la cible: Drupal 10, Composer, PHP compatible, base dédiée et chaîne de déploiement.

4. Recréer le modèle: types de contenus, champs, taxonomies, rôles, permissions, médias et menus.

5. Configurer les migrations: import initial, transformations spécifiques, fichiers et alias.

6. Porter le code: modules personnalisés, intégrations, tâches cron et règles d’accès.

7. Refondre le thème: Twig, composants, assets et comportement responsive.

8. Répéter les imports: plusieurs passages sur des copies représentatives de la production.

9. Mesurer: données, performances, erreurs, journaux et parcours fonctionnels.

10. Basculer: dernière synchronisation, fenêtre de maintenance, validation et surveillance des erreurs.

Le point critique est la répétabilité. Si chaque import nécessite une correction manuelle dans la base, le processus n’est pas maîtrisé. Si le déploiement dépend d’un répertoire modifié directement sur le serveur, le projet ne dispose pas d’une chaîne fiable.

La configuration doit être exportable et versionnée. Le code doit passer par Git. Les dépendances doivent être gérées par Composer. Les secrets ne doivent pas être stockés dans le dépôt. Ce ne sont pas des raffinements d’architecture: ce sont les conditions minimales pour reconstruire un environnement cohérent.

Verdict

À utiliser en production: oui, Drupal 10, avec une refonte planifiée, des migrations rejouables et une validation mesurée.

À utiliser en production: non, Drupal 7 après le 5 janvier 2025, sauf dispositif temporaire d’assistance étendue et plan de sortie daté.

La migration Drupal 7 vers Drupal 10 n’est pas un bouton de mise à niveau. C’est un transfert de données associé à une reconstruction applicative. Les outils du cœur réduisent le travail mécanique, mais ils ne remplacent ni l’audit du code, ni la refonte du thème, ni les tests de charge, ni le contrôle des URLs.

Marc ne doit pas chercher à sauver chaque ligne de Drupal 7. Il doit sauver les données utiles, les règles métier justifiées et les adresses qui ont une valeur réelle. Le reste appartient à l’historique de la plateforme.

Questions fréquentes

Pourquoi ne puis-je pas simplement mettre à jour mon site Drupal 7 vers Drupal 10 ?
Il n'existe pas de commande de mise à jour directe car Drupal 10 repose sur une architecture Symfony et un moteur de rendu Twig, contrairement à Drupal 7 qui utilise des conventions procédurales.
Que deviennent mes modules et mon thème Drupal 7 lors de la migration ?
Ils ne peuvent pas être transférés tels quels. Les modules doivent être portés ou réécrits pour s'adapter au nouveau modèle d'entités, et le thème doit être entièrement reconstruit avec Twig.
Comment transférer mes contenus de Drupal 7 vers Drupal 10 ?
Vous devez utiliser les modules du cœur Migrate, Migrate Drupal et Migrate Drupal UI, qui permettent d'importer les données depuis la base Drupal 7 vers une installation Drupal 10 propre.
Les alias d'URL sont-ils conservés automatiquement ?
Non, l'importation par défaut ne transfère pas les alias. Il est nécessaire d'exécuter la migration dédiée d7_url_alias pour générer les entités path_alias de Drupal 10.
Est-il possible de continuer à utiliser Drupal 7 après janvier 2025 ?
C'est fortement déconseillé car la branche ne reçoit plus de correctifs de sécurité. Seuls des programmes payants d'assistance étendue peuvent offrir des correctifs temporaires dans des cas très contraints.