0
votes

I am developing a WooCommerce theme, and on single product page I want to display a carousel of products from same vendor category.

I have the following category structure:

All products

  • product category no 1
  • product category no 2
  • product cat ...

Vendors

  • vendor name 1
  • vendor name 2
  • vendor name ...

While viewing product from category no 1 I would like to display a carousel off other products from same vendor name category if product is assigned to such child category.

In my example Vendors and All products are parent categories on the same level.

Doing a custom product loop is quiet easy, but to be honest I have no idea how I should handle the logic behind finding the right child category. I just can't imagine it , and that's why I can't came up with the right solution.

Each product can be assigned only to one vendor name, and both vendors and products are regular woocommerce categories here.

For the time being I have the following code

wooctrl_same_vendor_products('vendors');

function wooctrl_same_vendor_products($parent_cat_name){

  $parentCat = get_term_by('name', $parent_cat_name, 'product_cat');

  $product_cat_ID = $parentCat->term_id;
  $args = array(
    'hierarchical' => 1,
    'show_option_none' => '',
    'hide_empty' => 0,
    'parent' => $product_cat_ID,
    'taxonomy' => 'product_cat'
  );
  $subcats = get_categories($args);

  foreach ($subcats as $subcat) {
    //check if product is inside ?
  }
}

Should I first create an array of all Vendors child categories and the search for product there or is there a cleaner way to solve it directly from the $product variable?

2

2 Answers

0
votes

I got this working, however I think it's quiet dirty solution. Can you please take a look at the code and tell me how to do this in a "good practise" way?

So in first step a I am preping the list of all childe categories under the vendors main category:

wooctrl_vendor_cats('vendors');  // <-- main category slug

function wooctrl_vendor_cats($parent_cat_name){
$parentCat = get_term_by('name', $parent_cat_name, 'product_cat');

$product_cat_ID = $parentCat->term_id;
$args = array(
    'hierarchical' => 1,
    'show_option_none' => '',
    'hide_empty' => 0,
    'parent' => $product_cat_ID,
    'taxonomy' => 'product_cat'
);
$subcats = get_categories($args);

foreach ($subcats as $subcat) {
    //print_r($subcat->slug);
    check_if_in_vendor($subcat->slug); // <-- here I am passing each slug in order to compare it with products categories
}
}

Here is the function where I cross-reference product categories with vendor categories in order to find a match and then I am looping through it to display all the products inside:

function check_if_in_vendor($cat_slug){
global $post;
$terms = wp_get_post_terms( $post->ID, 'product_cat' );
foreach ( $terms as $term ) $categories[] = $term->slug;
if ( in_array( $cat_slug, $categories ) ) {

    $args = array(
        'post_type' => 'product',
        'posts_per_page' => 10,
        'product_cat' => $cat_slug,
        'orderby' => 'rand',
        'post__not_in' => array( $post->ID )
    );
    $loop = new WP_Query( $args );
    while ( $loop->have_posts() ) : $loop->the_post();  ?>



        <li class="product">

            <h3><?php the_title(); ?></h3>

        </li>

    <?php endwhile; ?>
    <?php wp_reset_query();
}
} 
0
votes

After reading Andrew comment and reading the docs provided there ( docs I never seen before, so thanks Andrew! Those gave me a lot ) I decided to filter products by the first part of SKU code, as I found it fastest. It's easier to manage the output content from WP admin panel too.

Here's my code updated with WooCommerce 3 functions. Is it better than the previous solution? What do you think?

function wooctrl_display_vendor_products_bySKU($number_of_products_displayed, $ordered_by) {
global $product;
$currentSku = $product->get_sku();
$groupSku = explode('-', $currentSku)[0];

$args = array(
    'sku' => $groupSku,
    'post_type' => 'product',
    'posts_per_page' => $number_of_products_displayed,
    'orderby' => $ordered_by,
    'exclude' => array($product->get_id())
);
$query = new WC_Product_Query($args);
$sku_products = $query->get_products();
//print_r($products);
if ($sku_products) : ?>


    <div class="wrapper">
        <h1 class="section-header"> <?php echo __('Same vendor products', 'genesis-wooctrl') ?> </h1>


        <?php foreach ($sku_products as $sku_product) : ?>

            <?php
            $post_object = get_post($sku_product->get_id());
            setup_postdata($GLOBALS['post'] =& $post_object);
            wc_get_template_part('content', 'product'); ?>

        <?php endforeach; ?>


    </div>


<?php endif;
wp_reset_postdata();
}

And for those, who are seeking realiable source of function, here are the URL's that helped me solving this issue a lot:

https://businessbloomer.com/woocommerce-easily-get-product-info-title-sku-desc-product-object/

https://github.com/woocommerce/woocommerce/wiki/Product-Data-Schema