PHP Ninja? Can anyone figure this line of logic out?

I’m building a Wordpress based site up and I’m using a plugin called Widget Logic to load sidebar content (ads in this case) dependent upon the category a post belongs to.

For example, this is the code I have at present for any post that belongs to a category with an ID of 31:

is_category(31) || is_single() && in_category(31)

I have a widget like this in place for every category so ads can be inserted specific to each category. This is working great except that if a post is in 2 or more categories, it is getting the ads for each category it belongs to and loading them one after another - leading to two lots of adverts…

Does anyone know of a way to amend the PHP logic so the widget only shows if the post belongs to a single category only?

I had spoken to the widget author and another skilled PHP’er who had recommended using the following:

global $post; $cats = wp_get_object_terms( $post->ID, 'category' ); if( count( $cats ) > 1 ) return false; return ( is_category( 26 ) || is_single() && in_category( 26 ) );

The plain english version of this logic hopefully being:

How many categories does this post belong to? If more than 1, don’t show the widget. If only 1 category, check if the post is in this category and if so, display the widget. If not, don’t show the widget.

However, using this code I don’t see any adverts - anyone know why?

Glancing at the WP Function Codex (IE: I am NOT a Wordpress coder), this reads to me as:

Get Global Reference: $post (Object, Type Unknown)
Define $cats with results of wp_get_object_terms
Return Type Unspecified (Array? String? Object -> WP_ERROR?)
If Count of element (that may or may not be an array) is greater than 1, return false.
Return the Boolean Logic of:
You’re Viewing the Category Page for category 26 OR
You’re Viewing an individual post AND
The post is in Category 26.

Now. Let me say this.

A || B && C is only true if A or B is true AND C is true.
A || (B && C) is true if A is true OR B and C are true.

So unless i’m wrong about the functions:
Category view:
is_category: true
is_single: false
in_category: false
Result: False.

Post view:
is_category: false
is_single: true
in_category: true*
Result: true.

  • Assuming the post is -directly- in category 26, not relatively through it’s parents. If it’s an indirect ownership, this evaluates to false.

Hi StarLion, thanks for coming back so quickly. Yes, everything you have said is correct as I understand it also. However, I am pretty much a beginner with PHP.

However, the problem is, if I view a post, in a single category, which is a direct descendant of that category, the widget still doesn’t show.

On what you have just written, that would match your criteria:

Post view:
is_category: false
is_single: true
in_category: true*
Result: true.

However, nothing shows which is what now has me so puzzled. Someone had suggested trying this in:

$cats = wp_get_object_terms( $post->ID, 'category' );
echo '<pre>';
print_r( $cats );
echo '</pre>';

But again nothing shows in the source. Any further thoughts?

“Nothing shows”… wait… you mean NOTHING? as in, white-screen-of-ive-got-a-syntax-error-somewhere nothing? Or Nothing as in “I cant even see my <pre> tags” or nothing as in “There’s nothing between my pre tags”

Hi StarLion, sorry, poor explanation. Not a whitescreen. I mean that nothing appears where the widget should appear, given the fact it seems to meet the logic. The rest of the page renders just fine.

the <pre> tags render with nothing between? Then we know where the problem is. wp_get_object_terms( $post->ID, ‘category’ ); is returning false or null.

does $post->ID exist? echo that out. also change your print_r to a var_dump so we can see what exactly is inside that variable.

OK, I think I’m following your logic…

I’ve tried this in there:

$cats = wp_get_object_terms( $post->ID ); echo '<pre>'; var_dump( $cats ); echo '</pre>';

Is that what you mean?

Also, as someone elsewhere had suggested I needed to use global $post I also tried:

global $post; $cats = $post->ID; echo '<pre>'; var_dump( $cats ); echo '</pre>';

But nothing is coming through. PHP has me stumped at the best of times but I’m a little perplexed why nothing is coming through at all!

again “nothing”… please be specific. Do the <pre> and </pre> show up? If no, you’ve got issues before this point.

Page renders but nothing displays where the widget should be. However think this method of troubleshooting is actually futile. I think the widget logic WordPress › Widget Logic « WordPress Plugins only actually allows true or false. If the widget logic statement is true it shows the widget it’s associated with. If it isn’t true it doesnt. So it won’t do a var_dump anyway. Mmmm. So perhaps I need to try these things in the functions.php instead…

OK, tried sticking this in functions.php instead:

$cats = wp_get_object_terms( $post->ID, 'category' ); echo '<pre>'; var_dump( $cats ); echo '</pre>';

And here is the code I get back:

array(0) {
}

But I’m afraid I’m not sure what that actually tells me? Is that saying the item doesn’t seem to have a category?

depends on when $post is getting set. if $post isnt set by the time your script executes, all it tells you is that your code is in the wrong place :wink:

var_dump $post and see if it has in it what you think it has in it.