我正在开发一个操纵定价的 WooCommerce 扩展。 它需要根据用户和产品动态过滤整个商店的定价。 它还需要能够强制某些购物车商品免费。
这两个函数都可以单独工作,但是当我同时使用这两个函数时,免费购物车项目的价格(零)会被动态设置产品价格的函数覆盖。
我目前让它应用客户的独特定价,如下所示(我删除了很多代码以保持与问题的相关性):
add_filter('woocommerce_product_get_price', 'wcds_custom_price', 10, 2);
function wcds_custom_price($price, $product)
{
if (did_action('woocommerce_product_get_price') >= 2) {
return;
}
// get price specific to user and product
$user_id = get_current_user_id();
$price = wcds_get_price($product, $user_id); // This works
return $price;
}
这个效果很好。
然后,对于以编程方式添加到购物车的某些商品,我需要将这些价格覆盖为零。免费商品达到最大数量 - 任何更多数量的赠品产品都会作为单独的订单商品添加,而不会覆盖价格(我再次将其保留在相关代码中):
add_filter('woocommerce_before_calculate_totals', 'wcds_apply_giveaway_pricing', 999, 1);
function wcds_apply_giveaway_pricing($cart)
{
// Do not modify prices in admin
if (is_admin()) {
return;
}
if (did_action('woocommerce_before_calculate_totals') >= 2) {
return;
}
// Example of $giveaway_products (actually set dynamically)
$giveaway_products = array(
'107964' => array
(
'qty' => '2',
'giveaway_post_id' => '127753'
)
);
// Example of $giveaway_products (actually set dynamically from cart contents)
$total_quantities = array(
'107964' => '5'
);
$to_add = array();
// Loop through cart items and split giveaways
foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
$product_id = $cart_item['product_id'];
if (array_key_exists($product_id, $giveaway_products)) {
$total_quantity = $total_quantities[$product_id];
$free_quantity = $giveaway_products[$product_id]['qty'];
$free_quantity = min($total_quantity, $free_quantity);
$paid_quantity = max($total_quantity - $free_quantity, 0);
$to_add[$product_id] = [
'paid' => $paid_quantity,
'free' => $free_quantity,
'giveaway_post_id' => $giveaway_products[$product_id]['giveaway_post_id'],
];
$cart->remove_cart_item($cart_item_key); // Remove original rows for giveaway products
} else {
unset($cart_item['giveaway']); // Remove the giveaway flag if not in the giveaway list
}
}
// Add the giveaway products to the cart with the adjusted quantities
foreach ($to_add as $product_id => $data) {
// Add paid products to cart
if ($data['paid'] > 0) {
$cart->add_to_cart($product_id, $data['paid']);
}
// Add free giveaway products to cart
if ($data['free'] > 0) {
$giveaway_id = $data['giveaway_post_id'];
$cart_item_key = $cart->add_to_cart($product_id, $data['free'], '', '', [
'giveaway' => true,
'giveaway_id' => $giveaway_id,
]);
// Adjust the price for giveaway items
$cart_item = $cart->get_cart_item($cart_item_key);
$cart_item['data']->set_price(0);
$cart_item['data']->set_name('FREE: ' . $cart_item['data']->get_name()); // Optionally change name for giveaways
}
}
}
第二部分成功设置了相关购物车商品的名称,但价格不为零,仍在由
wcds_custom_price
设置。
如果我删除
add_filter('woocommerce_product_get_price', 'wcds_custom_price', 10, 2);
,则添加的购物车商品的价格将成功设置为零。
似乎
woocommerce_product_get_price
在woocommerce_before_calculate_totals
之后触发了几次(我也尝试过woocommerce_get_cart_item_from_session
),在我将其设置为零后再次设置价格。
如何才能同时使用这两种功能?
您始终可以尝试在将购物车商品的价格设置为零之前删除过滤器,然后将其添加回来,例如:
remove_filter('woocommerce_product_get_price', 'wcds_custom_price', 10);
$cart_item['data']->set_price(0);
add_filter('woocommerce_product_get_price', 'wcds_custom_price', 10, 2);
应该可以。