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

WooCommerce 基于父产品类别设置购物车加购限制(Cat A无限制)

原代码核心问题
  • 数组取值逻辑错误:原代码写的! $product_cats['cat-a-slug'],是把数组下标当成键名调用。因为$product_cats是循环把分类对象push进去生成的索引数组,根本没有cat-a-slug这个键,这个判断永远返回真,等于完全没排除Cat A的商品
  • 校验范围跑偏:原逻辑没有锁定Cat B这个顶级父类的范围,把所有非Cat A关联的商品都拉进拦截规则,导致Cat A的商品被误限制,根本没走到放行分支
修正后逻辑

严格卡需求边界,全程不用记任何子分类ID:

  • 先查待加购商品是不是Cat A的:是就直接放行,啥校验都不跑
  • 再查待加购商品是不是Cat B范畴的(含所有层级子分类):不是就直接放行
  • 待加购确实是Cat B范畴的商品,再遍历购物车:只要购物车里已经有任意一个Cat B的商品,就拦住加购,弹错误提示;如果购物车只有Cat A的商品,正常加
可直接运行的修正代码
// 替换为站点实际的顶级分类slug,无需修改后续逻辑
define('CATEGORY_A_SLUG', 'cat-a'); // 替换为Cat A的实际slug
define('CATEGORY_B_SLUG', 'cat-b'); // 替换为Cat B的实际slug

add_filter( 'woocommerce_add_to_cart_validation', 'custom_cat_b_add_to_cart_check', 10, 3 );
function custom_cat_b_add_to_cart_check( $passed, $product_id, $quantity ) {
    // 通用判断:识别商品是否属于指定顶级分类(覆盖所有层级子分类)
    $check_top_category = function(int $product_id, string $target_slug): bool {
        $product_terms = get_the_terms( $product_id, 'product_cat' );
        if ( empty($product_terms) || is_wp_error($product_terms) ) return false;

        foreach ( $product_terms as $term ) {
            // 匹配当前商品直接绑定的分类本身
            if ( $term->slug === $target_slug ) return true;
            // 匹配分类的所有上级祖先层级,不遗漏跨级子分类
            $ancestors = get_ancestors( $term->term_id, 'product_cat' );
            foreach ( $ancestors as $ancestor_id ) {
                $ancestor_term = get_term( $ancestor_id, 'product_cat' );
                if ( $ancestor_term->slug === $target_slug ) return true;
            }
        }
        return false;
    };

    // Cat A类商品完全放行,不触发校验
    if ( $check_top_category( $product_id, CATEGORY_A_SLUG ) ) {
        return $passed;
    }

    // 非Cat B范畴的商品直接放行
    if ( ! $check_top_category( $product_id, CATEGORY_B_SLUG ) ) {
        return $passed;
    }

    // 遍历购物车,检查是否已有Cat B类商品
    foreach ( WC()->cart->get_cart() as $cart_item ) {
        if ( $check_top_category( $cart_item['product_id'], CATEGORY_B_SLUG ) ) {
            $passed = false;
            wc_add_notice( '购物车中仅可存在一个Cat B分类下的商品,请先移除现有Cat B类商品后再操作', 'error' );
            break;
        }
    }

    return $passed;
}
适配说明
  • 后续Cat B的子分类不管怎么增删改,代码都能自动识别,不用手动更新子分类ID列表
  • 如果想把Cat B的所有子分类都改成独立顶级分类,只要把判断逻辑改成“待加购商品如果属于Cat A就放行,其余非Cat A的顶级分类商品统一按‘购物车仅存一件’的规则校验”就行,核心流程不用动
  • Cat A的商品完全不受限,想加多少加多少,也能和任意数量的Cat B商品同时在购物车里

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.26 04:54:01