• Resolved VIPStephan

    (@10010110)


    I’m doing something like this in functions.php

    
    function modify_loop($query) {
      if(!is_admin() && $query->is_main_query()) {
        if($query->is_category(array(7,8,18,23,24)) {
          // stuff
        }
      }
    }
    add_action('pre_get_posts', 'modify_loop');
    

    If I load a non-existant URL on my site like https://example.com/this-page-doesnt-exist it will show the 404 page but with the PHP notice:

    Trying to get property ‘term_id’ of non-object in ~/wp-includes/class-wp-query.php

    Apparently it has something to do with the check for category IDs; without the array in is_category() the error goes away.
    Doing a

    
    var_dump($query->is_category());
    var_dump(is_404());
    

    inside the function it shows true for is_category() and false for is_404(). Why is that?

    I have to add that I have Yoast SEO set to remove the category base from URLs. Perhaps this has something to do with it?

    • This topic was modified 3 years, 10 months ago by VIPStephan.
Viewing 5 replies - 1 through 5 (of 5 total)
  • Moderator bcworkz

    (@bcworkz)

    It’s premature to attempt to use some of the is_*() methods because the query is yet to run. WP doesn’t know if a request goes 404 until it attempts to get posts and finds none. WP has not yet parsed the query vars, so it doesn’t yet know internally what sort of category query is being made. The answer is actually in the query vars, but the query hasn’t yet looked at those. If you want to do something only for certain category requests, check the related query vars.

    For certain types of requests, your code might work OK, but it’s the wrong approach for any possible request.

    Thread Starter VIPStephan

    (@10010110)

    Thanks for your prompt reply, @bcworkz. ?? I think I understand the concept now. So, you are saying I should rather do something like $query->get('cat') and then perform the conditional test on this result?

    Thread Starter VIPStephan

    (@10010110)

    OK, well, apparently a URL like “https://example.com/this-page-doesnt-exist” will only reveal the category_name query variable, because it basically translates to something like “https://example.com/index.php?category_name=this-page-doesnt-exist”, so get('cat') doesn’t bring up anything.

    What I ended up with was retrieving the category ID from the category_name variable and using that to compare against:

    
    function modify_loop($query) {
    	if(!is_admin() && $query->is_main_query()) {
    		$cat_name = $query->get('category_name');
    		$cat_object = get_category_by_slug($cat_name);
    		$cat_id = $cat_object ? $cat_object->term_id : null;
    		if(in_array($cat_id, [7,8,18,23,24]) {
    			// stuff
    		}
    	}
    }
    

    As far as I can tell this works.

    Moderator bcworkz

    (@bcworkz)

    Part of the challenge with query vars is knowing which ones are set for a particular request. What you have is fine. You could however save a query by building an array of category names for checking if $cat_name is in it or not.

    Thread Starter VIPStephan

    (@10010110)

    Yeah, I specifically wanted to avoid using category names because there is always the possibility that the client can change them while the IDs should stay the same. Thanks again, you pointed me in the right direction.

Viewing 5 replies - 1 through 5 (of 5 total)
  • The topic ‘“Trying to get property of non-object” in pre_get_posts’ is closed to new replies.