WooCommerce - 使用自定义整数输入值以编程方式更新产品价格

问题描述 投票:0回答:1
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 等)

wordpress woocommerce
1个回答
0
投票

您的代码中有一些错误以及一些错误的钩子用法。

请尝试以下操作,这将解决您面临的问题:

// 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 文件中(或插件中)。已测试并有效。

© www.soinside.com 2019 - 2024. All rights reserved.