【问题标题】:Make specific products mutually exclusive in WooCommerce在 WooCommerce 中使特定产品互斥
【发布时间】:2020-07-16 06:47:04
【问题描述】:

情况

我的网站提供两种产品。如果用户购买产品 A,他们可以访问所有电子书。如果用户购买产品 B,他们将被允许选择一本电子书。在 WooCommerce 中,我创建了电子书作为产品 B 中的变体。

产品 A ID = 477

产品 B ID = 297 (https://i.imgur.com/Sdo4XnT.png)。虽然 297 是主要 ID,但我相信我应该使用变体 ID,例如。 1483、997 (https://i.imgur.com/CEMFNLD.png)。

我要解决的问题

我希望两种产品互斥。毕竟,如果用户购买了所有电子书的访问权限(即产品 A),那么他们就不需要购买产品 B 下的单本书籍。

最终结果

我尝试了一些代码(如下所示),但它根本不起作用。这意味着我仍然可以将产品 A 和 B 的变体一起添加到同一个购物车中。

问题 1:我该如何解决?

问题 2: 有没有更简单的方法来不指定每个产品 B 变体?这是一个非常长的列表,从长远来看不是一个可扩展的解决方案。

我尝试了什么

这似乎符合我的要求:Woocomerce Remove a specific cart items when adding to cart another specific items

由于产品 B 的变化,我不得不稍微修改它。

add_action( 'woocommerce_add_to_cart', 'check_product_added_to_cart', 10, 6 );
function check_product_added_to_cart($cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data) {

    // Set HERE your targeted product ID
    $target_product_ids1 = array(477);
    $target_product_ids2 = array(1483, 997,998,999,1000,1001);
    // Set HERE the  product ID to remove
    $item_id_to_remove1 = array(1483, 997,998,999,1000,1481);
    $item_id_to_remove2 = array(477);

    // Initialising some variables
    $has_item1 = $has_item2 = $is_product_id1 = $is_product_id2 = false;

    foreach( WC()->cart->get_cart() as $key => $item ){
        // Check if the item to be removed 1 is in cart
        if( in_array( $item['product_id'], $item_id_to_remove1) ){
            $has_item1 = true;
            $key_to_remove1 = $key;
        }
        // Check if the item to be removed 2 is in cart
        if( in_array( $item['product_id'], $item_id_to_remove2) ){
            $has_item2 = true;
            $key_to_remove2 = $key;
        }

        // Check if we added to cart any targeted product IDs 1
        if( in_array( $product_id, $target_product_ids1 ) ){
            $is_product_id1 = true;
        }

        // Check if we added to cart any targeted product IDs 2
        if( in_array( $product_id, $target_product_ids2 ) ){
            $is_product_id2 = true;
        }
    }

    if( $has_item1 && $is_product_id1 ){
        WC()->cart->remove_cart_item($key_to_remove1);

        // Optionaly displaying a notice for the removed item:
        wc_add_notice( __( 'The product 1 "blab bla" has been removed from cart.', 'theme_domain' ), 'notice' );
    }

    if( $has_item2 && $is_product_id2 ){
        WC()->cart->remove_cart_item($key_to_remove2);

        // Optionaly displaying a notice for the removed item:
        wc_add_notice( __( 'The product 2 "blab bla" has been removed from cart.', 'theme_domain' ), 'notice' );
    }
}

【问题讨论】:

    标签: php wordpress woocommerce product cart


    【解决方案1】:

    有一种更简单的方式使用添加到购物车验证钩子:

    add_filter( 'woocommerce_add_to_cart_validation', 'wc_add_to_cart_validation_filter_callback', 10, 3 );
    function wc_add_to_cart_validation_filter_callback( $passed, $product_id, $quantity ) {
        if( WC()->cart->is_empty() )
            return $passed;
    
        $product_id1 = 37; // Single product Id
        $product_id2 = 19; // Variable product Id
    
        // Loop through cart items
        foreach( WC()->cart->get_cart() as $cart_item ) {
            if( ( $product_id = $product_id1 && $cart_item['product_id'] == $product_id2 )
            || ( $product_id = $product_id2 && $cart_item['product_id'] == $product_id1 ) ) {
                wc_add_notice( sprintf(
                    __("This product can't not be purchased toggether with %s."),
                    '"<strong>' . $cart_item['data']->get_name() . '</strong>"'
                ), 'error' );
                return false;
            }
        }
    
        return $passed;
    }
    

    代码在您的活动子主题(或活动主题)的functions.php 文件中。经过测试并且可以工作。


    补充 (与你的评论有关)

    另一种方法是当两个产品都在购物车中时,静默删除第一项:

    add_action('woocommerce_before_calculate_totals', 'keep_last_variation_from_variable_products', 10, 1 );
    function keep_last_variation_from_variable_products( $cart ) {
        if ( is_admin() && ! defined( 'DOING_AJAX' ) )
            return;
    
        $product_id1 = 37; // Single product Id
        $product_id2 = 19; // Variable product Id
    
        $product_ids = array($product_id1, $product_id2);
        $items_keys  = array();
    
        // Loop through cart items
        foreach (  $cart->get_cart() as $cart_item_key => $cart_item ) {
            // If cart item matches with one of our defined product
            if ( in_array( $cart_item['product_id'], $product_ids ) ) {
                // Set the cart item key in an array (avoiding duplicates)
                $items_keys[$cart_item['product_id']] = $cart_item_key;
            }
        }
    
        // If both products are in cart just keep the last one silently
        if( count($items_keys) > 1 ) {
            $cart->remove_cart_item( reset($items_keys) ); // remove the first one
        }
    }
    

    代码在您的活动子主题(或活动主题)的functions.php 文件中。经过测试并且可以工作。

    【讨论】:

    • 嗨 LoicTheAztec,感谢您的回复。使用您的代码,如果产品 A 在购物车中,则根本无法添加产品 B(反之亦然)。是否有可能如果添加任何一种产品,那么另一种产品会自动从购物车中删除?因此,如果产品 A 已经在购物车中并且添加了产品 B,则从购物车中删除产品 A 并添加产品 B。谢谢。
    • 完美运行!谢谢你,先生!我忘了点击接受,现在已经这样做了。
    猜你喜欢
    • 1970-01-01
    • 2017-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-25
    • 2018-11-09
    • 2013-08-11
    • 2018-08-19
    相关资源
    最近更新 更多