Woocommerce:仅含Appointment产品时隐藏免邮进度条及调整免邮逻辑
问题解决代码及说明
原代码存在的问题
woocommerce_package_rates钩子的函数参数错误,该钩子仅接收$rates和$package,不存在$order参数,原代码中调用$order->get_items()会直接报错- 第二个函数中
$item变量未定义,直接调用$item->get_product()会触发PHP错误 - 未实现“仅包含Appointment产品时不显示进度条”的核心逻辑,原代码逻辑混乱
修正后的完整代码
// 调整免费配送规则 add_filter( 'woocommerce_package_rates', 'ecommercehints_free_shipping_for_specific_products', 10, 2 ); function ecommercehints_free_shipping_for_specific_products($rates, $package) { $has_non_appointment = false; $cart_total = WC()->cart->get_subtotal(); // 遍历购物车中的所有商品 foreach ( $package['contents'] as $item ) { $product = $item['data']; if( !$product->is_type('Appointment') ){ $has_non_appointment = true; break; } } // 如果存在非Appointment类型商品且购物车总额不足50,移除免费配送选项 if( $has_non_appointment && $cart_total < 50 ) { unset( $rates['free_shipping:21'] ); // 替换为你的免费配送方法ID } return $rates; } // 显示免费配送进度条(仅当购物车不全是Appointment产品时) add_action( 'woocommerce_checkout_before_order_review', 'ecommercehints_checkout_page_progress_bar', 10 ); function ecommercehints_checkout_page_progress_bar() { $cart_total = WC()->cart->get_subtotal(); $free_shipping_threshold = 50; $cart_remaining = $free_shipping_threshold - $cart_total; // 判断购物车是否仅包含Appointment类型产品 $only_appointment = true; foreach ( WC()->cart->get_cart() as $item ) { $product = $item['data']; if( !$product->is_type('Appointment') ){ $only_appointment = false; break; } } // 仅当购物车不全是Appointment产品时,显示进度条或提示 if ( !$only_appointment ) { if ($cart_total < $free_shipping_threshold ) { echo '再消费 ' . get_woocommerce_currency_symbol() . $cart_remaining . ' 即可享受免费配送!<br><progress id="freeshippingprogress" max="' . $free_shipping_threshold . '" value="' . $cart_total . '"></progress>'; } else { echo '您已解锁免费配送!'; } } }
代码关键说明
- 修正钩子参数错误:
woocommerce_package_rates钩子正确使用$package参数获取购物车商品,而非不存在的$order参数 - 新增全Appointment产品判断逻辑:通过遍历购物车所有商品,标记是否仅包含Appointment类型产品
- 进度条显示控制:只有当购物车中存在非Appointment产品时,才显示免费配送相关提示或进度条;若全是Appointment产品,则不显示任何相关内容
- 代码健壮性优化:将免费配送阈值设为变量
$free_shipping_threshold,方便后续修改;修复原代码中未定义变量的问题
内容的提问来源于stack exchange,提问作者Marco Crisgod
相关产品推荐
相关产品推荐

