Cómo redirigir 301 posts privados en lugar de mostrar 404
¿Cómo puedo redirigir páginas privadas con código 301 en lugar de mostrar error 404? Cuando un post es privado, WordPress lo filtra en la consulta SQL, por lo que no hay variables $post disponibles para trabajar.
Me gustaría que este código funcionara, pero no lo hace:
add_action('wp','redirect_stuffs', 0);
function redirect_stuffs(){
global $post;
if ( $post->post_status == "private" && !is_admin() ):
wp_redirect("http://dangayle.com/",301);
exit();
endif;
}
No sé dónde se establece esto antes que wp
, aparte de que sé que es un problema de roles de usuario. Si pudiera establecer que un usuario no registrado tenga esa capacidad, probablemente resolvería el problema:
$publicReader -> add_cap('read_private_posts');
El problema con add_cap es que solo los usuarios registrados tienen capacidades.

Lo siento chicos, encontré mi respuesta:
add_action('wp','redirect_stuffs', 0);
function redirect_stuffs(){
global $wpdb;
if ($wpdb->last_result[0]->post_status == "private" && !is_admin() ):
wp_redirect( home_url(), 301 );
exit();
endif;
}
Las entradas/páginas son eliminadas de los mapas del sitio, pero la página aún aparece en el sitio para que pueda ser redirigida con un 301.

Me parece que no deberías devolver ni 404 ni 301, sino más bien 401 (No autorizado / se requiere autenticación, aunque no aceptarás ninguna autenticación que se ofrezca) o 403 (Rechazado, es decir, sé lo que estás pidiendo y no puedes tenerlo).
Existe un plugin abandonado Private Page Forbidden que podría valer la pena revisar como guía, aunque a primera vista parece querer convertir 404 en 403, lo cual parece una mala idea. Lamentablemente, aunque ha habido diversas discusiones sobre opciones (ver https://core.trac.wordpress.org/ticket/10551 y relacionados), el hito para las correcciones se ha movido gradualmente a "Versión Futura".

En primer lugar, debo estar de acuerdo con la respuesta de @fencepost. Sin embargo, no pude resistir la tentación de publicar una solución, ¡así que aquí estamos!
function __intercept_private_page( $posts, &$wp_query )
{
// Eliminar el filtro ahora, para que en consultas posteriores de entradas no nos involucremos
remove_filter( 'the_posts', '__intercept_private_page', 5, 2 );
if ( !( $wp_query->is_page && empty($posts) ) )
return $posts; // Salir, no es una página sin resultados
// Si deseas verificar explícitamente que *es* privada, usa el bloque de código a continuación:
/*
if ( !empty( $wp_query->query['page_id'] ) )
$page = get_page( $wp_query->query['page_id'] );
else
$page = get_page_by_path( $wp_query->query['pagename'] );
if ( $page && $page->post_status == 'private' ) {
// redireccionar
}
*/
// De lo contrario, asumir que si la solicitud era para una página y no se encontró ninguna, era privada
wp_redirect( home_url(), 301 );
exit;
}
is_admin() || add_filter( 'the_posts', '__intercept_private_page', 5, 2 );
Actualización: Código revisado para usar el filtro the_posts
en lugar de posts_results
(que se activa antes de que WordPress verifique los permisos, por lo que $posts
aún no se ha "vaciado").
