I have a woocommerce store with a custom category of "Sports". The classification has three levels - parent, child, child - for example: Indoor Sports > Arena Sports > Basketball. If the user views the Basketball item, then I want the related products to show other Basketball items first, and then fall back to the Arena Sport item if there aren't enough Basketball items. So, the lowest level is checked first - Sub-Child, then Child, then Parent.
Also, I use RankMath and I can set the classification term as the "primary" term. So, in the example above, the main term is basketball. Main terms are almost always sub-sub-terms, but may also be sub-terms.
I combined the answers from the other two questions and the code works by selecting relevant products from the sports category. But it only looks at sub-levels, not sub-sub-levels. So, in the example above, it selects the items in Arena Sports without prioritizing Basketball.
What changes should I make to ensure that related products see the "main" taxonomy term and then look for products with that term first, and then (if necessary) the next level down the term hierarchy?
Thanks for any help or advice you can provide.
I referred to these two articles when drafting the code:
WooCommerce Related Products by Kids Category as Backup to Rank Math Primary Category
Select related products in Woocommerce using custom taxonomies
This is the code I'm currently using:
add_filter( 'woocommerce_related_products', 'related_products_from_rankmath_primary_esporte_taxonomy', 10, 3 ); function related_products_from_rankmath_primary_esporte_taxonomy( $related_posts, $product_id, $args ) { $taxonomy = 'sport'; $term_ids = wp_get_post_terms( $product_id, $taxonomy, array( 'fields' => 'ids' ) ); $term_slugs = array(); if( count($term_ids) == 1 ) { // Get children categories $children_ids = get_term_children( reset($category_ids), $taxonomy ); // Loop through children terms Ids foreach ( $children_ids as $tem_id ) { $term_slugs[] = get_term_by( 'id', $tem_id, $taxonomy )->slug; // get the slug from each term Id } } elseif( count( $term_ids ) > 1 ) { // Get the primary taxonomy/term as saved by Rank Math SEO $primary_tax_id = get_post_meta( $product_id, 'rank_math_primary_taxonomy', true ); $term_slugs[] = get_term_by( 'id', $primary_tax_id, $taxonomy )->slug; // get the slug from the term Id } if ( count( $term_ids ) > 0 ) { foreach ( $term_ids as $term_id ) { $term_slugs[] = get_term_by( 'id', $term_id, $taxonomy )->slug; // Gets the IDs of child terms $children_ids = get_term_children( $term_id, $taxonomy ); foreach ( $children_ids as $child_id ) { $term_slugs[] = get_term_by( 'id', $child_id, $taxonomy )->slug; // Gets the slug of each child term } } $related_posts = wc_get_products( array( 'status' => 'publish', 'tax_query' => array( array( 'taxonomy' => $taxonomy, 'field' => 'slug', 'terms' => $term_slugs, ), ), 'return' => 'ids', 'exclude' => array( $product_id ), 'visibility' => 'catalog', 'limit' => -1, ) ); } return $related_posts; }
Try the following (commented):
It should work.