我在我的单个产品页面中添加了一个自定义编号输入字段.常规价格乘以输入的整值. 例如,如果基本价格为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 );
        }
    }
}

我try 了不同的方法.最好的是在添加一次价格后阻止Woo再次更新,但我也想对某些产品采用分层定价,所以这不是一个 Select .

我还try 了不同的挂钩(add_to_cart、woocommerce_before_calculate_targets等)

推荐答案

您的代码中有一些错误和一些错误的挂钩使用.

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

// 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文件中(或插件中).经过测试并工作.

Php相关问答推荐

显示根据WooCommerce单变量产品中的数量计算得出的汇总

未找到laravel cascadeOnEdit

有条件的运费率基于购物车小计与WooPayments货币转换

允许Laravel路由指定`withTrashed`,尽管有显式的模型绑定

如何使用属性#[Embedded]嵌入带有规则的对象集合?

PHP空数组定义与开始或结束逗号

如何保存基于用户 Select 的复选框 Select 模式

WooCommerce在收据页面获取产品下载URL

在WooCommercestore 页面上显示库存产品属性的值

Mockery在模拟Redis连接时抛出错误:Mockery\Exception\BadMethodCallException

防止在WordPress短代码中显示重复产品并请求代码更正

有没有办法像引用枚举一样引用注册表中的对象?

多个产品类别 Select 自定义 WooCommerce 插件设置页面

PHP 在数组中搜索值

为什么 debug_backtrace() 不返回任何内容?

在特征中使用类的属性

如何搜索和替换 XML 文件中的一段文本?

根据WooCommerce中的产品重量更改简单产品的输入数量步值

docker |管道失败的 ubuntu 源列表

为什么可以从 PHP 类访问 PHP Trait 的私有成员?