如何覆盖已由 woocommerce_product_get_price 过滤的 WooCommerce 购物车商品价格?

问题描述 投票:0回答:1

我正在开发一个操纵定价的 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
),在我将其设置为零后再次设置价格。

如何才能同时使用这两种功能?

php woocommerce hook-woocommerce cart
1个回答
0
投票

您始终可以尝试在将购物车商品的价格设置为零之前删除过滤器,然后将其添加回来,例如:

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);

应该可以。

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