Permitir comentar na página de visualização de front-end para postagens pendentes

Estamos no processo de permitir que os autores colaborativamente sejam parte do processo editorial. Eles terão access a todas as páginas de visualização de posts pendentes ( não páginas pós-edição).

Quero permitir que esses usuários publiquem um comentário normal sempre que a publicação estiver no post_status pendente .

Após a pesquisa, uma solução abrangente foi publicada aqui , embora essa solução apenas permita comentar através da página de edição posterior, e não a página de visualização que eu estou procurando.

Solutions Collecting From Web of "Permitir comentar na página de visualização de front-end para postagens pendentes"

Prefácio

Uma vez que a visualização da publicação é frontend, o formulário de comentário depende de como o tema lida com isso. Eu assumirei nesta resposta que o formulário de comentário é mostrado usando a function padrão comment_form() .

O pressuposto anterior não é suficiente, de fato comment_form é provavelmente a function no núcleo do WordPress com mais ganchos. Há quase um gancho para cada linha. Então o que é mostrado na página depende muito dos plugins ou do tema que podem alterá-lo.

Depois disso, comment_form usa para salvar o comentário de um POST para wp-comment-post.php que contém muitos ganchos também, então mesmo que minha solução funcione em uma instalação de vanilla do WP usando o tema de vinte *, não posso garantir que ele funciona também com alguns plugins ou tema personalizado.

Fluxo de trabalho

Então, uma vez que estamos assumindo que estamos em um caso padrão, o que você pergunta é mais simples do que o Q / A vinculado, porque o formulário de comentário não usa ajax e porque há muitos ganchos que podem nos ajudar a obter o resultado desejado (falou sobre o lado negativo deste ponto no prefácio).

Essencialmente, temos que:

  1. Adicionando um campo no formulário de comentário quando estamos na visualização de publicação pendente, desta forma, podemos reconhecer um comentário vindo desse formulário.
  2. Uma vez que temos que quebrar uma verificação de segurança do WordPress para permitir o comentário na postagem pendente, é uma boa idéia replace esta verificação por outra: usar um nonce para o campo oculto no ponto 1. pode ser uma boa idéia.
  3. Como verificação de segurança adicional, acho que é uma boa idéia permitir comentários apenas para usuários cadastrados (mas parece que você já está permitindo o access à visualização somente para usuários cadastrados). Provavelmente também restringir os papéis é uma boa idéia.
  4. A parte central deste stream de trabalho é quebrar a verificação que o WordPress faz para evitar comentários sobre as mensagens pendentes e preliminares. Minha idéia é apenas provocar WordPress, deixando-a acreditar que nossa publicação é publicada. A maneira como eu vou fazer isso, pode ser tomada como um exemplo de por que as variables ​​globais devem ser evitadas para evitar que nosso código seja provocado por alguém.
  5. A última coisa que temos que fazer é interceptar o redirecionamento após o comentário ser criado, porque o ponto de redirecionamento padrão para o permanente permanente de permalink, precisamos apontar para postar o permalink de pré-visualização

O código

Antes de tudo, vamos criar uma function que adicione um campo nonce no formulário de comentário, apenas para usuários registrados permitidos e somente na visualização da publicação. Também escreverei uma function para verificar se o usuário atual é um dos permitidos, desta forma eu posso usá-lo para outros escopos. Nesta function, coloco um gancho de filtro personalizado, desta forma as funções podem ser alteradas.

 /** * 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 ''; } } add_action( 'comment_form_logged_in_after', 'additional_comment_fields'); 

Agora vamos provocar o WordPress. A maneira como o WP usa para verificar se o status da publicação é bom para ser comentado é chamar $status_obj = get_post_status_object($status) (onde $status é o campo post_status da postagem que está sendo comentado) então verifique se $status_obj é private ou public outra forma wp_die . Mas o único que get_post_status_object faz é retornar um valor da matriz global $wp_post_statuses (o único com o status de postagem solicitada). Falhar a variável global significa fingir get_post_status_object e, portanto, também fingir a verificação do WordPress.

Alterar a variável global é super fácil, no entanto, eu farei algumas verificações para garantir que a publicação venha de nós (graças ao campo escondido do nonce anteriormente adicionado) e também verifique se o usuário atual existe e é permitido:

 /** * 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'); 

Agora, depois de um comentário ser inserido a partir da pré-visualização, devemos redirect o navegador novamente para publicar a visualização. Como de costume, asseguramos que a solicitação vem da pré-visualização e o usuário atual possui uma das funções permitidas

 /** * 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 );