如何从数据库清除WooCommerce产品零值促销价并隐藏零常规价商品
WooCommerce价格处理与商品隐藏问题
场景与需求
我正在搭建WooCommerce店铺,每天通过产品导入导出插件从厂商FTP获取CSV文件更新产品:
- 非促销商品的促销价设为0
- 缺货商品的常规价设为0
需要实现两个核心需求:
- 彻底清除数据库中的零值促销价,避免前端显示异常
- 隐藏常规价为0的缺货商品,不让它们出现在页面上
此前尝试用两段代码分别实现功能,但同时启用时无法正常工作;当前使用的代码存在两个问题:
- 零值促销价仍残留于数据库中
- 商品列表的「按价格排序」功能失效
示例与期望效果
| 商品 | 常规价 | 促销价 | 状态 | 期望显示 |
|---|---|---|---|---|
| A | 1000 | 0 | 在售 | 显示价格1000 |
| B | 1000 | 900 | 在售 | 显示促销价900 |
| C | 0 | - | 缺货 | 不显示在页面 |
额外要求:「按价格排序」功能正常,页面价格筛选能正确识别价格区间(如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); } }
使用说明
- 将上述两段修复代码添加到主题的
functions.php文件中,或使用代码片段插件管理 - 执行一次产品导入,零促销价会被自动清理到数据库
- 页面上会自动隐藏常规价为0的商品,价格排序和筛选功能恢复正常
内容的提问来源于stack exchange,提问作者Balazs
相关产品推荐
相关产品推荐

