Weird problem with pre_get_posts and $query->is_page()

The following bit of code was used in my fictitious plugin to redirect the non-logged-in users from page 173 (ID) to sample-page (slug). The code’s working well. But just today, I figured out that the code is causing Notices in Firefox.

The issue happened when I tried setting a Static Page as the front page from Settings » Reading.

Notice: Trying to get property of non-object in
/wp-includes/class-wp-query.php on line 3760
Notice: Trying to get property of non-object in
/wp-includes/class-wp-query.php on line 3762
Notice: Trying to get property of non-object in
/wp-includes/class-wp-query.php on line 3764

With several inspection, I figured out that, the following bit of code is causing the issue. And to be specific the issue is with the is_page(173).

add_action('pre_get_posts', function($query) {
  if( $query->is_main_query() && ! is_admin() && ! is_user_logged_in() && $query->is_page(173) ) {
    wp_redirect(home_url('/sample-page'));
    exit();
  }
});

I tried changing from $query->is_page(173) to is_page(173) – the result is same.

To test in a blank installation, I tried disabling all the plugins and set the default theme TwentySixteen, and re-installed WordPress to get a fresh install. I put the following code in TwentySixteen’s functions.php, and with DEBUG on, here’s what I got. (The notice is under the black area of header, just hit Ctrl + A to see ’em) You can check the redirection is working from this page (173) to this page without any notice.

What’s the problem with my code?

2 Answers
2

pre_get_posts is innapropriate for this use, instead you should use the template_redirect filter, e.g.

add_action( 'template_redirect', funnction() {
    if ( ! is_user_logged_in() && is_page( 123 ) ) {
        wp_safe_redirect( home_url( '/sample-page' ) );
        exit;
    }
} );

Leave a Comment