You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WooCommerce禁止指定商品类别混加购物车问题求助

问题:WooCommerce商品类别互斥规则实现修复

需求说明

  • 允许混加的类别:cheese、cheese-sets、bread、bakery、milk(这些类别商品可互相添加至购物车)
  • 禁止混加的类别:glamp、horse、foodtruck、other、farm(这些类别既不能和允许类别混加,也不能互相混加)
  • 触发规则时:跳转回商品页并显示错误提示

现有问题

参考代码修改后,仅能阻止允许类别与禁止类别混加,但禁止类别之间的商品仍可同时加入购物车,无法触发限制规则。

原参考代码

<?php
//*** Prevent mixture of paint and other prods in same cart ***//
function dont_add_paint_to_cart_containing_other($validation, $product_id) {

// Set flag false until we find a product in cat paint
    $cart_has_paint = false;

// Set $cat_check true if a cart item is in paint cat
    foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item) {

        $product = $cart_item['data'];

        if (has_term('paint', 'product_cat', $product->id)) {
            $cart_has_paint = true;
            // break because we only need one "true" to matter here
            break;
        }
    }

    $product_is_paint = false;
    if (has_term('paint', 'product_cat', $product_id)) {
        $product_is_paint = true;
    }

// Return true if cart empty
    if (!WC()->cart->get_cart_contents_count() == 0) {
        // If cart contains paint and product to be added is not paint, display error message and return false.
        if ($cart_has_paint && !$product_is_paint) {
            wc_add_notice('Sorry, you can only purchase paint products on their own. To purchase this product, please checkout your current cart or empty your cart and try again', 'error');
            $validation = false;
        }
        // If cart contains a product that is not paint and product to be added is paint, display error message and return false.
        elseif (!$cart_has_paint && $product_is_paint) {
            wc_add_notice('Sorry, you can only purchase paint products on their own. To purchase this product, please checkout your current cart or empty your cart and try again', 'error');
            $validation = false;
        }
    }
    // Otherwise, return true.
    return $validation;
}

add_filter('woocommerce_add_to_cart_validation', 'dont_add_paint_to_cart_containing_other', 10, 2);
?>

修改后未完全生效的代码

<?php
//*** Prevent mixture of certain categories in same cart ***//
function dont_add_categories_to_cart_containing_other($validation, $product_id) {
    // Set flag false until we find a product in prohibited categories
    $cart_has_prohibited = false;
    // Prohibited categories
    $prohibited_categories = array(
        'glamp',
        'horse',
        'foodtruck',
        'other',
        'farm'
    );
    // Allowed categories
    $allowed_categories = array(
        'cheese',
        'cheese-sets',
        'bread',
        'bakery',
        'milk'
    );

    // Set $cat_check true if a cart item is in prohibited categories
    foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item) {
        $product = $cart_item['data'];
        $product_categories = wp_get_post_terms($product->id, 'product_cat', array("fields" => "slugs"));
        $intersect_categories = array_intersect($prohibited_categories, $product_categories);

        if (!empty($intersect_categories)) {
            $cart_has_prohibited = true;
            // break because we only need one "true" to matter here
            break;
        }
    }

    $product_categories = wp_get_post_terms($product_id, 'product_cat', array("fields" => "slugs"));
    $intersect_categories = array_intersect($prohibited_categories, $product_categories);
    $product_is_prohibited = !empty($intersect_categories);

    // Return true if cart empty
    if (!WC()->cart->is_empty()) {
        // If cart contains prohibited categories and product to be added is not prohibited, display error message and return false.
        if ($cart_has_prohibited && !$product_is_prohibited) {
            wc_add_notice('Sorry, you can only purchase products from the allowed categories. Please checkout your current cart or empty your cart and try again.', 'error');
            $validation = false;
        }
        // If cart contains a product that is not prohibited and product to be added is from the prohibited categories, display error message and return false.
        elseif (!$cart_has_prohibited && $product_is_prohibited) {
            wc_add_notice('Sorry, you can only purchase products from the allowed categories. Please checkout your current cart or empty your cart and try again.', 'error');
            $validation = false;
        }
    }
    // Otherwise, return true.
    return $validation;
}

add_filter('woocommerce_add_to_cart_validation', 'dont_add_categories_to_cart_containing_other', 10, 2);
?>

修复后的代码及说明

问题核心在于原修改代码仅判断购物车是否存在禁止类别商品,未限制禁止类别之间的互加——只要同属禁止类别就允许添加,不符合需求。

修复思路:

  1. 区分购物车的三种状态:空、含允许类别商品、含禁止类别商品
  2. 针对禁止类别状态,新增判断:只要购物车已有某禁止类别商品,新添加的禁止类别商品无论属于哪个子类,都直接阻止
  3. 优化类别判断逻辑,适配WooCommerce最新属性调用规范

修复后的代码:

<?php
//*** Prevent mixture of certain categories in same cart ***//
function dont_add_categories_to_cart_containing_other($validation, $product_id) {
    // 定义类别组
    $allowed_categories = array('cheese', 'cheese-sets', 'bread', 'bakery', 'milk');
    $prohibited_categories = array('glamp', 'horse', 'foodtruck', 'other', 'farm');

    // 获取当前要添加商品的类别归属
    $current_product_cats = wp_get_post_terms($product_id, 'product_cat', array("fields" => "slugs"));
    $is_allowed = !empty(array_intersect($allowed_categories, $current_product_cats));
    $is_prohibited = !empty(array_intersect($prohibited_categories, $current_product_cats));

    // 购物车为空时直接通过验证
    if (WC()->cart->is_empty()) {
        return $validation;
    }

    // 检查购物车中已有商品的类别状态
    $cart_has_allowed = false;
    $cart_has_prohibited = false;

    foreach (WC()->cart->get_cart() as $cart_item) {
        $cart_product_cats = wp_get_post_terms($cart_item['data']->get_id(), 'product_cat', array("fields" => "slugs"));
        
        // 判断购物车是否包含允许类别商品
        if (!empty(array_intersect($allowed_categories, $cart_product_cats))) {
            $cart_has_allowed = true;
            break;
        }
        
        // 判断购物车是否包含禁止类别商品
        if (!empty(array_intersect($prohibited_categories, $cart_product_cats))) {
            $cart_has_prohibited = true;
            break;
        }
    }

    // 执行规则验证
    if ($cart_has_allowed) {
        // 购物车有允许类别商品,仅能添加同组允许类别
        if (!$is_allowed) {
            wc_add_notice('抱歉,当前购物车商品仅能与奶酪、面包、牛奶类商品混加,请先结算或清空购物车后再添加该商品。', 'error');
            $validation = false;
        }
    } elseif ($cart_has_prohibited) {
        // 购物车有禁止类别商品,既不能加允许类别,也不能加其他禁止类别
        if ($is_allowed || $is_prohibited) {
            wc_add_notice('抱歉,该类别商品无法与当前购物车商品混加,请先结算或清空购物车后再添加。', 'error');
            $validation = false;
        }
    }

    return $validation;
}

add_filter('woocommerce_add_to_cart_validation', 'dont_add_categories_to_cart_containing_other', 10, 2);
?>

代码说明:

  • 新增$cart_has_allowed状态判断,确保允许类别组内仅能添加同组商品
  • 针对禁止类别组,只要购物车已有任意禁止类别商品,新添加的任何禁止类别商品都会被阻止
  • 使用get_id()替代旧版的id属性,适配WooCommerce 3.0+版本的对象调用规范
  • 优化错误提示文案,让用户更清晰理解限制规则

内容的提问来源于stack exchange,提问作者Bubble

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 13:23:10