dpbfb7119 2017-07-15 11:07
浏览 15
已采纳

根据产品类别有条件地操作WooCommerce购物车项目

I'm in the process of creating a online food delivery website using WooCommerce and need to create a "Make it a Meal" type upsell for customers to purchase.

I've created a single product called "Make it a Meal" where users can select the drink and side of their choice (using variations). However what I need is for only one of these products to be able to be purchased per main meal.

Example:

  • Product in "Main Meal" category is added to cart
  • User can then add "Make it a Meal" product to cart
  • User cannot add second "Make it a Meal" product unless they have a second product from the "Meal Meal" category i.e. only one per product
  • If "Main Meal" product is removed from cart, then "Make it a Meal" is also removed.

Has anyone achieved this kind of functionality before? I've tried various plugins but currently had no luck.

  • 写回答

1条回答 默认 最新

  • dsi36131 2017-07-16 01:16
    关注

    Updated:

    It's possible checking first on add-to-cart events (optionally displaying an error notice):

    add_filter( 'woocommerce_add_to_cart_validation', 'checking_products_added_to_cart', 10, 3 );
    function checking_products_added_to_cart( $passed, $product_id, $quantity) {
    
        $cat_add = 'Make it a Meal';
        $cat_src = 'Main Meal';
    
        if(has_term( $cat_add, 'product_cat', $product_id )):
    
            $main_meal_count = 0;
            $make_it_a_meal_count = 0;
    
            foreach (WC()->cart->get_cart() as $cart_item ){
    
                // Counting 'Main Meal' products in cart (with quantity)
                if( has_term( $cat_src, 'product_cat', $cart_item['product_id'] ))
                    $main_meal_count += $cart_item['quantity'];
    
                // Counting 'Make it a Meal' products in cart (with quantity)
                if( has_term( $cat_add, 'product_cat', $cart_item['product_id'] ))
                    $make_it_a_meal_count += $cart_item['quantity'];
            }
    
            if( $main_meal_count < ($make_it_a_meal_count + $quantity) ) {
                $passed = false;
    
                // Displaying a message (optionnal)
                wc_add_notice( 'my custom error message…', 'error' );
            }
        endif;
    
        return $passed;
    }
    

    Then you will need to check also when cart quantities are changed or cart items removed:

    add_action( 'woocommerce_calculate_totals', 'check_removed_cart_items', 10, 1);
    function check_removed_cart_items( $cart_object ) {
    
        if ( is_admin() && ! defined( 'DOING_AJAX' ) )
            return;
    
        $cat_add = 'Make it a Meal';
        $cat_src = 'Main Meal';
    
        $main_meal_count = 0;
        $make_it_a_meal_count = 0;
    
        // First loop: Counting cart items 'Main Meal' and 'Make it a Meal'
        foreach ($cart_object->get_cart() as $item_values ){
    
            // Counting 'Main Meal' products in cart (with quantity)
            if( has_term( $cat_src, 'product_cat', $item_values['product_id'] ))
                $main_meal_count += $item_values['quantity'];
    
            // Counting 'Make it a Meal' products in cart (with quantity)
            if( has_term( $cat_add, 'product_cat', $item_values['product_id'] )){
                $make_it_a_meal_count += $item_values['quantity'];
            }
        }
    
        $difference = intval($make_it_a_meal_count - $main_meal_count);
    
            echo '<p>$main_meal_count is '.$main_meal_count.'</p>';
            echo '<p>$make_it_a_meal_count is '.$make_it_a_meal_count.'</p>';
            echo '<p>$difference is '.$difference.'</p>';
    
        if( $main_meal_count < $make_it_a_meal_count ) {
    
            echo '<p>case1</p>';
    
    
            // Second Loop: Make necessary actions
            foreach ($cart_object->get_cart() as $cart_item_key => $cart_item ){
    
                // Targeting 'Make it a Meal'
                if( has_term( $cat_add, 'product_cat', $cart_item['product_id'] )){
    
                    $item_qty = intval( $cart_item['quantity'] );
    
                    if( $item_qty == 1 && $difference == 1 ){
                        $cart_object->remove_cart_item($cart_item_key);
                        break;
                    } else {
                        if( $item_qty > 1 && $difference <= $item_qty ){
                            $cart_object->set_quantity( $cart_item_key, ($item_qty - $difference) );
                            break;
                        } else {
                            $cart_object->remove_cart_item($cart_item_key);
                        }
                    }
                }
            }
        }
    }
    

    With that 2 hooked functions you have a complete solution.

    Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

    This code is tested and works.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 有人能用聚类分析帮我分析一下文本内容嘛
  • ¥15 请问Lammps做复合材料拉伸模拟,应力应变曲线问题
  • ¥30 python代码,帮调试
  • ¥15 #MATLAB仿真#车辆换道路径规划
  • ¥15 java 操作 elasticsearch 8.1 实现 索引的重建
  • ¥15 数据可视化Python
  • ¥15 要给毕业设计添加扫码登录的功能!!有偿
  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥100 Jenkins自动化部署—悬赏100元