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
相关产品推荐
相关产品推荐

