Nous sommes en train de permettre aux auteurs de participer de manière collaborative au processus éditorial. Ils auront accès aux pages de prévisualisation de tous les messages en attente ( et non pages de post-édition).
Je souhaite autoriser ces utilisateurs à poster un commentaire normal chaque fois que l'article est dans en attente post_status
.
Après recherche, une solution complète a été publiée ici , bien que cette solution n'autorise que les commentaires via la page de post-édition, pas la page d'aperçu que je cherche. pour.
Une fois que l'aperçu de la publication est frontend, le formulaire de commentaire dépend de la manière dont le thème le gère. Je supposerai dans cette réponse que le formulaire de commentaire est affiché à l'aide de la fonction standard comment_form()
.
L'hypothèse précédente ne suffit pas, en fait, comment_form
est probablement la fonction dans le noyau de WordPress avec plus de points d'ancrage. Il y a presque un crochet pour chaque ligne. Donc ce qui est montré sur la page dépend beaucoup des plugins ou des thèmes qui peuvent le changer.
Après cela, comment_form
utilise pour enregistrer un commentaire POST
à wp-comment-post.php
qui contient également beaucoup de crochets, donc même si ma solution fonctionne sur une installation Vanilla de WP avec vingt * thèmes, je ne peux pas en assurer le fonctionnement aussi avec des plugins ou des thèmes personnalisés.
Donc, une fois que nous supposons être dans un cas standard, ce que vous demandez est plus simple que le Q/A lié, car le formulaire de commentaire n'utilise pas ajax et parce qu'il y a beaucoup de crochets qui peuvent nous aider à obtenir le résultat souhaité. (a parlé de côté négatif de ce point dans la préface).
Nous devons essentiellement:
Tout d'abord, créons une fonction qui ajoute un champ nonce dans le formulaire de commentaire, uniquement pour les utilisateurs enregistrés autorisés et uniquement dans l'aperçu de publication. Je vais également écrire une fonction pour vérifier si l'utilisateur actuel est l'un des utilisateurs autorisés. De cette manière, je peux l'utiliser pour d'autres portées. Dans cette fonction, je mets un crochet de filtre personnalisé, de cette façon, les rôles alloewd peuvent être modifiés.
/**
* Return true if user can comment on post preview
*/
function is_a_preview_commenter() {
// change this roles according to your needs
$roles = array('administrator', 'editor', 'author', 'contributor');
$allowed_roles = apply_filters('preview_comment_allowed_roles', $roles);
$user = wp_get_current_user();
$inrole = array_intersect($user->roles, $allowed_roles);
return ! empty( $inrole );
}
/**
* Add a nonce field for comment form in post preview for allowed users
*/
function additional_comment_fields() {
if ( is_preview() && is_a_preview_commenter() ) {
$nonce = wp_create_nonce('comment_preview');
echo '<input type="hidden" name="check_the_preview" value="' . $nonce . '" />';
}
}
add_action( 'comment_form_logged_in_after', 'additional_comment_fields');
Allumons maintenant WordPress. La méthode utilisée par WP pour vérifier si le statut de la publication peut être commenté consiste à appeler $status_obj = get_post_status_object($status)
(où $status
est le champ post_status
de la publication en cours de commentaire), puis à vérifier si $status_obj
est private
ou public
sinon wp_die
. Mais la seule chose que get_post_status_object
fait est de renvoyer une valeur du tableau global $wp_post_statuses
(celle qui est associée au statut de publication demandé). Simuler la variable globale signifie simuler get_post_status_object
et donc simuler un contrôle WordPress.
Changer la variable globale est super facile, mais je vais faire quelques vérifications pour nous assurer que la publication nous parvient (grâce au champ masqué nonce précédemment ajouté) et vérifier également si l'utilisateur actuel existe et est autorisé:
/**
* On 'wp_loaded', when the current page is wp-comments-post.php, check if the request
* comes from post preview, if so and also the current user is allowed replace
* $GLOBALS['wp_post_statuses']['pending'] with $GLOBALS['wp_post_statuses']['publish']
*/
function fake_public_pending() {
global $pagenow;
if ( $pagenow === 'wp-comments-post.php' && is_a_preview_commenter() ) {
$nonce = filter_input(INPUT_POST, 'check_the_preview', FILTER_SANITIZE_STRING);
if ( empty($nonce) || ! wp_verify_nonce($nonce, 'comment_preview') ) return;
global $wp_post_statuses;
// let WordPress believe all pending posts are published post
$wp_post_statuses['pending'] = $wp_post_statuses['publish'];
}
}
add_action('wp_loaded', 'fake_public_pending');
Maintenant, après l’insertion d’un commentaire à partir de l’aperçu de la publication, nous devons rediriger le navigateur pour publier la prévisualisation. Comme d’habitude, nous assurons que la demande provient de l’aperçu après publication et que l’utilisateur actuel a l’un des rôles autorisés.
/**
* After a comment is inserted, redirect page to post preview when request come from
* post preview. Also check if current user role is one of the allowed
*/
function redirect_to_preview( $comment, $user ) {
if ( ! is_a_preview_commenter() ) return;
$nonce = filter_input(INPUT_POST, 'check_the_preview', FILTER_SANITIZE_STRING);
if ( empty($nonce) || ! wp_verify_nonce($nonce, 'comment_preview') ) return;
$link = get_permalink($comment->comment_post_ID);
$url = add_query_arg( array('preview' => 'true'), $link );
wp_safe_redirect("{$url}#comment-{$comment->comment_ID}", 302);
exit();
}
add_action('set_comment_cookies', 'redirect_to_preview', 9999, 2 );