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

如何从数据库清除WooCommerce产品零值促销价并隐藏零常规价商品

WooCommerce价格处理与商品隐藏问题

场景与需求

我正在搭建WooCommerce店铺,每天通过产品导入导出插件从厂商FTP获取CSV文件更新产品:

  • 非促销商品的促销价设为0
  • 缺货商品的常规价设为0

需要实现两个核心需求:

  1. 彻底清除数据库中的零值促销价,避免前端显示异常
  2. 隐藏常规价为0的缺货商品,不让它们出现在页面上

此前尝试用两段代码分别实现功能,但同时启用时无法正常工作;当前使用的代码存在两个问题:

  • 零值促销价仍残留于数据库中
  • 商品列表的「按价格排序」功能失效

示例与期望效果

商品常规价促销价状态期望显示
A10000在售显示价格1000
B1000900在售显示促销价900
C0-缺货不显示在页面

额外要求:「按价格排序」功能正常,页面价格筛选能正确识别价格区间(如900-1000)。

此问题关联我之前的提问:How to clear WooCommerce products zero sale price?


原使用代码

#1 价格处理代码

// Adjust product active price
add_filter('woocommerce_product_get_price', 'adjust_product_active_price', 20, 2);
add_filter('woocommerce_product_variation_get_price', 'adjust_product_active_price', 20, 2);
function adjust_product_active_price( $price, $product ) {
    if ( $price == 0 && $product->get_regular_price() > 0 ) {
        return floatval($product->get_regular_price());
    }
    return $price;
}

// Empty product sale price with zero value
add_filter('woocommerce_product_get_sale_price', 'adjust_product_zero_sale_price', 20, 2 );
add_filter('woocommerce_product_variation_get_sale_price', 'adjust_product_zero_sale_price', 20, 2 );
function adjust_product_zero_sale_price( $price, $product ) {
    if ( $price == 0 ) {
        return '';
    }
    return $price;
}

// Utility function (Remove zero sale prices)
function remove_zero_prices( $prices ) {
    foreach( $prices as $key => $price ) {
        if ( $price == 0 ) {
            unset($prices[$key]);
        }
    }
    return $prices;
}

// Adjust displayed variable price
add_filter( 'woocommerce_variable_price_html', 'adjust_variable_price_html', 20, 2 );
function adjust_variable_price_html( $price_html, $product ) {
    $prices = $product->get_variation_prices( true );

    if ( min($prices['sale_price']) > 0 ) {
        return $price_html;
    }
    $active_prices  = remove_zero_prices($prices['price']);
    $regular_prices = $prices['regular_price'];
    $min_price      = min(array_merge($active_prices, $regular_prices));
    $max_price      = max(array_merge($active_prices, $regular_prices));
    $min_reg_price  = current($regular_prices);
    $max_reg_price  = end($regular_prices);

    if ( $product->is_on_sale() && $min_reg_price === $max_reg_price ) {
        $price_html = wc_format_sale_price( wc_price( $max_reg_price ), wc_price( $min_price ) );
    } elseif ( $min_price !== $max_price ) {
        $price_html = wc_format_price_range( $min_price, $max_price );
    } else {
        $price_html = wc_price( $min_price );
    }
    return $price_html;
}

add_filter('woocommerce_product_is_on_sale', 'filter_variable_product_is_on_sale', 20, 2);
function filter_variable_product_is_on_sale( $is_on_sale, $product ) {
    if( $product->is_type('variable') ) {
        $is_on_sale = false;
        
        foreach( $product->get_available_variations('') as $variation ) {
            if( $variation->is_on_sale() ) {
                return true;
            }
        }
    }
    return $is_on_sale;
}

#2 隐藏零常规价商品代码

add_action( 'woocommerce_product_query', 'themelocation_product_query' );
function themelocation_product_query( $q ){
    $meta_query = $q->get( 'meta_query' );
        $meta_query[] = array(
                    'key'       => '_price',
                    'value'     => 0,
                    'compare'   => '='
                );
    $q->set( 'meta_query', $meta_query );
}

修复后的解决方案

1. 彻底清除数据库零促销价(导入后自动处理)

这段代码会在产品导入完成后,自动将促销价为0的商品的促销价字段清空并保存到数据库,从根源解决零值残留问题,同时保证排序和筛选数据准确:

// 导入后自动清除零值促销价
add_action('woocommerce_product_import_finished', 'clear_zero_sale_prices_after_import', 10, 1);
function clear_zero_sale_prices_after_import($import_id) {
    global $wpdb;
    
    // 更新简单产品的零促销价为空
    $wpdb->query("
        UPDATE {$wpdb->prefix}postmeta 
        SET meta_value = '' 
        WHERE meta_key = '_sale_price' AND meta_value = '0'
    ");
    
    // 更新变体产品的零促销价为空
    $wpdb->query("
        UPDATE {$wpdb->prefix}postmeta 
        SET meta_value = '' 
        WHERE meta_key = '_sale_price' AND meta_value = '0' AND post_id IN (
            SELECT ID FROM {$wpdb->prefix}posts WHERE post_type = 'product_variation'
        )
    ");
    
    // 清理产品缓存
    wc_delete_product_transients();
}

// 前端确保促销价为空时显示常规价
add_filter('woocommerce_product_get_price', 'display_regular_price_when_sale_price_empty', 20, 2);
add_filter('woocommerce_product_variation_get_price', 'display_regular_price_when_sale_price_empty', 20, 2);
function display_regular_price_when_sale_price_empty($price, $product) {
    // 如果当前价格为空或0,且常规价大于0,返回常规价
    if ( (empty($price) || $price == 0) && $product->get_regular_price() > 0 ) {
        return floatval($product->get_regular_price());
    }
    return $price;
}

// 修正变量产品的在售状态判断
add_filter('woocommerce_product_is_on_sale', 'correct_variable_product_on_sale_status', 20, 2);
function correct_variable_product_on_sale_status($is_on_sale, $product) {
    if ($product->is_type('variable')) {
        $is_on_sale = false;
        $variations = $product->get_available_variations();
        
        foreach ($variations as $variation_data) {
            $variation = wc_get_product($variation_data['variation_id']);
            if ($variation->get_sale_price() && $variation->get_sale_price() > 0) {
                $is_on_sale = true;
                break;
            }
        }
    }
    return $is_on_sale;
}

// 修正变量产品价格显示
add_filter('woocommerce_variable_price_html', 'correct_variable_price_display', 20, 2);
function correct_variable_price_display($price_html, $product) {
    $variation_prices = $product->get_variation_prices(true);
    $sale_prices = array_filter($variation_prices['sale_price'], function($p) {
        return $p > 0;
    });
    $regular_prices = $variation_prices['regular_price'];
    
    // 有有效促销价时显示促销价格区间
    if (!empty($sale_prices)) {
        $min_sale = min($sale_prices);
        $max_sale = max($sale_prices);
        $min_reg = min($regular_prices);
        $max_reg = max($regular_prices);
        
        if ($min_reg === $max_reg) {
            $price_html = wc_format_sale_price(wc_price($min_reg), wc_price($min_sale));
        } else {
            $price_html = wc_format_price_range($min_sale, $max_sale) . ' <small class="woocommerce-price-suffix">' . __('(促销价)', 'woocommerce') . '</small>';
        }
    } else {
        // 无有效促销价时显示常规价格区间
        $min_reg = min($regular_prices);
        $max_reg = max($regular_prices);
        $price_html = wc_format_price_range($min_reg, $max_reg);
    }
    
    return $price_html;
}

2. 正确隐藏常规价为0的缺货商品

原代码错误使用_price字段,改用_regular_price字段排除常规价为0的商品,同时兼容变量产品(只要所有变体常规价都为0才隐藏):

// 隐藏常规价为0的商品
add_action('woocommerce_product_query', 'exclude_zero_regular_price_products', 20, 1);
function exclude_zero_regular_price_products($q) {
    if (!is_admin() && $q->is_main_query()) {
        $meta_query = $q->get('meta_query', []);
        
        // 排除常规价为0的简单产品
        $meta_query[] = [
            'key'     => '_regular_price',
            'value'   => '0',
            'compare' => '!=',
            'type'    => 'NUMERIC'
        ];
        
        // 处理变量产品:确保至少有一个变体常规价大于0
        $meta_query[] = [
            'relation' => 'OR',
            [
                'key'     => '_product_type',
                'value'   => 'variable',
                'compare' => '!='
            ],
            [
                'key'     => '_regular_price',
                'value'   => '0',
                'compare' => '!=',
                'type'    => 'NUMERIC'
            ]
        ];
        
        $q->set('meta_query', $meta_query);
    }
}

使用说明

  1. 将上述两段修复代码添加到主题的functions.php文件中,或使用代码片段插件管理
  2. 执行一次产品导入,零促销价会被自动清理到数据库
  3. 页面上会自动隐藏常规价为0的商品,价格排序和筛选功能恢复正常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 18:22:33