如何通过代码控制WooCommerce商品变体促销价的启用/禁用?
编程控制WooCommerce商品变体促销价的启用与禁用
可以通过WooCommerce的价格过滤钩子结合自定义元数据的日期判断实现需求,核心逻辑是:在获取变体促销价时,检查当前日期是否落在自定义元数据指定的任意日期范围内,若不在则返回空值,从而禁用促销价。
实现步骤与代码示例
假设你的自定义元数据键名为_sale_date_ranges,存储格式为JSON数组(每个元素包含start和end日期,格式为Y-m-d),示例值如下:
[{"start":"2024-05-01","end":"2024-05-10"},{"start":"2024-06-01","end":"2024-06-10"}]
将以下代码添加到主题的functions.php文件或自定义插件中:
add_filter('woocommerce_get_variation_sale_price', 'control_variation_sale_price_via_date_ranges', 10, 3); function control_variation_sale_price_via_date_ranges($sale_price, $variation, $product) { // 获取当前日期(与元数据日期格式保持一致) $current_date = date('Y-m-d'); // 获取变体的自定义日期范围元数据 $date_ranges_meta = $variation->get_meta('_sale_date_ranges'); if (empty($date_ranges_meta)) { // 无日期范围数据,保持原有促销价状态 return $sale_price; } // 解析JSON格式的日期范围 $date_ranges = json_decode($date_ranges_meta, true); if (!is_array($date_ranges)) { return $sale_price; } // 检查当前日期是否在任意一个日期范围内 $is_in_valid_range = false; foreach ($date_ranges as $range) { if (!isset($range['start'], $range['end'])) { continue; } // 转为时间戳进行日期比较,避免格式差异问题 $start_ts = strtotime($range['start']); $end_ts = strtotime($range['end']); $current_ts = strtotime($current_date); if ($current_ts >= $start_ts && $current_ts <= $end_ts) { $is_in_valid_range = true; break; } } // 不在有效日期范围内则禁用促销价 if (!$is_in_valid_range) { return ''; } // 在范围内则返回原促销价 return $sale_price; }
关键细节说明
- 钩子选择:使用
woocommerce_get_variation_sale_price钩子直接过滤变体促销价的返回值,返回空值时WooCommerce会自动切换为显示常规价格。 - 日期处理:统一使用
Y-m-d格式,通过时间戳比较避免日期格式不一致导致的判断错误。 - 容错处理:若元数据为空或JSON格式错误,保留原有促销价逻辑,避免影响商品正常展示。
测试与排查
- 给目标变体添加
_sale_date_ranges元数据,填入符合格式的日期范围。 - 测试当前日期在范围内时,变体应显示促销价;不在范围内时,仅显示常规价格。
- 若未生效,检查以下几点:
- 元数据键名是否与代码中的
_sale_date_ranges完全一致。 - JSON格式是否合法(可通过在线JSON校验工具验证)。
- WooCommerce价格缓存是否需要刷新(可在WooCommerce设置中清除缓存,或临时禁用缓存插件测试)。
- 元数据键名是否与代码中的
内容的提问来源于stack exchange,提问作者Ako Si
相关产品推荐
相关产品推荐

