I've got myself into a little pickle, and while I'm so close, my understanding of PHP is letting me down.
I want to display the image associated with each category in the menu - working from the answer over here I needed to make that code work with a custom taxonomy as I'm working with woocommerce product categories. I should add that my use case is fairly narrow, so I stripped much of the original answer away to focus on this product category image.
First I add all this to the menu.
<?php add_filter('wp_nav_menu_args', 'add_filter_to_menus');
function add_filter_to_menus($args) {
add_filter( 'wp_setup_nav_menu_item', 'filter_menu_items' );
return $args;
} ?>
The next bit is the problematic stuff...
<?php
function filter_menu_items($item) {
// if the menu item is taxonomy
if( $item->type == 'taxonomy') {
// explicitly set the category for now
$cat_base = 'product-category';
// strip away everything except the term path
$cat_path = str_replace(home_url().'/'.$cat_base.'/', '', $item->url);
// get the term object by using the slug
$term = get_term_by('slug', $cat_path, 'product_cat');
// get the term id from the object
$term_id = $term->term_id;
// $term_array = get_object_vars($term);
// echo '<pre>'; var_dump( $term ); echo '</pre>';
$thumbnail_id = get_woocommerce_term_meta( $term_id, 'thumbnail_id', false );
$image = wp_get_attachment_url( $thumbnail_id );
if( !empty($image) ) {
$item->title = $item->title . '<span class="menu-image"><img src="' . $image . '" alt=""></span>';
}
}
} ?>
Im having a problem getting the $term_id
from the $term
object. I get a notice Trying to get property of non-object
. But when I do a var_dump
on $term
i get the following:
<pre>object(stdClass)#4511 (10) {
["term_id"]=>
int(21)
["name"]=>
string(9) "Furniture"
["slug"]=>
string(9) "furniture"
["term_group"]=>
int(0)
["term_taxonomy_id"]=>
int(21)
["taxonomy"]=>
string(11) "product_cat"
["description"]=>
string(0) ""
["parent"]=>
int(0)
["count"]=>
int(0)
["filter"]=>
string(3) "raw"
}
</pre>
This looks to me like $term
is an object, so why the non-object notice and a total failure? You can also see commented out that I tried to turn this object into an array, but that didn't work out so well either...
Apologies for my PHP skills here - I'm clearly not understanding something fairly basic, but I really did want to solve this myself, but I must admit defeat!
Many thanks for reading.
EDIT:
As alluded to in Mark's answer below, the default get_term_by()
returns an object. Quite why my code was getting caught up on the is-it-or-isnt-it-an-object thing, I don't know. Using $term = get_term_by('slug', $cat_path, 'product_cat', ARRAY_A);
did the trick though, along with using array rather than object syntax to select the value I wanted.
As an aside, I realised that the above would return false
if these product categories were nested, as there would be two (or more) slugs being returned; so I did a bit more cleaning up of the slug before attempting to get the term id from it.
Replacing:
$cat_path = str_replace(home_url().'/'.$cat_base.'/', '', $item->url);
With:
$path = parse_url($item->url, PHP_URL_PATH);
$path_trimmed = trim($path, '/');
$parts = explode('/', $path_trimmed);
$cat_path = end($parts);