I'm writing some code to modify the related products section as follows:
- If a product has cross sell products, show those first, and fill up to 4 total products with others from the same category*
Or
- If a product has no cross sell products, show 4 products from the same category*
Here's my function to filter the related products so far:
add_filter( 'woocommerce_related_products', 'fivem_add_linked_to_related_products', 9999, 3 );
function fivem_add_linked_to_related_products( $related_posts, $product_id, $args ) {
$product = wc_get_product( $product_id );
$cross_sell_ids = $product->get_cross_sell_ids();
$product_categories = $product->get_category_ids();
// Get cross sell products
$cross_sell_products = get_posts( array(
'post_type' => 'product',
'post_status' => 'publish',
'fields' => 'ids',
'post__in' => $cross_sell_ids,
'posts_per_page' => 4,
'exclude' => array( $product_id ),
));
// Calculate how many filler products are needed
$category_product_count = 4 - count( $cross_sell_products );
// Exclude main product and cross sell products
$excluded_products = array_push( $cross_sell_ids, $product_id );
// Get filler products from same category
$category_products = get_posts( array(
'post_type' => 'product',
'post_status' => 'publish',
'orderby' => 'rand',
'fields' => 'ids',
'post__not_in' => $excluded_products,
'posts_per_page' => $category_product_count,
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'id',
'terms' => $product_categories,
'operator' => 'IN',
)
)
));
// Merge cross sell products with filler products
$related_products = array_merge( $cross_sell_products, $category_products );
// Return related products
return $related_products;
}
Currently, the above code mostly works.
- If cross-sells are set, it only displays those cross-sell products- ie. does not fill out to 4 total
- If no cross-sells are set, it displays products from the same category as expected.
There are two problems I'm trying to solve:
- Code above doesn't fill with category products. If I remove the post__not_in and tax_query arguments, it fills out, but obviously not with products from the same category.
- I want to show cross-sell products first, then the category-related products. There appears to be another randomization somewhere that mixes the order up, and I can't work out where that comes from.
Any ideas how I can fix this? Thanks in advance.