WooCommerce 购物车 - 条件项目类别验证 [英] WooCommerce Cart - Conditional Items categories validation

查看:20
本文介绍了WooCommerce 购物车 - 条件项目类别验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

  • 当有人订购类别 X 中的任何商品时,其他类别的商品无法添加到购物车并应显示警告
  • Y 类 产品不应与 X 混合使用.
  • When someone orders anything from category X, other category items cannot be added to cart and should display a warning
  • category Y products should not be mixed with X.

我怎么能做到这一点?

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

I got this code from other post, but its outdated and not satisfactory:

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

谢谢

推荐答案

已更新 (2019)

就像一切都在改变您的专属类别 category X,您需要为此类别使用条件.

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

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

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.

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

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

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

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

  • 检测该车中是否有 cat_x 物品.
  • 在检测到购物车中的一件商品的 cat_x 时移除其他商品并触发正确的消息.

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

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.

您需要将 'cat_x' 替换为您真正的类别 slug (在开始时)...

这篇关于WooCommerce 购物车 - 条件项目类别验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆