基于非变体产品属性控制WooCommerce多种配送方式显示
WooCommerce 按产品季节属性控制配送方式的解决方案
需求说明
- 产品属性:所有产品包含 Size、Colour(用于生成产品变体)、Season、Brand(不用于变体)四个属性
- 已配置三种配送方式:
- 无最低订单要求的免费配送(ID 17)
- 满100欧元免邮的免费配送(ID 8)
- 固定费用9.99欧元的付费配送(ID 1)
- 配送规则:
- 仅购买S24季产品时,启用ID 8(满100欧免邮)和ID 1(付费配送)
- 仅购买F23季产品时,启用ID 8(满100欧免邮)和ID 1(付费配送)
- 同时购买至少一件S24季和一件F23季产品时,仅启用ID 17(无门槛免邮)
原代码问题
原代码仅支持读取用于变体的属性,无法正确获取非变体属性Season的值,导致配送规则无法按需求生效。
修复后的代码
add_filter( 'woocommerce_package_rates', 'control_shipping_based_on_season_attribute', 10, 2 ); function control_shipping_based_on_season_attribute( $rates, $package ) { if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return; $season_taxonomy = 'pa_season'; $has_s24 = false; $has_f23 = false; // 遍历购物车商品,标记是否包含S24或F23季产品 foreach( $package['contents'] as $item ){ // 变体商品取父产品,普通商品直接取当前商品 $target_product = $item['variation_id'] > 0 ? wc_get_product($item['product_id']) : $item['data']; // 获取产品的Season属性slug $season_slugs = wp_get_post_terms( $target_product->get_id(), $season_taxonomy, array('fields' => 'slugs') ); if( in_array('s24', $season_slugs) ) $has_s24 = true; if( in_array('f23', $season_slugs) ) $has_f23 = true; } // 根据不同场景过滤配送方式 if( $has_s24 && $has_f23 ) { // 同时包含S24和F23:仅保留无门槛免邮 foreach( $rates as $rate_id => $rate ) { if( $rate_id !== 'free_shipping:17' ) unset($rates[$rate_id]); } } elseif( $has_s24 || $has_f23 ) { // 仅单一季节:移除无门槛免邮,保留满额免邮和付费配送 unset($rates['free_shipping:17']); } // 刷新配送费率缓存,确保修改生效 foreach ( $rates as $rate ) { $rate->set_cost( $rate->get_cost() ); } return $rates; }
代码逻辑说明
- 属性读取:通过
wp_get_post_terms直接读取产品的Season属性(不受是否为变体属性的限制),准确识别购物车中是否包含S24或F23季产品 - 场景判断:
- 同时存在两种季节产品时,仅保留无门槛免邮
- 仅存在单一季节产品时,移除无门槛免邮,保留满额免邮和付费配送
- 缓存刷新:修改配送方式后刷新费率缓存,确保前端能实时显示正确的配送选项
内容的提问来源于stack exchange,提问作者Luca Moschetta
相关产品推荐
相关产品推荐

