Modération des commentaires par les contributeurs

Je cherchais depuis quelques temps un moyen simple de permettre aux auteurs et aux contributeurs d’un blog de pouvoir modérer les commentaires des articles publiés, sans pour autant leur donner le rôle d’éditeurs normalement nécessaire pour cette tâche.

Lache tes coms

En effet, sur les blogs collaboratifs il n’est pas inhabituel de faire appel aux éditeurs pour qu’ils valident les articles proposés avant leur mise en ligne. Pour autant, une fois ces articles publiés, leurs auteurs (qu’ils aient le rôle de contributeur ou d’auteur pour WordPress) n’ont pas les permissions nécessaires pour modérer les commentaires.

Rôles et permissions

WordPress propose par défaut 5 rôles d’utilisateurs, qui définissent chacun un niveau de permissions supplémentaire par rapport au niveau précédent :

  • Abonné (simple lecteur)
  • Contributeur (peut proposer des articles)
  • Auteur (peut publier ses propres articles)
  • Editeur (peut modifier et publier les articles des autres utilisateurs)
  • Administrateur (accède à toutes les options d’administration : réglages, plugins, thèmes …)

Chaque rôle correspond en fait à un jeu de permissions définies dans WordPress, dont vous retrouverez la liste sur le Codex.

Cependant, il est possible de modifier ces rôles et de donner ou de retirer des permissions aux utilisateurs, on l’a déjà vu pour permettre l’upload d’images aux contributeurs. Un plugin assez connu, User Role Editor, permet de réaliser ces modifications sans la moindre ligne de code, directement depuis l’interface d’administration. Mais déployer un plugin aussi lourd me paraissait un peu disproportionné, d’autant qu’il ne répond pas exactement à mes besoins.

Julio de Boite à Web a dévoilé récemment un plugin permettant l’ajout d’un nouveau rôle « Modérateur », qui bien que très intéressant ne me satisfaisait pas : les modérateurs ainsi créés ne peuvent que modérer des commentaires. Cela dit, ça m’a quand même aidé, alors merci à lui :)
Puisque je cherchais à laisser tout de même aux contributeurs et aux auteurs la possibilité de proposer des articles, j’ai donc fouillé un peu plus.

Le début de solution

Une capacité qui pourrait suffire est moderate_comments. Comme son nom l’indique, elle permet la modération des commentaires. Malheureusement, la modération des commentaires est assimilée par le noyau de WordPress à l’édition d’un post (pour rappel, un post dans WordPress peut désigner à la fois un article, une page, une pièce jointe, un type de post personnalisé …).
Pour pouvoir modérer les commentaires, un utilisateur a donc besoin des capacités suivantes (en plus des permissions de base d’un contributeur) :

  • moderate_comments
  • edit_others_posts
  • edit_published_posts

Voilà donc un petit bout de code à insérer dans le fichier functions.php de votre thème, et qui ajoute ces capacités aux contributeurs et aux auteurs :

if ((current_user_can('contributor') || current_user_can('author')) && !current_user_can('moderate_comments'))
	add_action('admin_init', 'dfr_moderate_comments');

function dfr_moderate_comments() {
	$contributor = get_role('contributor');
	$contributor->add_cap('moderate_comments');
	$contributor->add_cap('edit_others_posts');
	$contributor->add_cap('edit_published_posts');
	$author = get_role('author');
	$author->add_cap('moderate_comments');
	$author->add_cap('edit_others_posts');
}

Pour ceux qui ont lu les précédents articles de ce blog, ça ressemble assez fortement à ce qu’on a utilisé pour permettre l’upload de media aux contributeurs. Je vous invite à aller voir l’article correspondant pour quelques explications sur le principe.
On n’a pas ajouté la capacité edit_others_posts au rôle Auteur, tout simplement parce qu’il la possède déjà.

L’astuce

L’ennui, c’est qu’avec toutes ces capacités, un contributeur est en mesure de lire, modifier, publier à sa guise ses articles et ceux des autres. En gros on lui donne les mêmes droits qu’un éditeur, alors qu’il n’est que simple contributeur.

La grosse feinte va donc consister à faire en sorte que lorsqu’un utilisateur cherche à éditer un article, si cet article est déjà publié ou n’est pas un des articles qu’il a proposés, on lui en interdit l’accès avec un autre bout de code à placer dans functions.php :

add_action( 'admin_init', 'dfr_redirect_users' );
function dfr_redirect_users()
{
	// On récupère la page active
	global $pagenow;
	// Si la page active est la page d'édition d'article
	if ($pagenow == "post.php") {
		// Si l'utilisateur n'est pas éditeur ou admin
		if ( !current_user_can( 'editor' ) ) {
			// On récupère l'objet post courant
			$id = $_GET['post'];
			$post = get_post($id);
			// On récupère l'utilisateur courant
			$current_user = wp_get_current_user();
			// Si le post est publié et si l'utilisateur n'en est pas l'auteur
			if ($post->post_status == "publish" && $post->post_author != $current_user->ID)
				wp_redirect( admin_url( 'edit.php' ) );
		}
	}
}

On utilise la variable globale $pagenow (voir la liste des variables globales dans WordPress) qui indique sur quelle page de WordPress nous nous trouvons. Pour le reste, il s’agit de vérifier que notre gentil contributeur ne tente pas d’aller modifier le post d’un autre utilisateur. Attention : il pourra par contre modifier les articles encore hors ligne. Si vous voulez interdire ce comportement, retirez simplement $post->post_status == "publish" de la dernière condition 😉

Le code complet

Pour les feignasses, voilà donc le code complet à placer dans le fichier functions.php de votre thème.

if ((current_user_can('contributor') || current_user_can('author')) && !current_user_can('moderate_comments'))
	add_action('admin_init', 'dfr_moderate_comments');
function dfr_moderate_comments() {
	$contributor = get_role('contributor');
	$contributor->add_cap('moderate_comments');
	$contributor->add_cap('edit_published_posts');
	$author = get_role('author');
	$author->add_cap('moderate_comments');
}
add_action( 'admin_init', 'dfr_redirect_users' );
function dfr_redirect_users()
{
	global $pagenow;
	if ($pagenow == "post.php") {
		if ( !current_user_can( 'editor' ) ) {
			$id = $_GET['post'];
			$post = get_post($id);
			$current_user = wp_get_current_user();
			if ($post->post_status == "publish" && $post->post_author != $current_user->ID)
				wp_redirect( admin_url( 'edit.php' ) );
		}
	}
}

Attention : cette solution n’est évidemment pas optimale, et il est certain qu’une mise à jour de la capacité moderate_comments pour la rendre indépendante d’autres capacités simplifierait le problème.
En attendant, si vous trouvez une façon plus élégante de faire la même chose, n’hésitez pas à partager votre solution dans les commentaires !

Cet article a été publié dans WordPress par . Mettez-le en favori avec son permalien.
  • http://coutant-maxime.fr COUTANT

    Très bonne explication qui peut être bien utile.
    Merci

  • http://www.mariandenys.com Marian

    Très bonne astuce qui va surement me servir pour mes deux trois sites privés. Et surtout une bonne explication du code.

  • http://polifiction.14h30.fr Mathieu

    Toujours au top diije ! Merci pour ce type d’astuces pour « feignasses » que nous sommes.

  • Agence de référencement

    Il serait pas mal d’y ajouter une fonction de mots interdits pour bannir les commentaires automatiquement.
    Laisser la porte ouverte ok. Mais mettre un videur à l’entrée ça peut gérer aussi ^^

  • Christine

    Très bonne explication du code, clair, simple, précis !
    Pour ma part j’utilise le plug-in Akismet, je trouve qu’il est assez bon aussi :)

  • Newsmag

    Suite à un tweet j’ai découvert l’article, et je t’avoue que je me serais pas pris la tête pour des personnes qui spamment sans assumer 😉

    Mais en tout cas joli, il faudrait presque que tu en fasses un plugins téléchargeable

  • Guillaume

    Il me semble qu’il y’a un plugin qui fait ce genre de truc non ? Je me vois mal pour ma part modifier mon code 😀

  • http://www.diije.fr/ Julien Deneuville

    @Guillaume: Entre la lecture très approximative de l’article et l’intérêt assez peu poussé de ton commentaire, tu comprendras que je ne te laisse pas spammer mon blog 😉

  • http://www.boiteaweb.fr Julio Potier (BoiteAWeb)

    Article du 31 mai et je ne reçois le ping que maintenant ! Zut !
    Merci beaucoup de m’avoir cité et pris mon plugin en exemple !
    Ton code est bon aussi, rien à redire, j’adore les articles avec du code 😀

  • https://addons.mozilla.org/fr/firefox/user/6556078/ moi non plus je ne te spamme pas du tout!

    En parlant de commentaires, en voilà un. Tu as vu la dédicace ;-))
    Bon j’avais déjà tweeté ton article, mais pour la peine, je vais recommencer!

  • http://www.diije.fr/ Julien Deneuville

    Puisque c’est toi je valide quand même ;p
    Au passage, le plan est foireux, mais bon …

  • Xav

    Le spamco saÿlemal

  • http://labo.seomix.fr/ Daniel Roch

    Comme le dit Julio, rien à redire sur le code : c’est propre et efficace pour parvenir à ton objectif.

    Après, le fonctionnement de WordPress t’a compliqué la vie mais il est compréhensible : le CMS a besoin de donner les droits d’édition de posts avec moderate_comment car la modération peut se faire aussi directement dans l’admin dans la page de l’article, et pas seulement dans le menu commentaires.

  • Laïka ou Milou

    Une problématique pertinente avec une solution technique fort à propos.
    La gestion des droits étant un sujet sensible et difficile techniquement à gérer puis à mettre en œuvre sous WordPress, merci de nous avoir proposés ta solution et de l’avoir partagée surtout.