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

woocommerce_package_rates过滤后配送方式选择异常求助:默认未选中+购物车选后失效

WooCommerce配送方式过滤函数的默认选中问题修复

你的代码实现了「有免费配送时禁用付费配送」的核心功能,但出现的两个问题本质是修改配送方式数组时破坏了WooCommerce依赖的键名和选中状态标记,以下是针对性的修复方案:

问题根源

  1. 你用array_unshift()和[]添加配送方式时,会重置数组的数字索引,而WooCommerce是通过配送方式的id(作为数组键名)来跟踪选中状态的,索引丢失后系统无法匹配之前选中的选项。
  2. 新添加的配送方式(比如修改后的fermopoint)没有继承或设置selected属性,导致页面加载时没有默认选中项。

修复后的完整代码

add_filter( 'woocommerce_package_rates', 'disable_paid_shipping', 9999, 2 );
function disable_paid_shipping( $rates, $package ) {
    $free_rates = array();
    $selected_rate_id = '';

    // 先记录原本选中的配送方式ID
    foreach ( $rates as $rate_id => $rate ) {
        if ( $rate->selected ) {
            $selected_rate_id = $rate_id;
        }

        // 收集原有免费配送方式,保留原键名
        if ( str_contains( $rate->label, "gratuita" ) || str_contains( $rate->label, "gratuito" ) ) {
            $free_rates[$rate_id] = $rate;
        }
    }

    // 处理fermopoint并加入免费列表(保留原键名)
    if ( isset( $rates['fermopoint'] ) ) {
        $fermopoint = $rates['fermopoint'];
        $fermopoint->cost = 0;
        $fermopoint->label .= ' gratuito';
        // 保留原键名,确保系统能识别
        $free_rates[$fermopoint->id] = $fermopoint;
    }

    // 处理local并加入免费列表(保留原键名)
    if ( isset( $rates['local'] ) ) {
        $free_rates[$rates['local']->id] = $rates['local'];
    }

    if ( !empty( $free_rates ) ) {
        // 确保有默认选中项:优先保留原本选中的(如果它在免费列表里),否则选第一个
        $has_selected = false;
        foreach ( $free_rates as $rate_id => $rate ) {
            if ( $rate_id === $selected_rate_id ) {
                $rate->selected = true;
                $has_selected = true;
                break;
            }
        }
        if ( !$has_selected ) {
            reset( $free_rates );
            $first_rate_id = key( $free_rates );
            $free_rates[$first_rate_id]->selected = true;
        }

        $rates = $free_rates;
    }

    return $rates;
}

关键改动说明

  1. 保留原数组键名:所有加入$free_rates的配送方式都使用原rate->id作为键名,WooCommerce能通过键名匹配选中状态,避免购物车AJAX刷新后选中状态丢失。
  2. 跟踪并恢复选中状态:先记录原本选中的配送方式ID,如果它在免费列表里就保持选中;如果没有,自动选中第一个免费配送方式,解决默认不选中的问题。
  3. 避免索引重置:不再使用array_unshift()这类会重置索引的函数,直接通过键名添加元素,保持数组结构的一致性。

额外注意事项

  • 确保fermopoint和local的ID匹配你实际的配送方式ID,代码里的$rates['fermopoint']需要对应后台配置的配送方式ID。
  • 测试前请清空WooCommerce缓存(WooCommerce > 状态 > 工具 > 清除配送缓存),避免旧的配送方式数据干扰。

内容的提问来源于stack exchange,提问作者checkm

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 01:20:18