问题
I want to know how to update the price calculation depending on some internal coding. This is the price that needs to go into the cart item and thus far, the cart item shows only the base cost of the product.
Technically the price should be altered, when a product is added to the cart.
I figured it had to be calculated like this:
global $woocommerce;
$items = $woocommerce->cart->get_cart();
foreach($items as $item => $values) {
if ($value['product_id'] == $product_id) {
$value['data']->set_price($price);
}
}
Since this does not do the trick, where/when do I need to put the set_price() function. When this is called, the cart is still empty and the loop is not entered.
My problem seems to be with Woocommerce Bookings as with following line $this->price is not set and then get_base_cost is called resulting in only showing the base cost and not the "recalculated" price. Since it is a bookable product, this seems to make it more tricky.
public function get_price($context = ‘view’) {
return apply_filters( 'woocommerce_get_price', $this->price ? $this->price : $this->get_base_cost(), $this );
}
Looking closely at $this I can at least see both prices within the class_wc_product_booking, where 300 is the "base cost" and 250 the recalculated price that has to be paid.
I did delete a lot of the array that should not be relevant for this issue.
WC_Product_Booking Object (
[availability_rules:WC_Product_Booking:private] => Array ( )
[object_type:protected] => product
[post_type:protected] => product
[cache_group:protected] => products
[data:protected] =>
Array (
[name] => Booking Test
[slug] => Booking Test
[sku] =>
[price] => 300
[regular_price] =>
[sale_price] =>
[rating_counts] => Array ( )
[average_rating] => 0
[review_count] => 0
)
[supports:protected] => Array ( )
[id:protected] => 1708
[changes:protected] => Array ( [price] => 250 )
[meta_data:protected] =>
[product_type] => booking
)
回答1:
Are you trying to change the price custom way before sending to the cart if yes then you need to send by session the below two hooks will help a lot
add_filter( 'woocommerce_add_cart_item' , 'set_woo_prices');
add_filter( 'woocommerce_get_cart_item_from_session', 'set_session_prices', 20 , 3 );
function set_woo_prices( $woo_data ) {
session_start();
$tac_dd_discounted_price = $_SESSION['']; // get the updated new price field
if ( ! isset($tac_dd_discounted_price ) || empty ($tac_dd_discounted_price ) ) { return $woo_data; }
$woo_data['data']->set_price( $tac_dd_discounted_price );
$woo_data['my_price'] = $tac_dd_discounted_price;
return $woo_data;
}
function set_session_prices ( $woo_data , $values , $key ) {
if ( ! isset( $woo_data['my_price'] ) || empty ( $woo_data['my_price'] ) ) { return $woo_data; }
$woo_data['data']->set_price( $woo_data['my_price'] );
return $woo_data;
}
回答2:
This needs to be done on woocommerce_before_calculate_totals
action hook, to work. Below a working example where it adds 30 to each product price in cart items:
add_action( 'woocommerce_before_calculate_totals', 'custom_cart_item_price', 10, 1 );
function custom_cart_item_price( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
foreach ( $cart->get_cart() as $cart_item ){
$price = $cart_item['data']->get_price(); // Get the product price
$new_price = $price + 30; // the calculation
$cart_item['data']->set_price( $new_price ); // Set the new price
}
}
This code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Note:
global $woocommerce;
with$woocommerce->cart
is outdated and has been replaced byWC()->cart
instead.
来源:https://stackoverflow.com/questions/47882716/custom-cart-items-price-calculation-for-woocommerce-bookings