如何使两个具有不同产品 ID 的产品在 WooCommerce 购物车页面 (BOGO) 上充当一个产品

How do I make two products with different product IDs act as one on WooCommerce cart page (BOGO)

我是 运行 一个项目的 BOGO。这个问题是当你增加购买物品的数量时,给定的免费物品数量不会随之增加。

我们怎样才能让它们像一个一样,使两个项目的数量相同?

我正在尝试更改此代码以使其完成工作。

add_action( 'template_redirect', 'bbloomer_add_gift_if_id_in_cart' );
 
function bbloomer_add_gift_if_id_in_cart() {
 
   if ( is_admin() ) return;
   if ( WC()->cart->is_empty() ) return;
 
   $product_bought_id = 874;
   $product_gifted_id = 870;
 
   // see if product id in cart
   $product_bought_cart_id = WC()->cart->generate_cart_id( $product_bought_id );
   $product_bought_in_cart = WC()->cart->find_product_in_cart( $product_bought_cart_id );
 
   // see if gift id in cart
   $product_gifted_cart_id = WC()->cart->generate_cart_id( $product_gifted_id );
   $product_gifted_in_cart = WC()->cart->find_product_in_cart( $product_gifted_cart_id );
 
   // if not in cart remove gift, else add gift
   if ( ! $product_bought_in_cart ) {
      if ( $product_gifted_in_cart ) WC()->cart->remove_cart_item( $product_gifted_in_cart );
   } else {
      if ( ! $product_gifted_in_cart ) WC()->cart->add_to_cart( $product_gifted_id );
   }
}

如果客户删除赠送的产品 ID,您正在使用的代码将无法使用。在这种情况下,赠品将在页面重新加载后被删除。

所以 woocommerce_before_calculate_totals 优于 template_redirect

我的回答包含:

  • 当购买的产品添加一定数量时,等量的赠品加入购物车
  • 当店铺页面更新一个产品的数量时,其他产品的数量也会随之改变,这通过jQuery
  • 可选的2个额外代码,可在礼品产品的整个操作过程中发挥作用
  • 在代码标签中添加解释的评论

比你得到:

function action_woocommerce_before_calculate_totals( $cart ) {  
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
        return;
    
    // SETTINGS
    $product_bought_id = 30;
    $product_gifted_id = 815;
    // END SETTINGS
    
    // Flags
    $product_bought_in_cart = false;
    $gifted_key = false;
    
    // Loop trough
    foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
        // Product ID in cart
        $product_id_in_cart = $cart_item['product_id'];
        
        // Check if product bought is in cart
        if ( $product_id_in_cart == $product_bought_id  ) {
            // True
            $product_bought_in_cart = true;
            
            // Product quantity in cart
            $product_bought_in_cart_quantity = $cart_item['quantity'];
        }
        
        // Check if product gifted is in cart
        if ( $product_id_in_cart == $product_gifted_id  ) {
            // Set gifted key (true)
            $gifted_key = $cart_item_key;
        }
    }

   // If product bought is false & gifted key is true
   if ( ! $product_bought_in_cart && $gifted_key ) {
       $cart->remove_cart_item( $gifted_key );
    // If product bought in true & gifted key is false
    } elseif ( $product_bought_in_cart && ! $gifted_key ) {
        $cart->add_to_cart( $product_gifted_id, $product_bought_in_cart_quantity );
    // If product bought in true & gifted key is true
    } elseif ( $product_bought_in_cart && $gifted_key ) {
        $cart->set_quantity( $gifted_key, $product_bought_in_cart_quantity );
    }
}
add_action( 'woocommerce_before_calculate_totals', 'action_woocommerce_before_calculate_totals', 10, 1 );

jQuery部分,保证数量字段同步调整

function action_wp_footer() {
    // SETTINGS
    $product_bought_id = 30;
    $product_gifted_id = 815;
    // END SETTINGS
    
    // See if product id in cart
    $product_bought_cart_id = WC()->cart->generate_cart_id( $product_bought_id );
    $product_bought_in_cart = WC()->cart->find_product_in_cart( $product_bought_cart_id );

    // See if gift id in cart
    $product_gifted_cart_id = WC()->cart->generate_cart_id( $product_gifted_id );
    $product_gifted_in_cart = WC()->cart->find_product_in_cart( $product_gifted_cart_id );
    
    // Both true
    if ( $product_bought_in_cart && $product_gifted_in_cart ) {
        ?>
        <script>
            jQuery(function($) {
                // Selectors
                var product_bought_in_cart_selector = $( "input[name*='<?php echo $product_bought_in_cart; ?>']" );
                var product_gifted_in_cart_selector = $( "input[name*='<?php echo $product_gifted_in_cart; ?>']" );
                
                // When 1 of the 2 quantity fields are updated, these values ​​change similarly
                $( product_bought_in_cart_selector ).change(function() {
                    var product_bought_in_cart_selector_quantity = $( this ).val();
                    
                    $( product_gifted_in_cart_selector ).val( product_bought_in_cart_selector_quantity );
                });
                
                $( product_gifted_in_cart_selector ).change(function() {
                    var product_gifted_in_cart_selector_quantity = $( this ).val();
                    
                    $( product_bought_in_cart_selector ).val( product_gifted_in_cart_selector_quantity );
                });
            });
        </script>
        <?php
    }
}
add_action( 'wp_footer', 'action_wp_footer');

可选1:赠品不可单独购买的警告

function filter_woocommerce_add_to_cart_validation( $passed, $product_id, $quantity, $variation_id = null, $variations = null ) {
    // SETTINGS
    $product_gifted_id = 815;

    // True
    if ( $product_gifted_id == $product_id ) {
        // Add notice    
        wc_add_notice( __( 'This is a gift item and cannot be purchased separately', 'woocommerce' ), 'error' );

        // NOT passed
        $passed = false;
    }

    return $passed;
}
add_filter( 'woocommerce_add_to_cart_validation', 'filter_woocommerce_add_to_cart_validation', 10, 5 );

可选2:确保礼品产品在购物车中不可单独移除

function filter_woocommerce_cart_item_remove_link( $link, $cart_item_key ) {
    // SETTINGS
    $product_gifted_id = 815;
    
    // Cart id
    $product_cart_id = WC()->cart->generate_cart_id( $product_gifted_id );

    // Find product in cart
    $in_cart_key = WC()->cart->find_product_in_cart( $product_cart_id );
    
    // True
    if ( $in_cart_key == $cart_item_key ) {
        $link = '';
    }

    return $link;
}
add_filter( 'woocommerce_cart_item_remove_link', 'filter_woocommerce_cart_item_remove_link', 10, 2 );

可选3:确保如果两个产品的数量不相等,订单将无法完成

function action_woocommerce_check_cart_items() {
    // SETTINGS
    $product_bought_id = 30;
    $product_gifted_id = 815;
    // END SETTINGS

    // Loop though cart items searching for the defined product
    foreach( WC()->cart->get_cart() as $cart_item ) {
        // Product id
        $product_id = $cart_item['product_id'];

        if ( $product_bought_id == $product_id ) {
            $product_bought_quantity = $cart_item['quantity'];
            $product_bought_name = $cart_item['data']->get_name();
        }
        
        if ( $product_gifted_id = $product_id ) {
            $product_gifted_quantity = $cart_item['quantity'];
            $product_gifted_name = $cart_item['data']->get_name();
        }
    }

    // Isset & NOT equal
    if( isset ( $product_bought_quantity ) && isset ( $product_gifted_quantity ) && $product_bought_quantity != $product_gifted_quantity  ) {
        wc_add_notice( sprintf(
            __( 'The quantity of %s and %s must be equal before you can continue', 'woocommerce' ),
            $product_bought_name,
            $product_gifted_name,
        ), 'error' );
        
        // Removing the proceed button, until the condition is met
        // optional
        remove_action( 'woocommerce_proceed_to_checkout','woocommerce_button_proceed_to_checkout', 20);
    }
}
add_action( 'woocommerce_check_cart_items', 'action_woocommerce_check_cart_items', 10, 0 );