【问题标题】:WooCommerce Cart - Conditional Items categories validationWooCommerce 购物车 - 条件项目类别验证
【发布时间】:2016-11-18 07:21:44
【问题描述】:

我们有一个专有类别 X 和其他常规类别 Y。我想要什么:

  • 当有人从 类别 X 订购任何商品时,其他类别的商品无法添加到购物车,应显示警告
  • Y 类产品不应与X混用。

我怎样才能做到这一点?

我从其他帖子中获得了此代码,但它已过时且不令人满意:

<?php

 // Enforce single parent category items in cart at a time based on first item in cart
function get_product_top_level_category ( $product_id ) {

    $product_terms            =  get_the_terms ( $product_id, 'product_cat' );
    $product_category         =  $product_terms[0]->parent;
    $product_category_term    =  get_term ( $product_category, 'product_cat' );
    $product_category_parent  =  $product_category_term->parent;
    $product_top_category     =  $product_category_term->term_id;

    while ( $product_category_parent  !=  0 ) {
            $product_category_term    =  get_term ( $product_category_parent, 'product_cat' );
            $product_category_parent  =  $product_category_term->parent;
            $product_top_category     =  $product_category_term->term_id;
    }

    return $product_top_category;
}

add_filter ( 'woocommerce_before_cart', 'restrict_cart_to_single_category' );
function restrict_cart_to_single_category() {
    global $woocommerce;
    $cart_contents    =  $woocommerce->cart->get_cart( );
    $cart_item_keys   =  array_keys ( $cart_contents );
    $cart_item_count  =  count ( $cart_item_keys );

    // Do nothing if the cart is empty
    // Do nothing if the cart only has one item
    if ( ! $cart_contents || $cart_item_count == 1 ) {
            return null;
    }

    // Multiple Items in cart
    $first_item                    =  $cart_item_keys[0];
    $first_item_id                 =  $cart_contents[$first_item]['product_id'];
    $first_item_top_category       =  get_product_top_level_category ( $first_item_id );
    $first_item_top_category_term  =  get_term ( $first_item_top_category, 'product_cat' );
    $first_item_top_category_name  =  $first_item_top_category_term->name;

    // Now we check each subsequent items top-level parent category
    foreach ( $cart_item_keys as $key ) {
            if ( $key  ==  $first_item ) {
                    continue;
            }
            else {
                    $product_id            =  $cart_contents[$key]['product_id'];
                    $product_top_category  =  get_product_top_level_category( $product_id );

                    if ( $product_top_category  !=  $first_item_top_category ) {
                            $woocommerce->cart->set_quantity ( $key, 0, true );
                            $mismatched_categories  =  1;
                    }
            }
    }

    // we really only want to display this message once for anyone, including those that have carts already prefilled
    if ( isset ( $mismatched_categories ) ) {
            echo '<p class="woocommerce-error">Only one category allowed in cart at a time.<br />You are currently allowed only <strong>'.$first_item_top_category_name.'</strong> items in your cart.<br />To order a different category empty your cart first.</p>';
    }
}
?>

谢谢

【问题讨论】:

    标签: php wordpress woocommerce categories cart


    【解决方案1】:

    更新(2019)

    就像一切都在扭转您的专属类别category X,您需要为此类别使用条件。

    你有机会,因为有一个特殊的功能可以与 woocommerce 产品类别结合使用。假设**cat_x** 是您的专属类别的蛞蝓,正如您所知,product_cat 是获取产品类别的参数。

    所以有了 has_term () 条件函数,你将使用这个:

    if ( has_term ('cat_x', 'product_cat', $item_id ) ) { // or $product_id
        // doing something when product item has 'cat_x'
    } else {
        // doing something when product item has NOT 'cat_x'
    }
    

    我们需要在 foreach 循环中运行购物车项目 2 次:

    • 检测该车是否有cat_x物品。
    • 如果检测到购物车中的一件商品有 cat_x 则删除其他商品并触发正确的消息。

    在下面的代码中,我改成了一个更有用的钩子。这个钩子会检查你的购物车里有什么。这个想法是当购物车中添加了“cat_x”项目时,删除购物车中的其他类别项目。

    代码注释很好。最后你会发现不同的通知被解雇了。您需要将真实文本放入其中。

    add_action( 'woocommerce_check_cart_items', 'checking_cart_items' );
    function checking_cart_items() {
        // Set your product category slug
        $category = 'cat_x';
    
        $number_of_items = sizeof( WC()->cart->get_cart() );
        $found  = false; // Initializing
        $notice = ''; // Initializing
    
        if ( $number_of_items > 0 ) {
    
            // Loop through cart items
            foreach ( WC()->cart->get_cart() as $cart_item ) {
                $product = $cart_item['data'];
                $product_id = $cart_item['product_id'];
    
                // Detecting if the defined category is in cart
                if ( has_term( $category, 'product_cat', $product_id ) ) {
                    $found = true;
                    break; // Stop the loop
                }
            }
    
            // Re-loop through cart items
            foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
                $product = $cart_item['data'];
                $product_id = $cart_item['product_id'];
    
                if ( $found ) // If the defined product category is in cart
                { 
                    if ( $number_of_items == 1 ) { // only one defined product category
                        if ( empty( $notice ) ){
                            $notice = '1';
                        }
                    }
                    if ( $number_of_items >= 2 ) { // The defined product category + other categories in cart
    
                        // removing other categories items from cart
                        if ( ! has_term( $category, 'product_cat', $product_id ) ) {
                            WC()->cart->remove_cart_item( $cart_item_key ); // removing item from cart
                            if ( empty( $notice ) || $notice == '1' ){
                                $notice = '2';
                            }
                        }
                    }
                } else { // Only other categories items
    
                    if ( empty( $notice ) ){
                        $notice = '3';
                    }
                }
            }
    
            // Firing woocommerce notices
            if ( $notice == '1' ) { // message for an 'cat_x' item only (alone)
                wc_add_notice( sprintf( '<p class="woocommerce-error">bla bla bla one category X item in the cart</p>' ), 'success' );
            } elseif ( $notice == '2' ) { // message for an 'cat_x' item and other ones => removed other ones 
                wc_add_notice( sprintf( '<p class="woocommerce-error">bla bla bla ther is already category X in the cart => Other category items has been removed</p>' ), 'error' );
            } elseif ( $notice == '3' ) { // message for other categories items (if needed)
                wc_add_notice( sprintf( '<p class="woocommerce-error">bla bla bla NOT category X in the cart</p>' ), 'success' );
            }
        }
    }       
    

    我无法真正测试这段代码(但它不会引发错误)……


    @edit

    我们可以使用通知以外的其他东西……一切皆有可能。但这是一个很好的开始解决方案,可以微调。

    您需要将 'cat_x' 替换为您的真实类别 slug (在开头)...

    【讨论】:

    • 看来我找到了解决方案,非常感谢。
    【解决方案2】:

    2020 年的答案

    最近,我需要几乎相同的要求。但我必须检查项目是否在一组类别中,而不是单个类别。

    假设我有 6 个类别。我将 6 个类别分为 3 个组。我的客户只能在一个订单中购买单个类别组(但多个类别)中的商品。

    代码sn-p如下。

    function sa45er_category_group_validation($valid, $product_id, $quantity) {
        global $woocommerce;
        if($woocommerce->cart->cart_contents_count == 0){
             return $valid;
        }
        
        $target_cat_group = array(
            array(17,20), // Update your product category
            array(19,18), // Update your product category
        );
        
        $this_product_terms = get_the_terms( $product_id, 'product_cat' );
        foreach ($this_product_terms as $term) {
            $this_product_cat_ids[] = $term->term_id; 
        }        
                
        foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
            $_product = $values['data'];
            $terms = get_the_terms( $_product->get_ID(), 'product_cat' );
            foreach ($terms as $term) {
                $cart_cat_ids[] = $term->term_id;  
            }       
        }
        
        $all_cats = array_merge($this_product_cat_ids,$cart_cat_ids);
        
        $result = array();
        foreach($target_cat_group as $target_cat_group_item){
                
            $intrsct = array_intersect($all_cats, $target_cat_group_item);
            
            if( !empty( $intrsct ) ){
                $result[] = $intrsct;
            }
                
        }
        
        if(count($result) > 1){
            wc_add_notice( 'You can\'t add this product with your current cart items.', 'error' );
            return false;
        }
        
        return $valid;
    }
    add_filter( 'woocommerce_add_to_cart_validation', 'sa45er_category_group_validation',10,3);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-10
      • 1970-01-01
      • 1970-01-01
      • 2019-04-14
      • 2021-05-12
      • 2020-02-28
      • 2018-08-29
      相关资源
      最近更新 更多