求助:WooCommerce中woocommerce_package_rates钩子运费过滤逻辑失效
问题分析与修复方案
原代码存在几处核心问题导致功能失效,以下是具体问题点和修复后的完整方案:
核心问题梳理
- 商品长度判断逻辑错误:
get_length()可能返回带单位的字符串(比如"25 in"),直接与数字24比较会因类型不匹配失效;且未处理不同单位的转换。 - UPS运费匹配逻辑错误:
strpos('UPS', serialize($rate))参数顺序颠倒,且序列化操作完全多余;同时break会只保留第一个UPS选项,而非所有符合条件的UPS运费。 - 边界情况处理缺失:当既无免运费、也无超长商品时,
rates_arr为空,会导致无运费选项返回。 - 原免运费逻辑未体现:用户提到的"订单满50美元仅保留免运费"逻辑在当前代码中缺失。
修复后的完整代码
add_filter( 'woocommerce_package_rates','deal_with_woocommerce_available_shipping_methods', 10, 2 ); function deal_with_woocommerce_available_shipping_methods( $rates, $package ) { // 无运费选项时直接返回 if ( empty( $rates ) ) { return $rates; } $rates_arr = []; $has_free_shipping = false; $cart_total = WC()->cart->get_subtotal(); // 获取购物车小计(不含运费/税) $has_overlength_item = longestItemLengthOver24(); // 1. 处理满50美元免运费逻辑:仅保留免运费选项 if ( $cart_total >= 50 ) { foreach ( $rates as $rate_id => $rate ) { if ( 'free_shipping' === $rate->method_id ) { $rates_arr[ $rate_id ] = $rate; $has_free_shipping = true; } } // 找到免运费选项则直接返回 if ( $has_free_shipping ) { return $rates_arr; } } // 2. 处理超长商品逻辑:仅保留UPS和免运费选项 if ( $has_overlength_item ) { foreach ( $rates as $rate_id => $rate ) { // 匹配UPS(method_id通常是'ups'或包含'ups',可根据实际插件调整) if ( strpos( strtolower( $rate->method_id ), 'ups' ) !== false || 'free_shipping' === $rate->method_id ) { $rates_arr[ $rate_id ] = $rate; } } } else { // 无超长商品时保留所有原始运费选项 $rates_arr = $rates; } // 3. 运费按价格从低到高排序 $prices = []; foreach( $rates_arr as $rate ) { $prices[] = $rate->cost; } array_multisort( $prices, SORT_ASC, $rates_arr ); return $rates_arr; } function longestItemLengthOver24(){ foreach( WC()->cart->get_cart() as $cart_item ) { $product = $cart_item['data']; $length = $product->get_length(); $unit = $product->get_length_unit(); // 跳过空值 if ( empty( $length ) ) { continue; } // 统一转换为英寸(示例含厘米转英寸,可扩展其他单位) $length_in_inches = (float)$length; if ( strtolower( $unit ) !== 'in' ) { if ( strtolower( $unit ) === 'cm' ) { $length_in_inches = $length * 0.3937; } // 可添加mm、ft等其他单位的转换逻辑 } // 检查是否超过24英寸 if ( $length_in_inches > 24 ) { return true; } } return false; }
关键修复说明
- 长度判断修正:取出商品长度单位,统一转换为英寸后再做数值比较,避免字符串/单位不匹配问题;支持多单位转换扩展。
- UPS匹配修正:直接检查
rate->method_id(无需序列化),用小写转换避免大小写问题,保留所有符合条件的UPS运费,同时保留免运费选项。 - 边界情况修复:无超长商品时直接保留所有原始运费,避免返回空数组;补全了用户提到的满50美元免运费逻辑。
- 排序逻辑保留:维持原有的运费按价格从低到高排序的功能。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

