I've found this great solution to display related products based on a product attribute, but additionally we would like to do the same with our upsells .
What I've tried so far doesn't work yet because I believe we have to add some additonal information as the related_products function is not the same as upsells.
add_filter( 'woocommerce_upsell_products', 'upsell_products_by_attribute', 10, 3 );
function upsell_products_by_attribute( $upsells, $product_id, $args ) {
$taxonomy = 'pa_attribute';
$term_slugs = wp_get_post_terms( $product_id, $taxonomy, ['fields' => 'slugs'] );
if ( empty($term_slugs) )
return $upsells;
$posts_ids = get_posts( array(
'post_type' => 'product',
'ignore_sticky_posts' => 1,
'posts_per_page' => 6,
'post__not_in' => array( $product_id ),
'tax_query' => array( array(
'taxonomy' => $taxonomy,
'field' => 'slug',
'terms' => $term_slugs,
) ),
'fields' => 'ids',
'orderby' => 'rand',
) );
return count($posts_ids) > 0 ? $posts_ids : $upsells;
}
So I wonder if there is any possibility to do the same with the upsell section.
CodePudding user response:
You can remove the default action hook woocommerce_after_single_product_summary
and add it again and you can customize upsells
products. check the below code. code will go into your active theme functions.php file.
Change $taxonomy = 'pa_color';
to your custom taxonomy.
function modify_woocommerce_upsell_display_based_on_attribute( $limit = '-1', $columns = 4, $orderby = 'rand', $order = 'desc' ){
remove_action( 'woocommerce_after_single_product_summary', 'woocommerce_upsell_display', 15 );
global $product;
if ( ! $product ) {
return;
}
// Handle the legacy filter which controlled posts per page etc.
$args = apply_filters(
'woocommerce_upsell_display_args',
array(
'posts_per_page' => $limit,
'orderby' => $orderby,
'order' => $order,
'columns' => $columns,
)
);
wc_set_loop_prop( 'name', 'up-sells' );
wc_set_loop_prop( 'columns', apply_filters( 'woocommerce_upsells_columns', isset( $args['columns'] ) ? $args['columns'] : $columns ) );
$orderby = apply_filters( 'woocommerce_upsells_orderby', isset( $args['orderby'] ) ? $args['orderby'] : $orderby );
$order = apply_filters( 'woocommerce_upsells_order', isset( $args['order'] ) ? $args['order'] : $order );
$limit = apply_filters( 'woocommerce_upsells_total', isset( $args['posts_per_page'] ) ? $args['posts_per_page'] : $limit );
// set your custom taxonomy here.
$taxonomy = 'pa_color';
$term_slugs = wp_get_post_terms( $product->get_id(), $taxonomy, ['fields' => 'slugs'] );
$posts_ids = get_posts( array(
'post_type' => 'product',
'ignore_sticky_posts' => 1,
'posts_per_page' => 6,
'post__not_in' => array( $product->get_id() ),
'tax_query' => array( array(
'taxonomy' => $taxonomy,
'field' => 'slug',
'terms' => $term_slugs,
) ),
'fields' => 'ids',
'orderby' => 'rand',
) );
if( !empty( $posts_ids ) ){
// Get visible upsells then sort them at random, then limit result set.
$upsells = wc_products_array_orderby( array_filter( array_map( 'wc_get_product', $posts_ids ), 'wc_products_array_filter_visible' ), $orderby, $order );
$upsells = $limit > 0 ? array_slice( $upsells, 0, $limit ) : $upsells;
wc_get_template(
'single-product/up-sells.php',
array(
'upsells' => $upsells,
// Not used now, but used in the previous version of up-sells.php.
'posts_per_page' => $limit,
'orderby' => $orderby,
'columns' => $columns,
)
);
}
}
add_action( 'woocommerce_after_single_product_summary', 'modify_woocommerce_upsell_display_based_on_attribute', 15 );