1

I want to display products that are related either by category or attributes (not tags)

I've modified the solution posted here here to my needs:

function custom_related_product_args ( $args ){
    global $product;

    $cats          = wc_get_product_terms( $product->id, 'product_cat', array( 'fields' => 'slugs' ) );
    $brands        = wc_get_product_terms( $product->id, 'pa_brand', array( 'fields' => 'slugs' ) );
    $collections   = wc_get_product_terms( $product->id, 'pa_collection', array( 'fields' => 'slugs' ) );    

    unset( $args['post__in'] );
    $args['tax_query'] = array( 
        'relation' => 'OR',
        array(
            'taxonomy' => 'product_cat',
            'field'    => 'slug',
            'terms'    => $cats,
        ),
        array(
            'relation' => 'OR',
            array(
                'taxonomy' => 'pa_brand',
                'field'    => 'slug',
                'terms'    => $brands,
            ),
            array(
                'taxonomy' => 'pa_collection',
                'field'    => 'slug',
                'terms'    => $collections,
            )
        )
    );

    return $args;
}
add_filter('woocommerce_related_products_args', 'custom_related_product_args');

However it doesn't seem to work for me and I can't figure out what I'm doing wrong?

1

Disable default Related Products and try this (Add custom code to the functions.php)

add_action( 'woocommerce_after_single_product_summary', 'custom_output_product_collection', 12 );
function custom_output_product_collection(){

    ## --- YOUR SETTINGS --- ##

    $attribute = "attribute_slug"; // <== HERE define your attribute slug
    $limit     = "5";     // <== Number of products to be displayed
    $cols      = "5";     // <== Number of columns
    $orderby   = "rand";  // <== Order by argument (random order here)

    ## --- THE CODE --- ##

    global $post, $wpdb;

    // Formatting the attribute
    $attribute = sanitize_title( $attribute );
    $taxonomy  = 'pa_' . $attribute;

    // Get the WP_Term object for the current product and the defined product attribute
    $terms = wp_get_post_terms( $post->ID, $taxonomy );
    $term = reset($terms);

    // Get all product IDs that have  the same product attribute value (except current product ID)
    $product_ids = $wpdb->get_col( "SELECT DISTINCT tr.object_id
        FROM {$wpdb->prefix}term_relationships as tr
        JOIN {$wpdb->prefix}term_taxonomy as tt ON tt.term_taxonomy_id = tr.term_taxonomy_id
        JOIN {$wpdb->prefix}terms as t ON tt.term_id = t.term_id
        WHERE tt.taxonomy LIKE '$taxonomy' AND t.term_id = '{$term->term_id}' AND tr.object_id != '{$post->ID}'" );

    // Convert array values to a coma separated string
    $ids = implode( ',', $product_ids );

    ## --- THE OUTPUT --- ##

    echo '<section class="'.$attribute.' '.$attribute.'-'.$term->slug.' products">
        <h2>'.__( "Collection", "woocommerce" ).': '.$term->name.'</h2>';

    echo do_shortcode("[products ids='$ids' columns='$cols' limit='$limit' orderby='$orderby']");

    echo '</section>';
}
2
  • It's always good to offer an explanation as to what the code is doing different or why it works, or why you've included things. In this instance you're using $wpdb, it'd be good for the OP to understand why it should be done this way vs. using wp_query. – Tony Djukic May 19 '20 at 21:10
  • works like a charm! thanks! – arispen Nov 30 '20 at 19:31
0
global $product;

$cats          = wc_get_product_terms( $product->id, 'product_cat', array( 'fields' => 'slugs' ) );
$brands        = wc_get_product_terms( $product->id, 'pa_brand', array( 'fields' => 'slugs' ) );
$artists       = wc_get_product_terms( $product->id, 'pa_artist', array( 'fields' => 'slugs' ) );    
$manufacturers = wc_get_product_terms( $product->id, 'pa_manufacturer', array( 'fields' => 'slugs' ) );

unset( $args['post__in'] );
$args['tax_query'] = array( 
    'relation' => 'AND',
    array(
        'taxonomy' => 'product_cat',
        'field'    => 'slug',
        'terms'    => $cats,
    ),
    array(
        'relation' => 'OR',
        array(
            'taxonomy' => 'pa_brand',
            'field'    => 'slug',
            'terms'    => $brands,
        ),
        array(
            'taxonomy' => 'pa_artist',
            'field'    => 'slug',
            'terms'    => $artists,
        ),
        array(
            'taxonomy' => 'pa_manufacturer',
            'field'    => 'slug',
            'terms'    => $manufacturers,
        )
    )
);

return $args;
1
  • Where do I place the code? I tried it in functions.php but doesn't seem to make a change in the output – Dan Feb 18 '18 at 16:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.