自定义动态项目定价在 Woocommerce Checkout 上重置
Custom dynamic item pricing gets reset on Woocommerce Checkout
我无法让价格更新生效。或多或少,这是我用来更新价格的示例:
add_action( 'woocommerce_before_calculate_totals', 'cst_product_quantity_discounter', 10 );
function cst_product_quantity_discounter( $cart_object ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ){
return;
}
if( ! isset( WC()->session->reload_checkout ) ) {
// declare woocommerce global
global $woocommerce;
// array of ID's to match that represent each item
$special_ids_array = [
0 => array( "id" => 15372, "product" => "TAF", "single_bag_price" => 42.99, "3_multiplier" => 0.82181902768 ),
1 => array( "id" => 14285, "product" => "POW", "single_bag_price" => 29.99, "3_multiplier" => 0.8890741358 )
];
// gather cart object
$wc_cart = WC()->cart->get_cart();
foreach( $wc_cart as $cart_item ){
// gather relevant data for testing and comparisons
$product_id = $cart_item['product_id'];
$product_key = $cart_item['key'];
$pack_size_attribute = $cart_item['variation']['attribute_pa_sample-check']; // returns: "full-pack" || "sample" || null
$item_quantity = $cart_item['quantity'];
foreach ( $special_ids_array as $id_test_2 ) {
if ( $product_id === $id_test_2["id"] && $pack_size_attribute !== "sample" ){
foreach ( $cart_object->cart_contents as $key => $value ) {
// if the key matches we will set the price of the correct product
if ( $key === $product_key ){
$discounted_price = 10;
$value['data']->set_price($discounted_price);
}
}
}
}
}
}
}
还有一些其他的东西可以让我们看到这些值,但它确实有效。这将在我的测试购物车页面上更新,一切看起来都很好。
我的问题是,当我转到我的测试结帐页面时,价格会短暂更新,然后被原始价格覆盖。我在结帐时遗漏了一些 运行 的更新,并且 woocommerce_before_calculate_totals
挂钩似乎没有在结帐页面上进行永久更改。
我需要在哪里挂钩我的函数,以便无论结帐时发生的负载覆盖初始成功的价格更改,更改都会持续存在?
您的代码中有些奇怪的地方:
$cart_object
(即 WC_Cart
对象)已经是挂钩函数中的一个参数 (它取代了 WC()->cart
或过时的 $woocommerce->cart
)…
- 所以
WC()->cart->get_cart()
和$cart_object->cart_contents
是一回事。最好的方法是在 foreach 循环中使用 $cart_object->get_cart()
。
- 您不需要
global $woocommerce;
,因为它已包含在 WC()
中(全局 Woocommerce 对象已包含在 $cart_object
中)
reload_checkout
不存在于 WC_Sessions
或 WC_Session_Handler
类 (所以你的条件总是正确的) 和无论如何,这对这个钩子没有用。
- 有关信息
$cart_item['data']
是此购物车商品的 WC_Product
对象的一个实例。
- 你有 2 个购物车环,一个在另一个中,你可以将所有东西合二为一(这样可以避免问题)。
$cart_item['key']
和 $key
(在购物车循环中) 始终是同一件事。在这种情况下你真的不需要使用它......
- 您已在问题的新编辑中完全删除了价格计算,并且定价不再是动态的(像以前一样基于产品数量)。
So I have tried to add back a kind of dynamic price calculation in more real conditions, but in a different way based on your $special_ids_array
array keys/values.
The calculated dynamic price discount start with a quantity of 3 by item that match the conditions (Product Ids et "pack size" attribute).
所以所有这些都简化和压缩了这段重新访问的代码:
add_action( 'woocommerce_before_calculate_totals', 'custom_product_quantity_discounter', 10, 1 );
function custom_product_quantity_discounter( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
// array of ID's to match that represent each item
$special_ids = array(
0 => array( "id" => 15372, "product" => "TAF", "single_bag_price" => 42.99, "3_multiplier" => 0.82181902768 ),
1 => array( "id" => 14285, "product" => "POW", "single_bag_price" => 29.99, "3_multiplier" => 0.8890741358 ),
);
// Loop through the cart items
foreach( $cart->get_cart() as $cart_item ){
$product_id = $cart_item['product_id'];
$quantity = $cart_item['quantity'];
$pack_size = $cart_item['variation']['attribute_pa_sample-check']; // returns "full-pack", "sample" or null
foreach ( $special_ids as $special_id ){
if( $special_id['id'] == $product_id && $pack_size !== 'sample' && $quantity >= 3 ){
$discounted_price = $special_id['single_bag_price'] * $special_id['3_multiplier']; // calculation (fake and custom)
$cart_item['data']->set_price($discounted_price); // set the calculated price
}
}
}
}
代码进入活动子主题(或活动主题)的 function.php 文件。
已测试并有效。
The dynamic calculated pricing based on cart item quantities and custom calculation persist in checkout even when reloading the page multiple times.
我无法让价格更新生效。或多或少,这是我用来更新价格的示例:
add_action( 'woocommerce_before_calculate_totals', 'cst_product_quantity_discounter', 10 );
function cst_product_quantity_discounter( $cart_object ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ){
return;
}
if( ! isset( WC()->session->reload_checkout ) ) {
// declare woocommerce global
global $woocommerce;
// array of ID's to match that represent each item
$special_ids_array = [
0 => array( "id" => 15372, "product" => "TAF", "single_bag_price" => 42.99, "3_multiplier" => 0.82181902768 ),
1 => array( "id" => 14285, "product" => "POW", "single_bag_price" => 29.99, "3_multiplier" => 0.8890741358 )
];
// gather cart object
$wc_cart = WC()->cart->get_cart();
foreach( $wc_cart as $cart_item ){
// gather relevant data for testing and comparisons
$product_id = $cart_item['product_id'];
$product_key = $cart_item['key'];
$pack_size_attribute = $cart_item['variation']['attribute_pa_sample-check']; // returns: "full-pack" || "sample" || null
$item_quantity = $cart_item['quantity'];
foreach ( $special_ids_array as $id_test_2 ) {
if ( $product_id === $id_test_2["id"] && $pack_size_attribute !== "sample" ){
foreach ( $cart_object->cart_contents as $key => $value ) {
// if the key matches we will set the price of the correct product
if ( $key === $product_key ){
$discounted_price = 10;
$value['data']->set_price($discounted_price);
}
}
}
}
}
}
}
还有一些其他的东西可以让我们看到这些值,但它确实有效。这将在我的测试购物车页面上更新,一切看起来都很好。
我的问题是,当我转到我的测试结帐页面时,价格会短暂更新,然后被原始价格覆盖。我在结帐时遗漏了一些 运行 的更新,并且 woocommerce_before_calculate_totals
挂钩似乎没有在结帐页面上进行永久更改。
我需要在哪里挂钩我的函数,以便无论结帐时发生的负载覆盖初始成功的价格更改,更改都会持续存在?
您的代码中有些奇怪的地方:
$cart_object
(即WC_Cart
对象)已经是挂钩函数中的一个参数 (它取代了WC()->cart
或过时的$woocommerce->cart
)…- 所以
WC()->cart->get_cart()
和$cart_object->cart_contents
是一回事。最好的方法是在 foreach 循环中使用$cart_object->get_cart()
。 - 您不需要
global $woocommerce;
,因为它已包含在WC()
中(全局 Woocommerce 对象已包含在$cart_object
中) reload_checkout
不存在于WC_Sessions
或WC_Session_Handler
类 (所以你的条件总是正确的) 和无论如何,这对这个钩子没有用。- 有关信息
$cart_item['data']
是此购物车商品的WC_Product
对象的一个实例。 - 你有 2 个购物车环,一个在另一个中,你可以将所有东西合二为一(这样可以避免问题)。
$cart_item['key']
和$key
(在购物车循环中) 始终是同一件事。在这种情况下你真的不需要使用它......- 您已在问题的新编辑中完全删除了价格计算,并且定价不再是动态的(像以前一样基于产品数量)。
So I have tried to add back a kind of dynamic price calculation in more real conditions, but in a different way based on your
$special_ids_array
array keys/values.The calculated dynamic price discount start with a quantity of 3 by item that match the conditions (Product Ids et "pack size" attribute).
所以所有这些都简化和压缩了这段重新访问的代码:
add_action( 'woocommerce_before_calculate_totals', 'custom_product_quantity_discounter', 10, 1 );
function custom_product_quantity_discounter( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
// array of ID's to match that represent each item
$special_ids = array(
0 => array( "id" => 15372, "product" => "TAF", "single_bag_price" => 42.99, "3_multiplier" => 0.82181902768 ),
1 => array( "id" => 14285, "product" => "POW", "single_bag_price" => 29.99, "3_multiplier" => 0.8890741358 ),
);
// Loop through the cart items
foreach( $cart->get_cart() as $cart_item ){
$product_id = $cart_item['product_id'];
$quantity = $cart_item['quantity'];
$pack_size = $cart_item['variation']['attribute_pa_sample-check']; // returns "full-pack", "sample" or null
foreach ( $special_ids as $special_id ){
if( $special_id['id'] == $product_id && $pack_size !== 'sample' && $quantity >= 3 ){
$discounted_price = $special_id['single_bag_price'] * $special_id['3_multiplier']; // calculation (fake and custom)
$cart_item['data']->set_price($discounted_price); // set the calculated price
}
}
}
}
代码进入活动子主题(或活动主题)的 function.php 文件。
已测试并有效。
The dynamic calculated pricing based on cart item quantities and custom calculation persist in checkout even when reloading the page multiple times.