is_category() in pre_get_posts strange error

I have a function that sets posts_per_page option depending on the category viewed.

I discovered and error which I can’t really understand: first this is how I get the error:

Read More
function custom_posts_per_page($query) {

    if ( !is_admin() && is_category(4)) {

    // Leaving this empty or with content

    }

}

add_filter( 'pre_get_posts', 'custom_posts_per_page' );

So I get an error there if WP_Debug is turn to true and when I access a non-exixting category.
So if I enter http://localhost/zz/category/uncategorized there is no problem but if I enter for example http://localhost/zz/category/aaaaaaaa (Category aaaaaaaa doesn’t exist), It gets correctly to the 404 page but throws these errors:

Notice:  Trying to get property of non-object in C:xampphtdocszzwp-includesquery.php on line 3420
Notice:  Trying to get property of non-object in C:xampphtdocszzwp-includesquery.php on line 3422
Notice:  Trying to get property of non-object in C:xampphtdocszzwp-includesquery.php on line 3424

What is wrong?

Related posts

1 comment

  1. After a bit of investigation…

    If you pass a category to is_category it uses get_queried_object to grab data– see the source. get_queried_object returns NULL for categories that do not exist. You can demonstrate that with:

    function custom_posts_per_page($query) {
      var_dump(get_queried_object());
    }
    add_filter( 'pre_get_posts', 'custom_posts_per_page' );
    

    Load a valid category archive and then an invalid one.

    The is_category method does not check to see whether it has a valid object before trying to use that object, hence the error. I would definitely consider that a bug.

    The only way I see around it is to check for the existence of the category first:

    function custom_posts_per_page($query) {
    
        if ( !is_admin() && term_exists(4,'category') && $query->is_category(4)) {
    
        // Leaving this empty or with content
    
        }
    
    }
    
    add_filter( 'pre_get_posts', 'custom_posts_per_page' );
    

    Or handle the logic yourself:

    function custom_posts_per_page($query) {
    
        if ( !is_admin() && $query->is_category()) {
          $qobj = get_queried_object();
          if (!empty($qobj)
            && (isset($qobj->taxonomy) && 'category' == $qobj->taxonomy && 4 == $qobj->term_id)
          ) {
            var_dump($qobj);
          }
        // Leaving this empty or with content
    
        }
    
    }
    
    add_filter( 'pre_get_posts', 'custom_posts_per_page' );
    

    Barely tested. Possibly buggy. Caveat emptor. No refunds.

Comments are closed.