Migration d’un forum PHPBB vers SPIP

La problématique

Le forum de la Ligue des Échecs d’Occitanie est en PHPBB.
A un moment très actif au fil des années et avec le développement d’autres réseaux sociaux, il est devenu de moins en moins fréquenté. Il faut de l’énergie pour maintenir cet outil à niveau alors qu’il est très peu utilisé… ce qui finit par poser un problème de sécurité.
Toutefois :
• Le forum privé de la Commission Technique a toujours une forte activité,
• Ce forum comprend aussi un historique important de débats, de résolutions de litiges etc. qu’il est important de conserver
Aussi on a décidé de migrer le forum PHPBB dans la solution SPIP. Après une phase de test ce « nouveau » forum sera intégré au site actuel de la Ligue.
Les fonctionnalités de l’ancien forum PHPBB ne seront probablement pas toutes migrées. Notamment les messages privés ne seront pas repris, le nombre de vues sur les forums et probablement pas non plus les sondages.
Pour transformer les forums en article il y a un nettoyage à faire de tout le code spécifique à PHPBB qui est présent dans les textes.

Migration, calendrier :

Une première phase de test sera ouverte aux utilisateurs actifs de la CT parce que ce sont eux seuls qui ont le besoin aujourd’hui.
La gestion des droits sera également revue de zéro : on ne migrera pas l’usine à gaz de droits de PHPBB, mais on partira des besoins très simples : laisser visible la partie publique et cacher les forums privés. Cette gestion des accès sera gérée par le plugin « accès restreint » et les groupes et les droits seront affinés pendant la première phase de test.

Migration, technique :

Il m’aura fallu apprendre pas mal de choses pour réussir à assurer cette migration :
• faire des requêtes MySQL simples dans phpmyadmin
• Apprendre à utiliser les bases de Regex
Le plugin RechRemp m’a été très utile et j’aurais eu plus de mal sans cet outil, j’ai utilisé soit la fonction de remplacement simple, soit les regex.
Surtout il a fallu nettoyer le code de PHPBB qui est bourré de balises spécifiques, des smileys en pagaille et des textes surlignés dans pas moins de 90 couleurs (au moins la moitié utilisées une seule fois...)

Les « sujets »

Le plus simple à basculer. On créée une section « forum de la Ligue » et à l’intérieur on créée rubriques et sous-rubriques en se basant sur la table phpbb3_topics.
Finalement on ne gardera que 3 sujets (rubriques), 2 publics (pour garder l’historique) qui seront en lecture seule et celui de la CT qui sera en accès restreint grâce au plugin du même nom.

Les sujets sont fixes, une fois définis on n’y touche plus

Les auteurs

Pour remplir la table spip_auteurs (exportée au format csv) on se base sur les tables phpbb3_users et phpbb3_profile_fields
Finalement de phpbb3_profile_fields on ne garde que les champs nom et prénom (spécifiques forum Ligue) afin de les concaténer et les importer dans le champ « nom » de la table spip_auteurs
Pour avoir l’info quelque part au moins provisoirement on convertit le champ user_regdate
en format date MySQL et on le copie dans le champ maj de la table spip_auteurs.

On enregistre au format csv et on importe dans SPIP.
Statut 1comite, pas de pass on verra ça un par un. De toute façon le forum sera en lecture seule sauf la dizaine de membres de la Commission Technique qui auront accès au forum de la CT Occitanie.

Attention j’avais un espace qui s’était mis à la fin du statut 1comite du deuxième auteur (le premier étant le webmestre) et les données ne s’affichaient pas dans SPIP…

Les dates sont stockées au format unix dans phpbb3. Je convertis dans le tableur avant d’exporter en csv avec cette formule
=(G2/86400)+25569
G2 étant la cellule avec le timestamp unix.
On ne fait cette migration qu’une fois : si entre le début du travail et la migration définitive un auteur est ajouté dans la Commission Technique, on l’ajoutera en manuel.

Les articles

Sont basés sur la table phpbb3_topics
On reprend 4 champs de cette table topic_id, forum_id, topic_title, topic_time qui vont respectivement alimenter les champs id_article, id_rubrique, titre, date
La requête SQL

INSERT INTO spip_articles (id_article,titre,id_rubrique,date,statut,id_secteur,accepter_forum,lang,langue_choisie,id_trad) SELECT topic_id,topic_title,forum_id,FROM_UNIXTIME(topic_time),'publie','1','pos','fr','non','0' FROM phpbb3_topics where topic_posts_unapproved <>'1' AND forum_id IN (2,5,6);

Lier les articles aux auteurs

Il faut maintenant alimenter la table spip_auteurs_liens
La requête SQL

INSERT INTO spip_auteurs_liens (id_auteur,id_objet,objet,vu) SELECT topic_poster,topic_id,'article','non' FROM phpbb3_topics where topic_posts_unapproved <>'1' AND forum_id IN (2,5,6);

Attention cette requête écrase les données déjà enregistrées dans la table

On alimente la table spip_forums avec phpbb3_posts

La requête MySQL

INSERT INTO spip_forum (id_forum,id_objet,objet,date_heure,date_thread,titre,texte,statut,auteur,id_auteur,ip,id_thread) SELECT post_id,topic_id,'article',FROM_UNIXTIME(post_time),FROM_UNIXTIME(post_time),post_subject,post_text,'publie',poster_id,poster_id,poster_ip,post_id FROM phpbb3_posts WHERE forum_id IN (2,5,6);

Associer les noms d’auteur aux forums

il faut aussi associer les noms d’auteurs dans les forums
Ce que demande la table spip_forum c’est le nom d’auteur… on le copie donc là

UPDATE `spip_forum` SET `auteur` = CASE
	WHEN auteur = 1 THEN 'Prenom  Nom de lauteur'

(...)

	WHEN auteur = 2186 THEN 'Prenom Nom dun autre auteur'
END

Nettoyage

On nettoie en MySQL toutes les balises spécifiques phpbb inutiles dans le texte…

UPDATE spip_forum SET texte = replace(texte, '<r>', ''); 
UPDATE spip_forum SET texte = replace(texte, '</r>', ''); 
UPDATE spip_forum SET texte = replace(texte, '<t>', ''); 
UPDATE spip_forum SET texte = replace(texte, '</t>', ''); 
UPDATE spip_forum SET texte = replace(texte, '<s>', ''); 
UPDATE spip_forum SET texte = replace(texte, '</s>', ''); 
UPDATE spip_forum SET texte = replace(texte, '<e>', ''); 
UPDATE spip_forum SET texte = replace(texte, '</e>', ''); 
UPDATE spip_forum SET texte = replace(texte,'<E>', '');
UPDATE spip_forum SET texte = replace(texte,'</E>', ''); 

Les smileys ou frimousses

On remplace tout ce qu’on peut avec une requête MySQL

UPDATE spip_forum SET texte = replace(texte, ':cry:', ':’');
UPDATE spip_forum SET texte = replace(texte, ';)', ';-)');
UPDATE spip_forum SET texte = replace(texte, ':wink:', ';-)'); 
UPDATE spip_forum SET texte = replace(texte, ':?:', ''); 
UPDATE spip_forum SET texte = replace(texte, ':!:', '');
UPDATE spip_forum SET texte = replace(texte,':D', ':-D'); 
UPDATE spip_forum SET texte = replace(texte,':lol:', ':-D'); 
UPDATE spip_forum SET texte = replace(texte,'8)', 'B-)');
UPDATE spip_forum SET texte = replace(texte,':oops:', '%-)');
UPDATE spip_forum SET texte = replace(texte,':P', ':-P');
UPDATE spip_forum SET texte = replace(texte,':twisted:', ':-P');
UPDATE spip_forum SET texte = replace(texte,':mrgreen:', 'O:)');
UPDATE spip_forum SET texte = replace(texte,':roll:', ':-!');
UPDATE spip_forum SET texte = replace(texte,':shock:', '8-)');
UPDATE spip_forum SET texte = replace(texte,':twisted:', ':-P');
UPDATE spip_forum SET texte = replace(texte,':twisted:', ':-P');

🤬 semble remonter OK…. On laisse ?

Les citations

La regex pour récupérer les citations (avec le nom, l’heure …)
Il y a plus de 22177 occurences dans 16368 messages de forum.
Pour l’instant on n’affichera que

Nom de la Personne Citée

, parce que c’est ce qu’on avoir facilement avec avec SPIP. Pas tout à fait conforme, mais bon...

On commence à remplacer avec Rechremp en regex

<QUOTE\hauthor="([A-Za-z0-9_&#;]{0,30}\h?[A-Za-z0-9_&#;]{0,30})"\hpost_id="[0-9]{2,6}"\htime="[0-9]{10}"\huser_id="[0-9]{1,4}">\[quote="?[A-Za-z0-9_&#;ïéç-]{0,30}\h?[A-Za-z0-9_&#;ïéç-]{0,30}"?\hpost_id=[0-9]{2,6}\htime=[0-9]{10}\huser_id=[0-9]{1,4}\]

3928 occurences dans 2881 messages de forum (remplacé par <quote><figcaption>$1</figcaption>)

<QUOTE\hauthor="([A-Za-z0-9_&#;-]{0,30}\h?[A-Za-z0-9_&#;-]{0,30}\h?[A-Za-z0-9_&#;-]{0,30})">\[quote="?[A-Za-z0-9_&#;ïéç-]{0,30}\h?[A-Za-z0-9_&#;ïéç-]{0,30}\h?[A-Za-z0-9_&#;ïéç-]{0,30}"?\]

1232 occurences dans 1079 messages de forum (remplacé par <quote><figcaption>$1</figcaption>)

avec Rechremp sans regex
<QUOTE>[quote]
1067 occurences dans 861 messages de forum (remplacé par <quote>)

[/quote]</QUOTE>
22170 occurences dans 16366 messages de forum (remplacé par </quote>)

Les gras et les italiques en code SPIP...

...et quelques smileys et les sauts de ligne en trop.
Également on remplace les "Underline" par un <span class="underline">(sans toucher à la css ça met un strong, et on va dire que ça suffit. Il sera toujours possible de

UPDATE spip_forum SET texte = replace(texte,'<B>[b]', '{{');
UPDATE spip_forum SET texte = replace(texte,'[/b]</B>', '}}');
UPDATE spip_forum SET texte = replace(texte,'<I>[i]', '{');
UPDATE spip_forum SET texte = replace(texte,'[/i]</I>', '}');
UPDATE spip_forum SET texte = replace(texte,':arrow:', '');
UPDATE spip_forum SET texte = replace(texte,':idea:', '');
UPDATE spip_forum SET texte = replace(texte,'<br/>', ''); 
UPDATE spip_forum SET texte = replace(texte,'<U>[u]', '<span class="underline">');
UPDATE spip_forum SET texte = replace(texte,'[/u]</U>', '</span>');

Les textes en couleur et de taille différente

Avec Rechremp
<SIZE size="\d*">\[size=\d*\]supprimés
[/size]</SIZE> par rien

<COLOR\hcolor="(#?[a-zA-Z0-9]+)">\[color=#?[a-zA-Z0-9]+\]
remplacer par <div style="color:$1;">
[/color]</COLOR> remplacé par </div>
</COLOR> remplacé par </div>
[/color] par rien

Attention à (par exemple)
Auch </COLOR>}}<i>[/color]</i> {{<div style

Voilà c’est migré en articles plus forums dans SPIP
Pendant la période de test il faudra notamment voir comment restreindre les accès :

  • sujets "archivés" en lecture seule
  • forum Commission Technique protégé avec Accès Restreint

Fusionner avec le site principal

Ensuite on fusionne en local avec le site principal grâce au plugin fusion_spip.

Comme d’habitude avec le plugin fusion_spip, il faut vérifier d’être cohérent avec les plugins utilisés (et leurs tables) pour être le plus consistent possible.

Supprimer les auteur·es en double

Attention, du coup plusieurs auteur·es sont en double voire même en triple pour certains. (initialement inscrits sur le forum et sur le site). On va s’assurer, au moins pour les membres de la CT dans un premier temps (ceux qui vont utiliser le forum privé)

On ramène tous les sujets et articles d’auteur·e avec le même nom sous un auteur·e unique.
En deux temps.
D’abord on met tout sous le même auteur·e
Par exemple avec cette requête SQL

UPDATE spip_auteurs_liens SET id_auteur = replace(id_auteur,'356', '2');
UPDATE spip_forum SET id_auteur = replace(id_auteur,'357', '2');

Puis on supprime l’auteur·e qui n’a pas plus de publication

DELETE FROM spip_auteurs
WHERE id_auteur IN (357,356,748,371,454,689,401,364,750,742,790,738,393,818,734);

Créer la zone d’accès restreint

Avec le plugin accès restreint on créée la zone qui réserve l’accès au forum CT aux seul·e·s membres de la Commission Technique.

Bloquer les commentaires sur les deux forums migrés pour historique

On souhaite que le débat n’ait plus lieu dans ces forums "historiques" mais dans les articles courants du site, quand les administrateur·e·s le souhaitent.
On va désactiver la possibilité de mettre des commentaires en mettant "non" dans le champ accepter_forum des articles des rubriques "débat général" et "résultat des matchs par équipe"

UPDATE spip_articles SET accepter_forum = replace(accepter_forum,'pos', 'non') where id_rubrique IN (80,81);

C’est prêt, ... et reste à faire !

Après vérifications on exporte la BDD pour qu’elle remplace celle du site de prod, ce sera fait le 19 mars

Après mise en prod deux questions :

  • on me demande la possibilité de modifier le texte des forums... Je vérifie les crayons devraient bien pouvoir être activés avec la balise #EDIT... mais rien ne se passe. A creuser
  • Les urls ont été oubliées. Beaucoup de vieux posts envoient sur des sites qui n’existent plus... mais il faudra tout de même les reprendre...