Supprimer les liens de spam dans les commentaires

Le code snippet du jour permet de supprimer automatiquement les liens contenus dans les commentaires en fonction de la longueur du message et de l’ancienneté de l’article.

Pourquoi filtrer les liens dans les commentaires ?

Si vous avez un blog avec des visiteurs réguliers, vous vous êtes certainement rendu compte que la modération des commentaires prend un certains temps. L’idée d’automatiser le processus de modération est donc assez logique : laissons WordPress supprimer les spams postés par des robots, et passons notre temps à écrire des articles et répondre aux vrais messages, c’est plus intéressant !

Notre CMS met à disposition quelques réglages pour filtrer l’approbation d’un commentaire, dans la partie « Réglages → Discussion » de l’administration :

Par défaut, il est possible de :

  • Définir si l’on active ou pas les commentaires ;
  • choisir qui peut commenter (seulement les utilisateurs enregistrés ?) ;
  • dire si l’on supprime la possibilité de commenter X jours après la publication de l’article ;
  • activer une modération manuelle pour l’ensemble des commentaires ;
  • … ou choisir d’approuver automatiquement les messages d’un utilisateur régulier ;
  • définir une liste noire de « mots » – s’ils se trouvent dans le contenu d’un message celui-ci sera soumis à  une validation manuelle ;
  • blacklister les commentaires contenant au delà d’un certains nombre de liens.

En plus de ces réglages, il est possible d’installer des barrières anti-spams supplémentaires telles que le plugin Akismet qui filtre les spams connus de sa base de données. C’est très efficace pour bloquer les spams de type site coquin, viagra ou pilules… (sur Wabeo, Akismet à déjà bloqué 384 235 messages, merci à lui ????)

L’astuce de développement du jour correspond à un autre système de filtrage que j’ai souhaité mettre en place sur mon site. Je n’aime pas modérer manuellement les commentaires, ça prend du temps que je pourrais utiliser autrement. Et en même temps ça m’embête de laisser passer des liens spammy dans les commentaires du type :

Coucou, super cet article ! Merci pour le partage 😉
– par site-immobilier <http://creation-site-immo.truc>

Ce qui me gène ici, c’est le ratio « 8 mots, 1 lien »…
Si on valide ça tel quel, la section commentaires aura vite fait de devenir une ferme de backlinks ; Autant de liens qui viendront diluer le jus SEO de votre article, et probablement affaiblir le maillage interne de votre site.

Autoriser les liens en fonction de la longueur du commentaire

Un lien, ça se mérite ! L’idée est de permettre au rédacteur d’un commentaire de déposer un lien (lien sur son nom inclus) pour 50 mots écrits. S’il écrit un message plus court, les balises <a/> disparaitront de son texte, et les possibles ancres-URLs perdront leur http://. Nous allons aussi fixer une limite à 3 liens maximum, il ne faut pas abuser…

Ce petit bout de code PHP filtre le contenu d’un commentaire juste avant qu’il ne soit enregistré en base de données. Si l’utilisateur n’est pas enregistré, alors on compte le nombre de mots, on déduit le quotas de liens autorisés et on supprime les balises <a/> au delà.

<?php
add_filter( 'preprocess_comment', 'willy_filter_links_in_comments' );
function willy_filter_links_in_comments( $commentdata ) {
	// bypass registred users
	if ( $commentdata['user_id'] ) {
		return $commentdata;
	}

	// Déduire le nombre de liens autorisés selon le nombre de mots
	$max = 3;
	$words_per_link = 50;
	$words = str_word_count( strip_tags( $commentdata['comment_content'] ) );
	$allowed_links = ( $max < $count = floor( $words / $words_per_link ) ) ? $max : $count;
    
	// Supprimer les lien sur `comment_author_url`
	if ( $allowed_links && ! empty( $commentdata['comment_author_url'] ) ) {
		$allowed_links--;
	} else {
		$commentdata['comment_author_url'] = false;
	}
	// La regex qui trouve les liens
	$re = '/<a[^>]*>([\s\S]*?)<\/a>/mi';
	// Supprimer les liens dans `comment_content`
	if ( preg_match_all( $re, $commentdata['comment_content'], $links )
	  && count( $links ) > $allowed_links ) {
	  	$commentdata['comment_content'] = preg_replace_callback( $re,
			function( $link ) use ( &$allowed_links ) {
				if ( $allowed_links ) {
					$allowed_links--;
					return $link[0];
				} else {
					return preg_replace( '/^https?:\/\//', '', $link[1] );
				}
			},
			$commentdata['comment_content']
		);
	}
	return $commentdata;
}

Vous pouvez bien sûr changer les variables $max et $words_per_link pour adapter les règles  de modération selon vos préférences.

Vos autres options de modérations en place resteront actives mais la suppression des liens auta lieu légèrement en amont.

Supprimer la possibilité de poster des liens sur les vieux articles

Les commentaires des articles ayant un peu d’ancienneté sont souvent un terrain propice au spam. Personnellement cela me gène de fermer complètement les commentaires, mais j’estime que le partage de lien sur un article de plus de 6 mois n’a pas d’intérêt (autre que le dépôt d’un backlink, ????).

Je vous propose de compléter la fonction précédente avec une condition pour vérifier l’âge de l’article sur lequel est posté le commentaire. Ici, s’il a été publié il y a plus de six mois (6 * MONTH_IN_SECONDS), alors on fixe le quota de liens tolérés à 0.

<?php
/**
 * Filter links in comments
 */
add_filter( 'preprocess_comment', 'willy_filter_links_in_comments' );
function willy_filter_links_in_comments( $commentdata ) {
	// Ne pas filtrer les liens des utilisateurs enregistrés
	if ( $commentdata['user_id'] ) {
		return $commentdata;
	}

	// Vérifier la date
	$comment_post = get_post( intval( $commentdata['comment_post_ID'] ) );
	$date = ! empty( $commentdata['comment_date_gmt'] ) ? $commentdata['comment_date_gmt'] : current_time( 'mysql', 1 );
	$post_age = strtotime( $date ) - strtotime( $comment_post->post_date_gmt );
	// Si l’article est vieux, ne pas autoriser les liens
	if ( 6 * MONTH_IN_SECONDS > $post_age ) {
		$allowed_links = 0;
	} else {
		// Sinon, déduire le nombre de liens autorisés selon le nombre de mots
		$max = 3;
		$words_per_link = 50;
		$words = str_word_count( strip_tags( $commentdata['comment_content'] ) );
		$allowed_links = ( $max < $count = floor( $words / $words_per_link ) ) ? $max : $count;
	}

	// Supprimer les lien sur `comment_author_url`
	if ( $allowed_links && ! empty( $commentdata['comment_author_url'] ) ) {
		$allowed_links--;
	} else {
		$commentdata['comment_author_url'] = false;
	}

	// La regex qui trouve les liens
	$re = '/<a[^>]*>([\s\S]*?)<\/a>/mi';
	// Supprimer les liens dans `comment_content`
	if ( preg_match_all( $re, $commentdata['comment_content'], $links )
	  && count( $links ) > $allowed_links ) {
	  	$commentdata['comment_content'] = preg_replace_callback( $re,
			function( $link ) use ( &$allowed_links ) {
				if ( $allowed_links ) {
					$allowed_links--;
					return $link[0];
				} else {
					return preg_replace( '/^https?:\/\//', '', $link[1] );
				}
			},
			$commentdata['comment_content']
		);
	}

	return $commentdata;
}

J’ai écris cette petite astuce pour les besoins de mes sites, et je me suis dit que je pourrai vous en faire profiter. L’article explique donc comme cela fonctionne et donne des pistes pour comprendre comment intervenir sur la modification de commentaires. Mais, plutôt que de vous obliger à déposer ce code dans un plugin ou dans votre thème, je me suis dit que cela serait plus simple de vous fournir directement un plugin.

Le plugin Advanced Remove Links in Comments est donc disponible sur le répertoire officiel des extensions WordPress.

La base est identique avec le code ci-dessus, mais j’ai ajouté des options dans le menu « Réglages → Discussion » pour pouvoir changer les conditions de modération plus simplement. Les fonctions de l’extension sont aussi légèrement optimisées. Si ce plugin vous plait, n’hésitez pas à laisser un avis ou faire un don.

Voilà, j’espère que cette astuce vous aidera à modérer plus simplement vos commentaires, et vous permettra de comprendre un peu mieux comment il est possible d’utiliser les filtres du cœur de WordPress ????

À bientôt !

5 commentaires
Ludovic, il y a 5 mois
Je trouve ton idée très bonne pour éviter que les commentaires ne soient remplis de liens. En revanche, les liens contenus dans les commentaires ont un impact minime sur le SEO du site car WordPress leur ajoute automatiquement l’attribut rel="nofollow" 😉
Willy Bahuaud, il y a 5 mois
Merci !
En fait les attributs nofollow permettent de ne pas transmettre de popularité aux pages ciblés par les liens. Ils ont donc été largement utilisés pour faire du « pagerank sculpting » (la popularité non transférée étant redistribuée sur les autres liens de la page). En 2009, et pour mettre fin à cette pratique, Google a décidé de ne plus redistribuer la popularité des liens en nofollow. Le « jus » part donc aux oubliettes…
D’où mon envie de supprimer les liens inutiles 😛
Amauri, il y a 5 mois
Sympa comme idée 🙂

Ton exemple de commentaire m’en donne une autre:
– filtrer les noms avec une liste de mots clés

On voit beaucoup de « agence immobilière », « code promo », .. commenter et tenter d’avoir un lien ancré tout en ayant un commentaire qui passe entre les filtres.

A moins que le fonction de liste noire de WP cherche aussi dans le nom?

Loic, il y a 5 mois
Bonjour Willy,
bravo pour tes conseils et plugins. Effectivement, j’en ai bien besoin car mon site est submergé de commentaires ( plus de 3500 en attente de modération!! !!) et j’ai beaucoup de mal et perte de temps pour les filtrer manuellement… d’autant plus que beaucoup sont des spams – certains provenant de sites chinois ou russes écrits en langue locale. Rien à voir avec mon site.
Merci pour ton expérience partagée.
Loic
Samuel, il y a 3 semaines
Salut Willy,
ton plugin est le bienvenu car cela me gêne de fermer les commentaires au bout de 15 jours à cause du spam. En effet mon site est également en dofollow car je trouve ça beaucoup plus dans l’esprit du net mais pour éviter le spam je fermais les coms au delà d’un certain délai. Avec ce plugin je vais pouvoir ré-ouvrir les coms c’est cool, certains articles sont toujours d’actualité en dépit de leur âge vénérable! ;)

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Publié le 02 novembre 2016
par Willy Bahuaud
Catégorie Développement WordPress, Référencement naturel