Come eseguire un 301 reindirizzamento per i post privati invece di un 404?
Come posso reindirizzare con codice 301 le pagine private, invece di mostrarle come 404? Se un post è privato, WordPress lo filtra nella query SQL, quindi non ci sono variabili $post con cui lavorare.
Vorrei che questo codice funzionasse, ma non lo fa:
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;
}
Non so dove questo viene impostato prima di wp
, se non per il fatto che so che è un problema relativo ai ruoli utente. Se potessi impostare un utente non loggato per avere questa capacità, probabilmente risolverei il problema:
$publicReader -> add_cap('read_private_posts');
Il problema con add_cap è che solo gli utenti loggati hanno le capacità.

Scusate ragazzi, ho trovato la mia risposta:
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;
}
I post/pagine vengono rimossi dalle sitemap, ma la pagina viene comunque visualizzata sul sito in modo da poter essere reindirizzata con 301.

Mi sembra che non dovresti restituire né 404 né 301 - dovresti restituire 401 (Non autorizzato / autenticazione richiesta, anche se non accetterai alcuna autenticazione offerta) o 403 (Rifiutato, ovvero so cosa stai chiedendo e non puoi averlo).
C'è un plugin abbandonato Private Page Forbidden che potrebbe valere la pena esaminare per avere indicazioni, anche se a prima vista sembra voler convertire il 404 in 403, il che sembra una cattiva idea. Sfortunatamente, nonostante ci siano state diverse discussioni sulle opzioni (vedi https://core.trac.wordpress.org/ticket/10551 e collegati), la milestone per le correzioni si è gradualmente spostata a "Future Release".

Innanzitutto, devo concordare con la risposta di @fencepost. Tuttavia, non ho potuto resistere alla tentazione di pubblicare una soluzione, ed eccoci qui!
function __intercept_private_page( $posts, &$wp_query )
{
// rimuovi il filtro ora, in modo che nelle successive query sui post non interveniamo!
remove_filter( 'the_posts', '__intercept_private_page', 5, 2 );
if ( !( $wp_query->is_page && empty($posts) ) )
return $posts; // esci, non è una pagina senza risultati
// se vuoi verificare esplicitamente che sia *privata*, usa il blocco di codice sotto:
/*
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' ) {
// reindirizza
}
*/
// altrimenti supponi che se la richiesta era per una pagina e nessuna pagina è stata trovata, era privata
wp_redirect( home_url(), 301 );
exit;
}
is_admin() || add_filter( 'the_posts', '__intercept_private_page', 5, 2 );
Aggiornamento: Codice rivisto per utilizzare il filtro the_posts
invece di posts_results
(che viene attivato prima che WordPress controlli i permessi, quindi $posts
non è ancora stato 'svuotato').
