How to redirect (301) trashed post to it's parent taxonomy TERM ARCHIVE instead of 404 page

I have a taxonomy called "Sports", that includes terms: Football, Rugby, Tennis... What I want to achieve is when (for instance) a post that has the term football is trashed and a visitor try access it, it will be redirected to (for SEO purpose): mywebsite.com/sports/football/ .

I spent many days trying to figure how to do this but in vain. Here is an example of codes I tried:

    function redirect_trashed_posts(){
    if( is_404() ){

        global $wp_query, $wpdb, $post;

        $post_id = $post-ID;

        if( is_object_in_term( $post_id, 'sports' ) ) {

            $terms = get_the_terms( $post_id, 'sports' );
            $term = array_shift( $terms );
            $slug = $term-slug;

            $redirect_to = get_option('siteurl') . '/sports/' . $slug . '/';
            wp_redirect( $redirect_to, 301 );
            exit();
        }
    }
}
add_action('template_redirect', 'redirect_trashed_posts');

The main issue is that I can't get the ID of the trashed post and as a consequence the if statement to check if the post belong to "sports" is not working and the "get_the_terms()" returns nothing. I also tried to get data by slug but It did not succeed.

Thanks for your help.

SOLUTION

function redirect_trashed_posts(){
    if( is_404() ){ // if page does not exist anymore

        global $wpdb; // so we can talk to db

        // getting current slug__trashed
        // WP append __trashed to trshed posts
        $trashed_post_slug = trim($_SERVER['REQUEST_URI'], '/') . '__trashed'; 

        $post_data = $wpdb-get_row( // requesting ID  post_status from DB
            "
            SELECT ID, post_status
            FROM $wpdb-posts
            WHERE post_name = '$trashed_post_slug'
            "
        );

        $post_id = $post_data-ID; // Getting the ID
        $post_status = $post_data-post_status; // Grabbing the post_status

        if ( $post_status == 'trash'){ // if we are currently on a trashed post
            $terms = get_the_terms( $post_id, 'sports'); // Getting Term, it's an array of objects
            $term = array_shift( $terms ); // Getting first object. I have just one 
            $term_slug = $term-slug; // Getting term slug
            $redirect_to = get_option('siteurl') . '/sports/' . $term_slug . '/'; // full url
            wp_redirect( $redirect_to, 301 ); // 301 redirection
            exit();
        }

    }
}
add_action('template_redirect', 'redirect_trashed_posts');

Thanks :D

Topic get-the-id template-redirect functions php Wordpress

Category Web


Try something like

$post_id = url_to_postid($_SERVER['REQUEST_URI']);

Might need some tweaking: might need 'HTTP_REFERER' instead of 'REQUEST_URI'; might need to append the protocol and the domain to the string passed to url_to_postid().

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.