WooCommerce:如何基于指定属性分类永久调整变体商品价格
解决方案
要实现永久联动的属性溢价规则,核心是在商品/变体保存时自动触发价格计算,而非手动单次修改。以下是调整后的实现方案:
关键改进点
- 绑定WooCommerce商品保存钩子,确保后台修改价格时自动重新计算溢价
- 优化属性匹配逻辑,避免空格导致的匹配失败
- 基于变体基础价格动态计算溢价,确保价格联动更新
完整代码
// 绑定可变商品保存钩子:后台保存整个可变商品时触发批量更新 add_action('woocommerce_process_product_meta_variable', 'update_premium_color_prices', 10, 1); // 绑定变体保存钩子:单独保存某个变体时触发单条更新 add_action('woocommerce_save_product_variation', 'update_single_premium_variation_price', 10, 2); /** * 批量更新所有变体的溢价价格 * @param int $product_id 可变商品ID */ function update_premium_color_prices($product_id) { $product = wc_get_product($product_id); if (!$product || $product->get_type() !== 'variable') return; // 获取ACF中的溢价颜色列表(若为全局字段则保留3096,若为商品专属字段则替换为$product_id) $premium_list = get_field("color_list", 3096); if (empty($premium_list)) return; // 处理颜色列表,去除每个颜色前后的空格 $premium_colors = array_map('trim', explode(",", $premium_list)); // 遍历所有变体执行价格更新 foreach ($product->get_children() as $variation_id) { update_variation_premium_price($variation_id, $premium_colors); } } /** * 更新单个变体的溢价价格 * @param int $variation_id 变体ID * @param int $i WooCommerce内部循环索引(未使用) */ function update_single_premium_variation_price($variation_id, $i) { // 获取溢价颜色列表(同全局/商品字段规则) $premium_list = get_field("color_list", 3096); if (empty($premium_list)) return; $premium_colors = array_map('trim', explode(",", $premium_list)); update_variation_premium_price($variation_id, $premium_colors); } /** * 核心逻辑:计算并更新单个变体的价格 * @param int $variation_id 变体ID * @param array $premium_colors 溢价颜色列表 */ function update_variation_premium_price($variation_id, $premium_colors) { $variation = wc_get_product($variation_id); if (!$variation) return; // 获取变体的颜色属性显示值(需与ACF中填写的名称一致,如"Yellow") $variation_color = $variation->get_attribute('pa_color'); if (empty($variation_color)) return; // 获取变体的基础常规价格 $base_price = (float)$variation->get_regular_price(); if ($base_price <= 0) return; // 计算最终价格:溢价颜色上浮20%,非溢价颜色保持基础价 $final_price = in_array($variation_color, $premium_colors) ? ceil($base_price * 1.2) : $base_price; // 更新变体的常规价和前台显示价 update_post_meta($variation_id, '_regular_price', $final_price); update_post_meta($variation_id, '_price', $final_price); // (可选)若需对销售价也应用溢价规则,取消以下注释 // $base_sale_price = (float)$variation->get_sale_price(); // if ($base_sale_price > 0) { // $final_sale_price = in_array($variation_color, $premium_colors) ? ceil($base_sale_price * 1.2) : $base_sale_price; // update_post_meta($variation_id, '_sale_price', $final_sale_price); // } }
代码说明
- 钩子触发时机:
- 保存整个可变商品时,批量更新所有变体价格;单独保存变体时,仅更新当前变体
- 颜色列表处理:用
array_map('trim', ...)清理输入的颜色名称,避免因空格导致匹配失败 - 属性获取优化:使用
get_attribute('pa_color')规范获取变体颜色值,替代原代码直接访问数组的写法 - 价格联动逻辑:每次保存都基于变体的基础价格重新计算,确保后台修改基础价后,溢价价格自动同步更新
注意事项
- 若ACF字段为商品专属设置,请将代码中
get_field("color_list", 3096)的3096替换为对应商品ID(如$product_id) - 确认属性slug
pa_color与后台实际颜色属性slug一致,可在WooCommerce「产品 > 属性」中查看 - 测试前建议备份商品数据,避免价格错误
内容的提问来源于stack exchange,提问作者FoxInBox
相关产品推荐
相关产品推荐

