如何让WooCommerce根据非变体产品属性隐藏配送方式?
修改WooCommerce代码使其支持非变体产品属性判断
原代码仅检查购物车项中的变体属性(即$cart_item['variation']存储的字段),但非变体属性(比如简单产品的Season/Brand,或变体产品父产品中未用于变体的属性)不会存放在这个数组里,因此无法触发判断逻辑。以下是修改后的代码,可同时兼容变体与非变体产品属性:
add_filter( 'woocommerce_package_rates', 'hide_shipping_method_based_on_product_attribute', 10, 2 ); function hide_shipping_method_based_on_product_attribute( $rates, $package ) { if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return; // 定义目标属性分类(必须以pa_开头) $taxonomy = 'pa_season'; // 定义需要移除的配送方式ID与对应属性术语slug的映射 $data_array = array( 'free_shipping:8' => array('s24'), 'flat_rate:17' => array('f23'), ); // 遍历购物车内的每个商品 foreach( $package['contents'] as $cart_item ){ // 获取正确的产品对象:如果是变体商品,取父产品;否则直接取当前产品 $product = $cart_item['variation_id'] > 0 ? wc_get_product( $cart_item['product_id'] ) : $cart_item['data']; // 获取当前产品的目标属性术语slug $term_slug = $product->get_attribute( $taxonomy ); // 如果属性存在且不为空 if( !empty($term_slug) ) { // 遍历配送方式映射数组 foreach( $data_array as $rate_id => $target_slugs ) { // 匹配属性slug并移除对应配送方式 if( in_array( strtolower($term_slug), $target_slugs ) && isset($rates[$rate_id]) ) { unset($rates[$rate_id]); } } } } return $rates; }
关键修改说明
- 适配产品类型:通过
$cart_item['variation_id']判断是否为变体产品,变体产品取父产品(非变体属性存储在父产品中),简单产品直接使用自身对象。 - 统一属性获取:使用WooCommerce内置的
get_attribute()方法,可直接获取指定属性的术语slug,无需区分是否为变体属性。 - 大小写兼容:添加
strtolower()确保匹配时不区分大小写(若你的属性slug为严格小写,可移除该函数)。
生效须知
修改代码后,需进入WooCommerce后台的设置 > 配送 > 配送区域,点击任意区域的「更新」按钮,清空配送缓存后新代码才会生效。
内容的提问来源于stack exchange,提问作者Luca Moschetta
相关产品推荐
相关产品推荐

