购物车含多品类商品时隐藏指定自定义配送方式
问题解决:WooCommerce混合品类购物车隐藏特定配送方式
问题背景
已通过插件实现:当商品分类为baby-care且收货国家为India时,生成ID为pisol_extended_flat_shipping:52540的配送方式,该功能正常。需求是:当购物车同时包含baby-care品类与其他品类商品时,在结账环节隐藏该配送方式,原尝试代码未生效。
原代码
function check_cart_categories() { $baby_care = false; $other_categories = false; foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) { $product = $cart_item['data']; if ( has_term( 'baby-care', 'product_cat', $product->id ) ) { $baby_care = true; } else { $other_categories = true; } } return ( $baby_care && $other_categories ); } add_filter( 'woocommerce_available_shipping_methods', 'hide_pisol_extended_flat_shipping' ); function hide_pisol_extended_flat_shipping( $available_methods ) { if ( check_cart_categories() ) { unset( $available_methods['pisol_extended_flat_shipping:52540'] ); } return $available_methods; }
问题分析
- 钩子选择不合适:
woocommerce_available_shipping_methods在新版WooCommerce中优先级低,且不处理包裹级配送逻辑,推荐用woocommerce_package_rates钩子。 - 产品ID调用过时:WooCommerce 3.0+版本中,产品ID需通过
get_id()方法获取,不能直接访问$product->id属性。 - 未处理缓存问题:WooCommerce会缓存配送方式,修改后需清除缓存才能生效。
修正后的代码
function check_cart_mixed_categories() { $has_baby_care = false; $has_other_cats = false; foreach ( WC()->cart->get_cart() as $cart_item ) { $product = $cart_item['data']; // 检查商品是否属于baby-care分类 if ( has_term( 'baby-care', 'product_cat', $product->get_id() ) ) { $has_baby_care = true; } else { // 确认商品属于其他分类 $product_cats = get_the_terms( $product->get_id(), 'product_cat' ); if ( ! empty( $product_cats ) ) { $has_other_cats = true; } } // 满足条件后提前终止循环,提升效率 if ( $has_baby_care && $has_other_cats ) { break; } } return $has_baby_care && $has_other_cats; } add_filter( 'woocommerce_package_rates', 'hide_pisol_shipping_for_mixed_carts', 10, 2 ); function hide_pisol_shipping_for_mixed_carts( $rates, $package ) { // 仅在购物车同时包含两类商品时执行 if ( check_cart_mixed_categories() ) { foreach ( $rates as $rate_id => $rate ) { if ( $rate_id === 'pisol_extended_flat_shipping:52540' ) { unset( $rates[$rate_id] ); break; } } } return $rates; } // 购物车更新时清除配送方式缓存,确保修改立即生效 add_action( 'woocommerce_cart_updated', 'clear_shipping_method_cache' ); function clear_shipping_method_cache() { WC()->session->set( 'shipping_methods', null ); }
代码说明
- 改用
woocommerce_package_rates钩子:针对每个包裹的配送方式处理,更贴合WooCommerce配送逻辑。 - 优化分类检查逻辑:提前终止循环减少不必要的遍历,同时确保准确判断非
baby-care品类商品的存在。 - 添加缓存清除:购物车更新时重置配送方式缓存,避免修改后无法立即生效。
内容的提问来源于stack exchange,提问作者chirag
相关产品推荐
相关产品推荐

