Diije

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 !