WordPress: 6.5.2
WooCommerce: 8.8.3
我将自定义整数输入字段添加到我的单个产品模板中。常规价格乘以提供的整数。例如基本价格为 10 美元,用户在整数字段中输入 2,新价格为 20 美元。
更新价格工作正常,但是当用户进入购物车并更新购物车中产品的数量时,价格会重新计算。例如新计算的价格为 20 美元(上面的示例),用户将购物车中的数量从 1 更改为 5,自定义整数字段再次重新计算价格,因此 20 美元再次乘以 2,现在为 40 美元。但我不明白为什么会发生这种情况...
这是我当前的代码
add_action( 'woocommerce_after_add_to_cart_quantity', 'add_custom_input_number_field', 0 );
function add_custom_input_number_field() {
echo '<div class="custom-input-number-field">';
echo '<label>' . __( 'Custom Input Number', 'woocommerce' ) . '</label>';
echo '<input type="number" required="true" placeholder="max. 30.500" class="custom-input-number" name="custom_input_number" min="1" step="0.001" />';
echo '</div>';
}
add_filter( 'woocommerce_get_price_html', 'update_product_price_based_on_custom_input_on_product_page', 9999, 2 );
function update_product_price_based_on_custom_input_on_product_page( $price, $product ) {
if ( is_product() && isset( $_POST['custom_input_number'] ) ) {
$custom_input_value = (float) $_POST['custom_input_number'];
$product_price = $product->get_price();
$new_price = $product_price * $custom_input_value;
$price = wc_price( $new_price ) . $product->get_price_suffix();
}
return $price;
}
add_filter( 'woocommerce_add_cart_item_data', 'save_custom_input_number_field_data', 10, 2 );
function save_custom_input_number_field_data( $cart_item_data, $product_id ) {
if ( isset( $_POST['custom_input_number'] ) ) {
$cart_item_data['custom_input_number'] = wc_clean( $_POST['custom_input_number'] );
$cart_item_data['custom_input_number'] = (float) $cart_item_data['custom_input_number'];
}
return $cart_item_data;
}
add_action( 'woocommerce_before_calculate_totals', 'update_product_price_based_on_custom_input_in_cart', 10, 1 );
function update_product_price_based_on_custom_input_in_cart( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
return;
}
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
if ( isset( $cart_item['custom_input_number'] ) ) {
$custom_input_value = $cart_item['custom_input_number'];
$product = $cart_item['data'];
$product_price = $product->get_price();
$new_price = $product_price * $custom_input_value;
$product->set_price( $new_price );
}
}
}
我尝试了不同的方法。最好的方法是阻止 Woo 在添加一次价格后再次更新价格,但我也想对某些产品使用分层定价,所以这不是一个选择。
我还尝试了不同的钩子(add_to_cart、woocommerce_before_calculate_totals 等)
您的代码中有一些错误以及一些错误的钩子用法。
请尝试以下操作,这将解决您面临的问题:
// Additional custom input field in single product
add_action( 'woocommerce_after_add_to_cart_quantity', 'add_custom_input_number_field', 0 );
function add_custom_input_number_field() {
echo '<div class="custom-input-number-field">
<label>' . __( 'Custom Input Number', 'woocommerce' ) . '</label>
<input type="number" required="true" placeholder="max. 30.500" class="custom-input-number" name="custom_number" min="1" step="0.001" />
</div>';
}
// Save custom input field value as custom cart item data
add_filter( 'woocommerce_add_cart_item_data', 'save_custom_input_number_field_data', 10, 2 );
function save_custom_input_number_field_data( $item_data, $product_id ) {
if (isset( $_POST['custom_number']) ) {
$item_data['custom_number'] = floatval($_POST['custom_number']);
}
return $item_data;
}
// Change and set cart item custom calculated price
add_action( 'woocommerce_before_calculate_totals', 'update_product_price_based_on_custom_input_in_cart', 10, 1 );
function update_product_price_based_on_custom_input_in_cart( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
foreach ( $cart->get_cart() as $item ) {
if ( isset($item['custom_number']) && $item['custom_number'] ) {
$item['data']->set_price( $item['data']->get_price() * $item['custom_number'] );
}
}
}
// Cart and mini cart displayed calculated price
add_filter( 'woocommerce_cart_item_price', 'filter_cart_item_price', 10, 2 );
function filter_cart_item_price( $price_html, $cart_item ) {
if( isset($cart_item['custom_number']) && $cart_item['custom_number'] ) {
$product = wc_get_product( $cart_item['variation_id'] > 0 ? $cart_item['variation_id'] : $cart_item['product_id'] );
$args = array('price' => ($product->get_price() * $cart_item['custom_number']));
if ( WC()->cart->display_prices_including_tax() ) {
$product_price = wc_get_price_including_tax( $cart_item['data'], $args );
} else {
$product_price = wc_get_price_excluding_tax( $cart_item['data'], $args );
}
return wc_price( $product_price );
}
return $price_html;
}
代码位于子主题的functions.php 文件中(或插件中)。已测试并有效。