为WooCommerce简单产品添加自定义角色定价选项
为WooCommerce简单产品实现基于用户角色的自定义定价
我已经为WooCommerce可变产品搭建了基于用户角色的自定义定价功能,当前效果是在产品变体的定价选项区域添加了三个自定义价格字段:General、Food、Hot Food,对应不同用户角色的专属定价。
实现该功能的代码如下:
// Add custom fields to variations option pricing add_action( 'woocommerce_variation_options_pricing', 'add_variation_options_pricing', 20, 3 ); function add_variation_options_pricing( $loop, $variation_data, $post_variation ) { $value1 = get_post_meta( $post_variation->ID, '_food_price', true ); $value2 = get_post_meta( $post_variation->ID, '_hot_food_price', true ); $value3 = get_post_meta( $post_variation->ID, '_general_price', true ); $symbol = ' (' . get_woocommerce_currency_symbol() . ')'; $key_1 = '_food_price[' . $loop . ']'; $key_2 = '_hot_food_price[' . $loop . ']'; $key_3 = '_general_price[' . $loop . ']'; // General echo '<div class="variable_general-price"><p class="form-row form-row-first"> <label>' . __( "General", "woocommerce" ) . $symbol . '</label> <input type="text" size="5" name="' . $key_3 .'" value="' . esc_attr( $value3 ) . '" /> </p></div>'; // Food echo '<div class="variable_food-price"><p class="form-row form-row-first"> <label>' . __( "Food", "woocommerce" ) . $symbol . '</label> <input type="text" size="5" name="' . $key_1 .'" value="' . esc_attr( $value1 ) . '" /> </p></div>'; // Hot Food echo '<div class="variable_hot-food-price"><p class="form-row form-row-first"> <label>' . __( "Hot Food", "woocommerce" ) . $symbol . '</label> <input type="text" size="5" name="' . $key_2 .'" value="' . esc_attr( $value2 ) . '" /> </p></div>'; } // Save variations prices custom fields values add_action( 'woocommerce_save_product_variation', 'save_product_variation_price', 20, 2 ); function save_product_variation_price( $variation_id, $i ) { if ( isset( $_POST['_food_price'][$i] ) ) { update_post_meta( $variation_id, '_food_price', floatval( $_POST['_food_price'][$i] ) ); } if ( isset( $_POST['_hot_food_price'][$i] ) ) { update_post_meta( $variation_id, '_hot_food_price', floatval( $_POST['_hot_food_price'][$i] ) ); } if ( isset( $_POST['_general_price'][$i] ) ) { update_post_meta( $variation_id, '_general_price', floatval( $_POST['_general_price'][$i] ) ); } } // Variable product price range add_filter('woocommerce_variation_prices_price', 'variation_price', 900, 2 ); // Product variations (of a variable product) add_filter('woocommerce_product_variation_get_price', 'variation_price', 900, 2 ); function variation_price( $price, $object ) { if( is_user_logged_in() ) { // Hot Food User if ( current_user_can( 'stallholder') && current_user_can( 'hot_food' ) ) { $new_price = (float) get_post_meta( $object->get_id(), '_hot_food_price', true ); $price = empty($new_price) ? $price : $new_price; } // Food User elseif ( current_user_can( 'stallholder') && current_user_can( 'food' ) ){ $new_price = (float) get_post_meta( $object->get_id(), '_food_price', true ); $price = empty($new_price) ? $price : $new_price; } // General User else { $new_price = (float) get_post_meta( $object->get_id(), '_general_price', true ); $price = empty($new_price) ? $price : $new_price; } } return $price; }
现在需要为WooCommerce简单产品实现相同功能,将这三个自定义定价字段添加到简单产品的定价选项区域(常规价格/销售价格下方)。
解决方案代码
以下代码可在简单产品的定价面板添加对应字段,并实现保存和前端价格替换逻辑,同时兼容已有的可变产品功能:
// 1. 为简单产品添加自定义定价字段 add_action( 'woocommerce_product_options_pricing', 'add_simple_product_custom_pricing_fields' ); function add_simple_product_custom_pricing_fields() { global $post; $symbol = ' (' . get_woocommerce_currency_symbol() . ')'; // General 价格字段 echo '<div class="simple_general-price"> <p class="form-row form-row-first"> <label>' . __( "General", "woocommerce" ) . $symbol . '</label> <input type="text" size="5" name="_general_price" value="' . esc_attr( get_post_meta( $post->ID, '_general_price', true ) ) . '" /> </p> </div>'; // Food 价格字段 echo '<div class="simple_food-price"> <p class="form-row form-row-first"> <label>' . __( "Food", "woocommerce" ) . $symbol . '</label> <input type="text" size="5" name="_food_price" value="' . esc_attr( get_post_meta( $post->ID, '_food_price', true ) ) . '" /> </p> </div>'; // Hot Food 价格字段 echo '<div class="simple_hot-food-price"> <p class="form-row form-row-first"> <label>' . __( "Hot Food", "woocommerce" ) . $symbol . '</label> <input type="text" size="5" name="_hot_food_price" value="' . esc_attr( get_post_meta( $post->ID, '_hot_food_price', true ) ) . '" /> </p> </div>'; } // 2. 保存简单产品的自定义定价字段值 add_action( 'woocommerce_process_product_meta', 'save_simple_product_custom_pricing_fields' ); function save_simple_product_custom_pricing_fields( $post_id ) { if ( isset( $_POST['_food_price'] ) ) { update_post_meta( $post_id, '_food_price', floatval( $_POST['_food_price'] ) ); } if ( isset( $_POST['_hot_food_price'] ) ) { update_post_meta( $post_id, '_hot_food_price', floatval( $_POST['_hot_food_price'] ) ); } if ( isset( $_POST['_general_price'] ) ) { update_post_meta( $post_id, '_general_price', floatval( $_POST['_general_price'] ) ); } } // 3. 替换简单产品的前端显示价格 add_filter( 'woocommerce_product_get_price', 'simple_product_role_based_pricing', 900, 2 ); add_filter( 'woocommerce_product_get_regular_price', 'simple_product_role_based_pricing', 900, 2 ); function simple_product_role_based_pricing( $price, $product ) { if ( ! $product->is_type( 'simple' ) || ! is_user_logged_in() ) { return $price; } // Hot Food 用户角色 if ( current_user_can( 'stallholder' ) && current_user_can( 'hot_food' ) ) { $new_price = (float) get_post_meta( $product->get_id(), '_hot_food_price', true ); $price = empty( $new_price ) ? $price : $new_price; } // Food 用户角色 elseif ( current_user_can( 'stallholder' ) && current_user_can( 'food' ) ) { $new_price = (float) get_post_meta( $product->get_id(), '_food_price', true ); $price = empty( $new_price ) ? $price : $new_price; } // 普通用户 else { $new_price = (float) get_post_meta( $product->get_id(), '_general_price', true ); $price = empty( $new_price ) ? $price : $new_price; } return $price; }
代码说明
- 字段添加:使用
woocommerce_product_options_pricing钩子,在简单产品的定价面板下方插入三个自定义价格字段,样式和可变产品的字段保持一致。 - 字段保存:通过
woocommerce_process_product_meta钩子处理简单产品的字段保存逻辑,将值存储为产品元数据。 - 价格替换:利用
woocommerce_product_get_price和woocommerce_product_get_regular_price钩子,根据当前登录用户的角色替换显示价格,逻辑和可变产品完全一致。
内容的提问来源于stack exchange,提问作者JWCreative
相关产品推荐
相关产品推荐

