基于可变产品属性隐藏WooCommerce配送方式的代码失效排查
代码问题排查与修正
核心问题分析
你的代码无法实现预期功能,主要存在以下几个问题:
- 遗漏关键配送方式ID:需求中要求含
digitale变体时隐藏free_shipping:5,但你的$data_array完全没有配置这个配送方式,直接导致该规则失效。 - 错误的返回逻辑:函数开头的
if (is_admin() && !defined('DOING_AJAX')) return;直接返回空值,而非原始的$rates,会导致后台非AJAX场景下配送方式显示异常。 - 数据结构适配性差:原数组结构以配送方式ID为键,无法高效处理一个属性对应多个配送方式的场景(比如
digitale需要隐藏两种配送方式),逻辑易混乱。 - 未考虑WooCommerce缓存:配送方式数据会被WooCommerce缓存,修改代码后若不清除缓存,新规则不会即时生效。
修正后的代码
add_filter( 'woocommerce_package_rates', 'ts_hide_shipping_method_based_on_variation_product_attribute', 10, 2 ); function ts_hide_shipping_method_based_on_variation_product_attribute( $rates, $package ) { // 后台非AJAX请求时,直接返回原始配送方式 if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return $rates; // 产品属性 taxonomy(固定以pa_开头) $taxonomy = 'pa_versione'; // 调整数据结构:属性slug => 要隐藏的配送方式ID数组 $hide_rules = array( 'digitale' => array('free_shipping:5', 'flat_rate:3'), 'cartaceo' => array('free_shipping:4'), ); // 标记是否需要隐藏对应的配送方式 $to_hide = array(); // 遍历购物车商品 foreach( $package['contents'] as $cart_item ){ // 检查当前商品是否是变体且包含目标属性 if( isset($cart_item['variation']['attribute_'.$taxonomy]) ) { $term_slug = $cart_item['variation']['attribute_'.$taxonomy]; // 如果当前属性slug有对应的隐藏规则,合并到待隐藏列表 if( isset($hide_rules[$term_slug]) ) { $to_hide = array_merge($to_hide, $hide_rules[$term_slug]); } } } // 去重并移除对应的配送方式 $to_hide = array_unique($to_hide); foreach( $to_hide as $rate_id ) { if( isset($rates[$rate_id]) ) { unset($rates[$rate_id]); } } return $rates; }
生效步骤
- 将修正后的代码替换原代码,添加到主题的
functions.php文件或自定义插件中。 - 清除WooCommerce配送缓存:进入WooCommerce设置→配送选项,随便修改一个设置后保存,或在前台购物车页面按
Ctrl+F5强制刷新页面。
内容的提问来源于stack exchange,提问作者Simone Apicella
相关产品推荐
相关产品推荐

