Suppression en bloc d'utilisateurs
Comment supprimer massivement les spammers qui s'inscrivent sur les forums pour faire indexer des liens sur leur site par les moteurs de recherche?
Il est dommage que fluxBB ne permette pas de moduler l'accès aux renseignements sur les utilisateurs selon leur anciènneté.
Une première riposte au spam est très simple: Le spam devient déjà inutile si le fichier robots.txt interdit aux moteurs de recherche l'accès aux profils:
disallow:/forum/profile.php
disallow:/forum/userlist.php
Ensuite il faudrait de temps en temps nettoyer la base de donnée des inscriptions inutiles, tous les spammeurs dont les messages ont été effacés ou qui n'ont pas posté de message..
Mais ce n'est pas si simple: il y a des relations multiples entre les tables de la base et si l'on supprime une entrée dans l'une d'elles, il faut aussi supprimer toutes les références à cette entrée.
Tables fluxBB et membres inscrits
Nous allons donc voir toutes les tables et colonnes qui se rapportent aux utilisateurs.
users
id: identificateur repris dans d'autres tables.
username: nom repris dans d'autres tables.
num_posts: nombre de messages.
bans
username: l'utilisateur peut être banni, il faut supprimer l'entrée dans bans aussi.
reports
reported_by: (id) pour le cas peu probable ou un spammer aurait fait un rapport.
subscriptions
user_id: (id) pour le cas ou le spammer aurait souscrit à ce fil de discussion.
La requête d'interrogation
A partir de l'interface de PHPMyAdmin ou toute autre interface à SQL, on peut déjà voir combien il y a d'utilisateurs inactifs:
SELECT username FROM users WHERE num_posts='0' AND username != 'Guest'
Remplacer users par xxxxusers si le préfix déclaré dans config.php est xxxx.
On exclut Guest qui est un le nom générique des invités dans la version anglaise. Ce peut être un autre nom dans votre version, vérifier dans la liste des utilisateurs pour l'id 1.
En fait il est indispensable de conserver un utilisateur dont l'id est 1.
Voir les utilisateurs bannis sans messages:
SELECT * FROM bans, users WHERE bans.username=users.username AND users.num_posts='0'
Autre formulation utilisable pour la suppression:
SELECT * FROM bans WHERE username IN (SELECT username FROM users WHERE num_posts='0')
On remplacera SELECT * par DELETE pour la suppression.
La requête de suppression
On supprime les utilisateurs n'ayant aucun message avec cette commande SQL:
DELETE FROM $usertable WHERE num_posts='0' AND username != 'Guest'
Important: Dans la version francisée, remplacer Guest par Invité. Il a l'id 1.
Mais on doit d'abord éliminer les références:
DELETE FROM bans WHERE username IN (SELECT username FROM users WHERE num_posts='0')
DELETE FROM reports WHERE reported_by IN (SELECT id FROM users WHERE num_posts='0')
DELETE FROM subscriptions WHERE user_id IN (SELECT id FROM users WHERE num_posts='0')
On peut se contenter de vérifier d'abord les références, et faire une simple suppresssion s'il n'y en a pas.
En faire un script
Cette seconde partie introduit un script PHP à placer sur le site et qui réalise l'opération automatiquement.
On définit un spammeur comme utilisateur s'inscrivant pour ajouter son profil, avec un lien sur un site éventuellement douteux, et qui n'a pas jamais ajouté de billet ou dont les billets sont des spams et ont été supprimés.
Le script est plus élaboré que la commande SQL simple, car il va tester la table des messages pour vérifier que l'utilisateur n'en a posté aucun et ne se contente pas de consulter le nombre de messages dans la table utilisateur.
Ce dernier en effet n'est pas mis à jour par fluxBB après suppression d'un billet. C'est un compteur à sens unique!
Plus de tables fluxBB
Outre les tables décrites dans la première partie, nous utiliserons cette fois la table posts.
Table posts:
poster | poster_id | ||||
pseudo de l'utilisateur | son numéro d'identification |
On veut seulement de vérifier qu'un utilisateur n'a aucun billet.
Table topics:
poster | ||||
pseudo de l'utilisateur |
Normalement le topic est supprimé quand le premier billet est supprimé aussi on n'utilisera pas cette table.
Requête
On reprend les requêtes données dans la première partie et on ajoute un traitement pour la table des messages.
Vérifier le nombre de messages pour un utilisateur (on fera le test pour tous les utilisateurs en fait):
$user = "xxxx";
$query = SELECT * WHERE poster='$user'
$hnd = mysqli_query($db_handler, $query);
if(mysqli_num_rows($hnd) == 0)
{
echo "$user n'a aucun message.<br>";
}
Si le nombre de message est null, on peut mettre à jour le nombre de billets dans la table users:
UPDATE users SET num_posts='0' WHERE poster='$user'
Puis on ajoute au script les requêtes de suppression vues en première partie qui se basent sur la table users et les tables associées:
DELETE FROM bans WHERE username IN (SELECT username FROM users WHERE num_posts='0')
DELETE FROM reports WHERE reported_by IN (SELECT id FROM users WHERE num_posts='0')
DELETE FROM subscriptions WHERE user_id IN (SELECT user_id FROM users WHERE num_posts='0')
DELETE FROM users WHERE num_posts='0' AND id != '1'
On conserve l'entrée 1 qui est celle de l'invité, "Guest" en anglais, qui doit toujours rester présente.
Le script de suppression
include("config.php");
$hnd = mysqli_query($db_handler, "SELECT username FROM users");
while($userlist = mysqli_fetch_assoc($hnd))
{
$user = $userlist['username'];
$hndposts = mysqli_query($db_handler, "SELECT * FROM $posts WHERE poster='$user'");
if(mysqli_num_rows($hndposts) == 0)
{
mysql_query("UPDATE users SET num_posts='0' WHERE username='$user'", $db_handler);
}
}
mysql_query("DELETE FROM bans WHERE username IN (SELECT username FROM users WHERE num_posts='0')", $db_handler);
mysql_query("DELETE FROM reports WHERE reported_by IN (SELECT id FROM users WHERE num_posts='0')", $db_handler);
mysql_query("DELETE FROM subscriptions WHERE user_id IN (SELECT id FROM users WHERE num_posts='0')", $db_handler);
mysql_query("DELETE FROM users WHERE num_posts='0' AND id != '1'", $db_handler);
echo "Done!";
A cela on doit ajouter le code de connexion à la base de données, ce qui est inclut dans le script à télécharger...
Télécharger et utiliser
Pour utiliser le script, on le place dans le répertoire racine de fluxBB et on appelle directement le fichier à partir d'un navigateur.
Par exemple:
http://www.monsiteweb.com/forum/killbill.php
Vous pouvez voir ce que fera le script sans modifier quoi que ce soit en activant provisoirement le drapeau DEBUG dans le code source:
$DEBUG = true;
Script de suppression en masse d'utilisateurs sous fluxBB
Le fichier s'appelle killbill.php. Vous pouvez changer ce nom et lui donner un nom personnalisé.
Faites par précaution une sauvegarde de la base de données avec la commande export de PHPMyAdmin ou la fonction de votre panel d'administration, avant la première utilisation.