Wordpress - How to 301 private posts rather than 404?

Sorry guys, I found my answer:

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;
}

Posts/Pages are removed from the sitemaps, but the page still shows up on the site so that it can get 301'd.


Firstly, I would have to agree with @fencepost's answer. However, I couldn't resist posting a solution, so here we are!

function __intercept_private_page( $posts, &$wp_query )
{
    // remove filter now, so that on subsequent post querying we don't get involved!
    remove_filter( 'the_posts', '__intercept_private_page', 5, 2 );

    if ( !( $wp_query->is_page && empty($posts) ) )
        return $posts; // bail, not page with no results

    // if you want to explicitly check it *is* private, use the code block below:   
    /*
        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' ) {
            // redirect
        }
    */

    // otherwise assume that if the request was for a page, and no page was found, it was private
    wp_redirect( home_url(), 301 );
    exit;
}
is_admin() || add_filter( 'the_posts', '__intercept_private_page', 5, 2 );

Update: Revised code to use the_posts filter instead of posts_results (which fires before WordPress checks permissions, and so $posts hasn't been 'emptied' yet).