在woocommerce_before_calculate_totals钩子中,set_price计算添加了两次

时间:2017-08-09 18:29:29

标签: php wordpress woocommerce cart product

我在我的网站上使用Woocommerce和Event Ticket插件,我不得不硬编码选择字段,以便在客户购买机票时根据他们的选择,价格会相应提高。

它的大部分似乎都运行正常,然后选择被保存为购物车数据的一部分。然后我会在点击“添加到购物车”按钮后尝试更新产品价格,以便将新值添加到产品价格中。

以下是我所拥有的,似乎是在更新价格,但令人烦恼的是它将 $pickup_price 值添加两次(因此,而不是3,它会增加6)< / em>的。

奇怪的是,如果我在篮子阶段更改数量并更新,它会获得正确的值,而不是在最初添加时。

我做错了什么以及如何防止这个问题?

这是我的代码:

add_action( 'woocommerce_before_calculate_totals', 'add_pickup_cost', 10, 1 );
function add_pickup_cost( $cart_object, $cart_item_data ) {

     foreach ( $cart_object->get_cart() as $cart_item ) {

          $wc_product = $cart_item['data'];
          // My custom field which is returning the additional cost
          $pickup_price = $cart_item['pickupOptions'];

          $product_price = method_exists( $wc_product, 'get_price' ) ? floatval($wc_product->get_price()) : floatval($wc_product->price);
          $new_price = $product_price + $pickup_price;
          method_exists( $wc_product, 'set_price' ) ? $wc_product->set_price( $new_price ) : $wc_product->price = $new_price;
     }
}

1 个答案:

答案 0 :(得分:1)

你错过了一些小事,我已经简化了你的代码:

add_action( 'woocommerce_before_calculate_totals', 'add_pickup_cost', 10, 2 );
function add_pickup_cost( $cart ) {

    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
        return;

    foreach ( $cart->get_cart() as $cart_item ) {
        if( isset( $cart_item['pickupOptions'] ) && ! empty( $cart_item['pickupOptions'] ) ){
        // WC_Product object instance
        $product = $cart_item['data'];

        // Get cart item price
        $price  = method_exists( $product, 'get_price' ) ? floatval($product->get_price()) : floatval($product->price);
        $price += (float) $cart_item['pickupOptions']; // Add "Pickup option to the price

        // Set the new price
        if( method_exists( $product, 'set_price' ) ) 
            $product->set_price( $price )
        else
            $product->price = $price;
        }
    }
}

代码放在活动子主题(或主题)的function.php文件中,或者放在任何插件文件中。

经过测试和工作。