web-dev-qa-db-fra.com

Activer les commentaires sur la page d'aperçu frontale pour les publications en attente

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.

1
Christine Cooper

Préface

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.

Flux de travail

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:

  1. L'ajout d'un champ dans le formulaire de commentaire lorsque nous sommes sur l'aperçu de publication en attente nous permet de reconnaître un commentaire provenant de ce formulaire.
  2. Une fois que nous devons interrompre une vérification de sécurité de WordPress pour autoriser les commentaires sur le message en attente, il est judicieux de remplacer cette vérification par une autre: utiliser un nonce pour le champ masqué au point 1. peut être une bonne idée.
  3. En tant que vérification de sécurité supplémentaire, je pense qu’il est judicieux d’activer les commentaires uniquement pour les utilisateurs enregistrés (mais vous semblez déjà autoriser l’accès en prévisualisation uniquement aux utilisateurs enregistrés). Probablement aussi restreindre les rôles est une bonne idée.
  4. La partie principale de ce flux de travail est une pause la vérification effectuée par WordPress pour empêcher tout commentaire sur les messages en attente et brouillons. Mon idée est juste de taquiner WordPress en laissant croire que notre message est publié. La façon dont je vais le faire peut être prise comme exemple de la raison pour laquelle les variables globales doivent être évitées pour éviter que notre code ne soit taquiné par quelqu'un.
  5. La dernière chose à faire est d'intercepter la redirection une fois le commentaire créé, car la redirection standard pointe sur permalink standard, nous devons pointer sur post permalink

Le code

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 );
5
gmazzap