J'ai régulièrement besoin d'organiser le transfert des données de sites Joomla vers une copie de ces sites, pour plusieurs raisons (nettoyage, mise-à-jour, sauvegardes spécifiques, évolutions...).
Là-dessus, vous allez me dire : beh euuuh, tu connais pas Akeeba ? Si si, je connais, et je valide. J'utilise AkeebaBackup sur tous mes sites Joomjoom, à des fins de sauvegardes. Mais ça ne correspond pas à tous mes besoins. Soit trop lourd, soit trop spécifique, soit trop long...
Imaginez par exemple que vous souhaitiez préparer la nouvelle version d'un site - en modifiant des menus, modules, catégories, etc - tout en y insérant les données du site en production😎Pas simple hein ? Maintenir la cohérence des données tout en travaillant sur les évolutions est un vrai défi, et Akeeba ne fait plus du tout l'taf.
Il s'agit donc de transférer les données cœur de Joomla : articles, catégories, tags, utilisateurs, groupes, droit d'accès, etc - comprenant également certaines tables, lignes ou valeurs spécifiques : id super-utilisateur, #_assets, #_ucm, #_workflows, etc - sans toucher aux données structurelles de Joomla. Ce qui peut être un sacré bazar, car Joomjoom a parfois ses raisons que l'amour irradie... ou ignore... ou... bref🥴
De plus, dans certains cas, ce n'est pas seulement les données cœur que je souhaite transférer, mais aussi certaines tables métiers, créées à côté de Joomla (avec Fabrik par exemple).
Dans d'autres cas, j'ai besoin de le faire régulièrement, parfois même très, très, très régulièrement😥: pour tester des templates, des mises-à-jour suspectes, des triggers SQL... Avec donc le besoin d'être rapide et depouvoir vidanger le site de destination à chaque opération.
J'ai donc décider d'automatiser tout ça ! Voici le le lien GitHub vers un petit process qui me fait gagner pas mal de temps, et qui peut-être vous en fera gagner à vous aussi. Une fois mis en place, un clic et quelques secondes/minutes (selon la taille du site) suffisent pour transférer vos données.
https://github.com/georgie123/JoomlaDataMigration
Grands principes
Données cœur VS données structurelles
Identification/séparation/gestion des données cœur VS données structurelles, afin de permettre le développement continu du site de destination en même temps que le transfert régulier des données du site d'origine.
L'un des intérêts de ce principe est de garantir l'absence d'impact sur le site source (nommé source dans le code, ou _s).
Le process ne touchera jamais au site source.
Optimisation des transferts de données
Les tables Joomla, on le sait, peuvent évoluer d'une version à l'autre du CMS (des tables en plus, des tables en moins, des champs en plus, des champs en moins, des champs légèrement renommés😣... oui oui, vous avez bien lu : parfois des champs sont renommés d'une version à l'autre !).
Des fonctions de vérification de l'existence des tables et de comparaison des champs présents vont générer les requêtes SQL de façon dynamique, puis les exécuter (et afficher quelques logs en console). Il s'agit des fonctions isTableExistInTarget/Source
; et de conditions basées sur des comparaisons dynamiques à partir de requêtes SELECT column_name FROM information_schema WHERE
.
Un autre intéret de cette méthode est d'être particulièrement évolutive : ajouter le transfert d'une autre table nécessite simplement de l'ajouter dans une liste😎
Nous allons aussi prendre en compte la taille des requêtes, et les connexions au réseau, afin d'éviter tout interruption, ou manquement, qui endommagerait le site cible (nommé target dans le code, ou _t). Ainsi les requêtes sensibles passeront par les fonctions query_management_select_t/s
ou query_management_update
, vérifiant la bonne exécution des requêtes, les divisant éventuellement en lot et les ré-exécutant si besoin.
Indépendance des scripts de transferts
Plusieurs scripts sont présents dans le répertoire transferts, car la cohérence des données ne suit pas toujours la même logique, selon que l'on parle des données de contenu, des données d'utilisateurs, de la gestion des liens, des images, de données personnalisées... Ces logiques sont donc séparées en scripts distincts.
Un script peut donc être ajouté ou supprimé sans gêner le reste du processus, facilitant ainsi son évolutivité (ajouter la gestion d'une extension par exemple).
Scripts de transfert
_params.py
Ce script contient les accès aux 2 sites (le site source et le site cible (target).
Il est extrêmement important de ne pas confondre le site source et le site cible. Le site site source est votre site en production, auquel nous ne toucherons pas. Le site cible est le site en cours de travail, qui n'est pas en production.
start.py
Ce script lance définit quelques fonctions qui seront utilisées plus tard, crée quelques variables qui seront utilisées plus tard, puis lance les scripts de transfert.
_1_users.py
Le premier script de transfert. Ce script transfère les données utilisateurs de Joomla.
_2_contents.py
Ce script transfère les données de contenu de Joomla.
_3_images_and_links.py
Ce script traite les liens divers des données de contenu. L'objectif est double :
- transformer tous les liens présents en liens durs. Car le fonctionnement parallèle des 2 sites en sera facilité.
- gérer une éventuelle utilisation de la ré-écriture des URLs en clair (URLs Rewriting).
Attention : ce script ne gère pas le transfert des images ou fichiers utilisés par les contenus. Nous verrons cela plus bas.
_4_forum_kunena.py
Gestion d'un éventuel forum Kunena. Si le site source n'utilise pas Kunena, le process va le comprendre (en regardant si certaines tables existent, fonction isTableExistInTarget
).
Comment ça marche ?
La première chose est de remplir correctement les variable du script _params.py.
Cela sans confondre le site source et le site cible.
Ensuite, lanceez simplement le script start.py 😎
Versions testées
- OK de J3.9.23 à J5.0.2
- OK de J3.9.23 à J5.1.1
- OK de J3.7.4 à J4.2.8
- Notes personnelles d'amélioration :
- - Extraire les chemins des images et fichiers utilisés, dans _5_files_listing.py, afin de faciliter leur transfert manuellement, car ce transfert est indispensable au moins 1 fois après l'exécution du process.
- - Vérifier que la messagerie privée se vide aussi, en back.
- - Regarder de quelle version date la suppression des id de l'URL rewrite et le faire selon !