Search code examples
phpwoocommerceproductcart

How to automatically set cross-sells in WooCommerce based on product category


I'm trying to edit the cross-sell section of the cart page in WooCommerce. I want to display random products from the same category in the cross-sell section.

For example, someone adds something from the category women's fashion then it will display other products in the cross-sell section from the same category.

or if they have items from multiple categories to then just pick two at random.

Is there a way of doing this or is it a case of having to go through every product individually to select the cross-sell products?


Solution

  • Following code returns automatically $cross_sells IDs that belong to the product categor(y)(ies) from the products in the cart.

    function filter_woocommerce_cart_crosssell_ids( $cross_sells, $cart ) {
        // Initialize
        $product_cats_ids = array();
        $product_cats_ids_unique = array();
    
        foreach ( $cart->get_cart() as $cart_item ) {       
            // Get product id
            $product_id = $cart_item['product_id'];
    
            // Get current product categories id(s) & add to array
            $product_cats_ids = array_merge( $product_cats_ids, wc_get_product_term_ids( $product_id, 'product_cat' ) );
        }
    
        // Not empty
        if ( !empty( $product_cats_ids ) ) {
            // Removes duplicate values
            $product_cats_ids_unique = array_unique( $product_cats_ids, SORT_REGULAR );
    
            // Get product id(s) from a certain category, by category-id
            $product_ids_from_cats_ids = get_posts( array(
                'post_type'   => 'product',
                'numberposts' => -1,
                'post_status' => 'publish',
                'fields'      => 'ids',
                'tax_query'   => array(
                    array(
                        'taxonomy' => 'product_cat',
                        'field'    => 'id',
                        'terms'    => $product_cats_ids_unique,
                        'operator' => 'IN',
                    )
                ),
            ) );
    
            // Removes duplicate values
            $cross_sells = array_unique( $product_ids_from_cats_ids, SORT_REGULAR );
        }
    
        return $cross_sells;
    }
    add_filter( 'woocommerce_cart_crosssell_ids', 'filter_woocommerce_cart_crosssell_ids', 10, 2 );
    

    Note: 'numberposts' => -1 means ALL, this can be adapted to your needs


    The limit ('posts_per_page') can be set via the woocommerce_cross_sells_total filter hook

    function filter_woocommerce_cross_sells_total( $limit ) {
        // Set limit
        $limit = 4;
        
        return $limit;
    }
    add_filter( 'woocommerce_cross_sells_total', 'filter_woocommerce_cross_sells_total', 10, 1 );