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 . ' ';
endforeach;
$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>';
}
else{
//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.
Leave an answer