WooCommerce Cart - Conditional Items categories validation

前端 未结 2 1866
星月不相逢
星月不相逢 2020-12-07 04:09

We have an exclusive category X and others regular categories Y. What I would like:

  • When someone orders anything from
相关标签:
2条回答
  • 2020-12-07 04:24

    Updated (2019)

    Like everything is turning around your exclusive category category X, you need to use a conditional for this category.

    And you have chance because there is a special function that you can use in combination with woocommerce product categories. Lets say that **cat_x** is the slug for your exclusive category, as you know it yet product_cat is the argument to get products categories.

    So with has_term () conditional function, you are going to use this:

    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'
    }
    

    We need to run the cart items 2 times in a foreach loop:

    • To detect if there is a cat_x item in that car.
    • To remove other items if cat_x is detected for one item in the cart and to fire the right messages.

    In the code below, I have changed to a more useful hook. This hook will check what you have in your cart. The idea is to removed other categories items in the cart when there is a 'cat_x' item added in cart.

    The code is well commented. At the end you will find different notices that are fired. You will need to put your real text in each.

    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' );
            }
        }
    }       
    

    Is not possible for me to really test this code (but it doesn't throws errors)…


    @edit

    We can use something else than notices… everything is possible. But it's a good starting solution, to fine tune.

    You will need to replace 'cat_x' by your real category slug (in the beginning)

    0 讨论(0)
  • 2020-12-07 04:42

    Answer in 2020

    Recently, I need almost the same requirement. But instead of a single category, I have to check if the item is in a group of categories.

    Consider that I have 6 categories. I will group 6 categories into 3 groups. My customer can only purchase items in a single category group (but multiple categories) in a single order.

    The code snippet is given below.

    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);
    
    0 讨论(0)
提交回复
热议问题