Redirect Restricted Page to 404

Is there a way to show a 404 page if the current logged in user does not have the right clearance to view the page? I am looking for a PHP method, something like

if( !current_user_can('administrator') ) { show_404(); exit(); }

I have thought about using a redirect, but I would like to keep the url the same.

Related posts

Leave a Reply

4 comments

  1. I was able to display a 404 error by using the following code in my header.

    <?php
      global $wp_query;
      $wp_query->set_404();
      status_header( 404 );
      get_template_part( 404 ); exit();
    ?>
    

    To break it down:
    $wp_query->set_404(): tells the wp_query this is a 404, this changes the title
    status_header(): sends a HTTP 404 header
    get_template_part(): displays the 404 template

  2. Why don’t you create a page that show error message and then redirect user to that page? Here is a simple way to achieve that:

    Open the 404.php file and add these lines to the top of it:

    /**
     * Template Name: 404 Page
     */
    

    Create a page with 404 Page template. Then redirect users:

    if ( !current_user_can('administrator') ) {
        $404_page = get_permalink( $404_page_id );
        wp_redirect( $404_page );
        exit();
    }
    

    The reason you should use a page for 404 request is: in WP 404 page actually is a page that doesn’t exists, WP has to search for all of its content before returning the 404 page and that work is a waste of resource. Using a pre-configured page that might help you run your blog faster.

  3. I had a similar requirement where I should not let users access the author.php page based on the role a user was in. I register the template_redirect action to do my checks and redirect to 404 page even before the actual page is loaded.

    Registration:

    add_action( 'template_redirect', [ $this, 'handle_inactive_users']);
    

    Handler:

    public function handle_inactive_users() {
        global $wp_query;
        if ( $wp_query->is_author() ) {
            $user = $wp_query->get_queried_object();
            if ( is_a( $user, WP_User::class ) && $user->has_cap( 'inactive' ) ) {
                $wp_query->set_404();
                status_header( 404 );
                get_template_part( 404 );
                exit();
            }
        }
    }
    

    If you chose to only use the following code snippet in the middle of template part, the page may have already been rendered partially and you are not actually redirected to a 404 page. So better to do it in the template_redirect action –

    $wp_query->set_404();
    status_header( 404 );
    get_template_part( 404 );
    exit();