php – Show related products by attribute based and certain conditions


Getting a reference here, I want to display a “product collection” on related products based on certain conditions.

Example :

The product has a color attribute and a size attribute.

The color attribute has 3 colors, namely red, yellow and green.

And for the size attribute it has 3 sizes, namely small, medium, and large.

Number of products in each attribute (on the back end) ;

  • Red color : 2
  • Yellow color : 6
  • Green color : 1

  • Small size: 3
  • Medium size: 8
  • Big Size : 4

I want to display a collection of products on related products with a sum : 2 rows, and 3 columns.

The first row for products that have a color attribute, show 3 products.

The second row for products that have a size attribute, show 3 products.

The conditions that must be met are as follows :

On a single page, when the product has a color attribute (ex : red || or whatever the color is) and the number is more than 5 => display the product.

But if the condition is not is met then nothing needs to be displayed.

The same rule applies to the size attribute.

But i having trouble checking the number of attributes on color (red, yellow, etc) as well as the number of attributes on size (small, medium, etc.)

The efforts I have so far are :

add_action( 'woocommerce_after_single_product_summary', 'custom_output_product_collection_color',30 );
function custom_output_product_collection_color ($post){
global $product;

$color = $product->get_attribute('pa_color');

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

if( ! empty( $color ) ){
$col_terms = get_the_terms($post, 'pa_color');
$col_id = ''; // Reset string
$col_slug = '';// Reset string
$col_name="";// Reset string  
foreach ($col_terms as $col_term) :
$col_id .= $col_term->term_id . ' ';
$col_slug .= $col_term->slug . ' ';
$col_name .= $col_term->name . ' ';
$attribute = "color"; // <== HERE define your attribute name
$limit     = "3";     // <== Number of products to be displayed
$cols      = "3";     // <== Number of columns
$orderby   = "rand";  // <== Order by argument (random order here)
$val_col = $col_id;//dinamically
## --- 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 = '{$col_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.'-'.$col_slug.' products">
    <h2>'.__( "Collection", "woocommerce" ).': '.$col_name.'</h2>';

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

echo '</section>';

    //Don't show anything

Note : I have duplicated the code above and only changed the value of the color attribute to the size attribute (Code A – for color attributes and code B – for attributes size).

Result :

On the current single page, the product has attributes -> red color and large size.

And on related products displays: Color collection (on line 1) and size collection (on line 2).

  • In line 1 – “red” collection : Displays 3 products, 1 red product and 2 other color products (random).

  • In line 2 – Collection “large” : Displays 3 products with large size.

What I want (and should be) :

There is no need for anything to be shown as they are both ineligible.

Unless the conditions are as follows:

Scenario 1

On the current single page, the product has a -> yellow color attribute and a large size attribute.

Which should be shown => Only the first line.

  • Yellow color (6) = > Qualified, and

  • Large size (4) = > Not eligible.

Scenario 2

On the current single page, the product has a -> yellow color attribute and a medium size attribute.

Which should be displayed => First line & second line.(Both are eligible).

  • Yellow color (6)
  • Medium size (8)

So, the problem I haven’t been able to solve is:

1. How to check the number of (ex : red color) attributes and apply them to the condition?

Maybe it’s like:

if( ! empty( $color ) && count($color) >= 5 ){

2. How to adjust the position or order on the display?

For example, I want the first row to contain the color attribute and the second row the size attribute or vice versa.

Here’s the hook I’m currently using.

Hook for color attribute

add_action( 'woocommerce_after_single_product_summary', 'custom_output_product_collection_color',30 );
function custom_output_product_collection_color ($post){

Hook for size attribute

add_action( 'woocommerce_after_single_product_summary', 'custom_output_product_collection_size',30 );
function custom_output_product_collection_size ($post){

Thank you.

carlozsan 2 years 2022-01-18T07:32:03-05:00 0 Answers 0 views 0

Leave an answer