Habilite los comentarios en la página de vista previa del front-end para publicaciones pendientes

Estamos en el proceso de permitir que los autores colaborativamente sean parte del proceso editorial. Tendrán acceso a todas las páginas de vista previa de las publicaciones pendientes ( no a las páginas posteriores a la edición).

Quiero permitir que estos usuarios publiquen un comentario normal siempre que la publicación esté en post_status pendiente .

Tras la investigación, se ha publicado una solución integral aquí , aunque esa solución solo permite comentarios a través de la página posterior a la edición, no la página de vista previa que estoy buscando.

Solutions Collecting From Web of "Habilite los comentarios en la página de vista previa del front-end para publicaciones pendientes"

Prefacio

Una vez que la vista previa es frontend, el formulario de comentarios depende de cómo lo maneje el tema. comment_form() en esta respuesta que el formulario de comentarios se muestra usando la función estándar comment_form() .

La suposición anterior no es suficiente, de hecho comment_form es probablemente la función en el núcleo de WordPress con más ganchos. Hay casi un gancho para cada línea. Entonces, lo que se muestra en la página depende mucho de los complementos o del tema que pueda cambiarlo.

Después de eso, comment_form use para guardar un comentario de POST a wp-comment-post.php que también contiene muchos ganchos, así que incluso si mi solución funciona en una instalación estándar de WP usando twenty * theme, no puedo asegurar que funcione también con algunos complementos o temas personalizados.

Flujo de trabajo

Entonces, una vez que estamos asumiendo que estamos en un caso estándar, lo que usted pregunta es más simple que la Q / A vinculada, porque la forma de comentario no usa ajax y porque hay muchos ganchos que pueden ayudarnos a obtener el resultado deseado (habló sobre el lado negativo de este punto en el prefacio).

Esencialmente tenemos que:

  1. Agregar un campo en el formulario de comentarios cuando estamos en la vista previa pendiente, de esta manera podemos reconocer un comentario que proviene de ese formulario.
  2. Una vez que tenemos que romper un control de seguridad de WordPress para permitir comentarios sobre la publicación pendiente, es una buena idea reemplazar este cheque con otro: usar un nonce para el campo oculto en el punto 1. puede ser una buena idea.
  3. Como control de seguridad adicional, creo que es una buena idea permitir comentarios solo para usuarios registrados (pero parece que ya está permitiendo el acceso de vista previa solo a usuarios registrados). Probablemente también restringir los roles es una buena idea.
  4. La parte central de este flujo de trabajo es romper el control que WordPress hace para evitar comentarios sobre publicaciones pendientes y de borrador. Mi idea es solo provocar a WordPress dejándolo creer que nuestra publicación está publicada. La forma en que lo haré, puede tomarse como un ejemplo de por qué las variables globales deben evitarse para evitar que nuestro código sea burlado por alguien.
  5. Lo último que tenemos que hacer es interceptar el redireccionamiento después de crear un comentario, porque el punto de redireccionamiento estándar al enlace permanente estándar, debemos apuntar al enlace permanente de la vista previa

El código

Antes que nada, creemos una función que agregue un campo nonce en forma de comentario, solo para usuarios registrados permitidos y solo en la vista previa del post. También escribiré una función para verificar si el usuario actual es uno de los permitidos, de esta forma puedo usarlo para otros ámbitos. En esta función, puse un gancho de filtro personalizado, de esta forma los roles alloewd se pueden cambiar.

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

Ahora bromeemos con WordPress. La forma en que WP usa para verificar si el estado de la publicación es bueno para comentar es llamar a $status_obj = get_post_status_object($status) (donde $status es el campo post_status de la publicación que se está comentando) luego verificar si $status_obj es private o public wp_die . Pero lo único que get_post_status_object hace es devolver un valor de la matriz global $wp_post_statuses (la clave con el estado de la publicación solicitada). Fingir la variable global significa falsificar get_post_status_object y también falsificar la verificación de WordPress.

Cambiar la variable global es muy fácil, sin embargo, haré algunos controles para asegurar que la publicación venga de nosotros (gracias a un campo oculto nonce agregado anteriormente) y también verifica si el usuario actual existe y está 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'); 

Ahora, después de insertar un comentario desde la vista previa de la publicación, tenemos que redirigir el navegador nuevamente para publicar la vista previa. Como de costumbre, aseguramos que la solicitud proviene de una vista previa y el usuario actual tiene uno de los roles permitidos.

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