You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:WooCommerce中woocommerce_package_rates钩子运费过滤逻辑失效

问题分析与修复方案

原代码存在几处核心问题导致功能失效,以下是具体问题点和修复后的完整方案:


核心问题梳理

  1. 商品长度判断逻辑错误:get_length()可能返回带单位的字符串(比如"25 in"),直接与数字24比较会因类型不匹配失效;且未处理不同单位的转换。
  2. UPS运费匹配逻辑错误:strpos('UPS', serialize($rate))参数顺序颠倒,且序列化操作完全多余;同时break会只保留第一个UPS选项,而非所有符合条件的UPS运费。
  3. 边界情况处理缺失:当既无免运费、也无超长商品时,rates_arr为空,会导致无运费选项返回。
  4. 原免运费逻辑未体现:用户提到的"订单满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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 14:19:52