Woocommerce Bookings - 如何更改已在购物车中的项目元数据?
Woocommerce Bookings - How do I change item meta which is already in cart?
我正在尝试更改所有可预订产品的元数据,这些产品已经在cart,更具体地说 - end_date 和持续时间,但已经好几天没有结果了...我需要在 woocommerce_before_calculate_totals 行动中完成。我试过这段代码:
if ( $my_condition ) {
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
if ( isset( $cart_item['booking'] ) ) {
$cart_item['booking']->set_duration( $my_new_duration );
}
}
}
还有成千上万种其他方式,但均未成功。
类似的方法适用于 set_price(),它会更改价格,但对于购物车中已存在的产品,可预订的产品元数据(如持续时间和结束日期)似乎无法更改! Google 似乎对此无能为力,因为在搜索几天时我只能找到如何更改价格本身,而不是持续时间或其他元数据。
有人能帮帮我吗?谢谢!
编辑:
简而言之,这就是我要实现的目标 - 假设我的购物车中有这些商品:
- 从 2018-05-10 10:00 到 2018-05-10 16:00
预订的产品 1
- 从 2018-05-10 10:00 到 2018-05-10 17:00
预订的产品 2
并且当我的函数触发时,我购物车中的这两个产品预订范围应该更改为 2018-05-10 10:00 到 2018-05-10 13:30
when my function triggers, both of these products booking range in my
cart should change to 2018-05-10 10:00 to 2018-05-10 13:30
如果您只想设置一个固定的结束时间(例如您的示例中的13:30
),那么尝试以下 function
,我已经尝试并测试过它在 WordPress 4.9.5 上与 WooCommerce 3.3.5 和 WooCommerce Bookings 1.11.1.
一起正常工作
但是,产品的预订时长(在编辑产品的一般选项卡中admin 中的页面)预计是 客户定义的 {n}
小时 块;即类型为customer
,单位为hour
.
// Use `WC_Cart::set_cart_contents()` to actually update the cart (contents).
// See `recalc_bookings_duration()` for an example of how to use this function.
function change_booking_end_time( array &$cart_item, $end_time ) {
if ( ! isset( $cart_item['data'] ) ) {
return false;
}
if ( ! preg_match( '/^\d{2}:\d{2}$/', $end_time ) ) {
return false;
}
if ( ! is_wc_booking_product( $cart_item['data'] ) ) {
//echo 'Not a Bookable product..<br>';
return false;
}
if (
'hour' !== $cart_item['data']->get_duration_unit() ||
'customer' !== $cart_item['data']->get_duration_type()
) {
//echo 'Duration unit/type error.<br>';
return false;
}
$booking_id = $cart_item['booking']['_booking_id'];
$booking = get_wc_booking( $booking_id );
if ( $booking ) {
// Set the end time in 24-hour clock format.
$new_end_time = $end_time;
// Get the timestamp of the `$new_end_time`.
$start_time = $booking->get_start();
$end_time = @strtotime( $new_end_time, $start_time );
if ( ! $end_time ) {
return false;
}
// Update the booking data; in the database.
$_end_time = (int) $booking->get_end();
if ( $end_time !== $_end_time ) {
$booking->set_end( $end_time );
$booking->save();
// Update failed.
$_end_time = (int) $booking->get_end();
if ( $end_time !== $_end_time ) {
//echo '$booking->save() error.<br>';
return false;
}
// The end time / duration already changed.
} else {
//echo 'End time already match.<br>';
return false;
}
// Re-calculate the duration (number of hours).
$duration = abs( $end_time - $start_time ) / ( 60 * 60 );
$cart_item['data']->set_duration( $duration );
// Check/adjust the maximum duration.
$max_duration = $cart_item['data']->get_max_duration();
if ( is_numeric( $max_duration ) && $duration > $max_duration ) {
$cart_item['data']->set_max_duration( ceil( $duration ) );
}
// Check/adjust the minimum duration.
$min_duration = $cart_item['data']->get_min_duration();
if ( is_numeric( $min_duration ) && $duration < $min_duration ) {
$cart_item['data']->set_min_duration( floor( $duration ) );
}
// Update the product data; in the cart.
$cart_item['data']->apply_changes();
// Update the booking data; in the cart.
$cart_item['booking']['_duration'] = $duration;
$cart_item['booking']['duration'] = $duration . ' ' .
_n( 'hour', 'hours', $duration, 'woocommerce-bookings' );
$cart_item['booking']['_end_date'] = $booking->get_end();
return true;
}
}
示例用法
add_action( 'woocommerce_before_calculate_totals', 'recalc_bookings_duration' );
function recalc_bookings_duration( WC_Cart $cart ) {
$cart_items = $cart->get_cart_contents();
$update_cart = false;
foreach ( $cart_items as $cart_item_key => $cart_item ) {
if ( change_booking_end_time( $cart_item, '13:30' ) ) {
$cart_items[ $cart_item_key ] = $cart_item;
$update_cart = true;
}
}
if ( $update_cart ) {
$cart->set_cart_contents( $cart_items );
}
}
我正在尝试更改所有可预订产品的元数据,这些产品已经在cart,更具体地说 - end_date 和持续时间,但已经好几天没有结果了...我需要在 woocommerce_before_calculate_totals 行动中完成。我试过这段代码:
if ( $my_condition ) {
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
if ( isset( $cart_item['booking'] ) ) {
$cart_item['booking']->set_duration( $my_new_duration );
}
}
}
还有成千上万种其他方式,但均未成功。
类似的方法适用于 set_price(),它会更改价格,但对于购物车中已存在的产品,可预订的产品元数据(如持续时间和结束日期)似乎无法更改! Google 似乎对此无能为力,因为在搜索几天时我只能找到如何更改价格本身,而不是持续时间或其他元数据。
有人能帮帮我吗?谢谢!
编辑: 简而言之,这就是我要实现的目标 - 假设我的购物车中有这些商品:
- 从 2018-05-10 10:00 到 2018-05-10 16:00 预订的产品 1
- 从 2018-05-10 10:00 到 2018-05-10 17:00 预订的产品 2
并且当我的函数触发时,我购物车中的这两个产品预订范围应该更改为 2018-05-10 10:00 到 2018-05-10 13:30
when my function triggers, both of these products booking range in my cart should change to 2018-05-10 10:00 to 2018-05-10 13:30
如果您只想设置一个固定的结束时间(例如您的示例中的13:30
),那么尝试以下 function
,我已经尝试并测试过它在 WordPress 4.9.5 上与 WooCommerce 3.3.5 和 WooCommerce Bookings 1.11.1.
但是,产品的预订时长(在编辑产品的一般选项卡中admin 中的页面)预计是 客户定义的 {n}
小时 块;即类型为customer
,单位为hour
.
// Use `WC_Cart::set_cart_contents()` to actually update the cart (contents).
// See `recalc_bookings_duration()` for an example of how to use this function.
function change_booking_end_time( array &$cart_item, $end_time ) {
if ( ! isset( $cart_item['data'] ) ) {
return false;
}
if ( ! preg_match( '/^\d{2}:\d{2}$/', $end_time ) ) {
return false;
}
if ( ! is_wc_booking_product( $cart_item['data'] ) ) {
//echo 'Not a Bookable product..<br>';
return false;
}
if (
'hour' !== $cart_item['data']->get_duration_unit() ||
'customer' !== $cart_item['data']->get_duration_type()
) {
//echo 'Duration unit/type error.<br>';
return false;
}
$booking_id = $cart_item['booking']['_booking_id'];
$booking = get_wc_booking( $booking_id );
if ( $booking ) {
// Set the end time in 24-hour clock format.
$new_end_time = $end_time;
// Get the timestamp of the `$new_end_time`.
$start_time = $booking->get_start();
$end_time = @strtotime( $new_end_time, $start_time );
if ( ! $end_time ) {
return false;
}
// Update the booking data; in the database.
$_end_time = (int) $booking->get_end();
if ( $end_time !== $_end_time ) {
$booking->set_end( $end_time );
$booking->save();
// Update failed.
$_end_time = (int) $booking->get_end();
if ( $end_time !== $_end_time ) {
//echo '$booking->save() error.<br>';
return false;
}
// The end time / duration already changed.
} else {
//echo 'End time already match.<br>';
return false;
}
// Re-calculate the duration (number of hours).
$duration = abs( $end_time - $start_time ) / ( 60 * 60 );
$cart_item['data']->set_duration( $duration );
// Check/adjust the maximum duration.
$max_duration = $cart_item['data']->get_max_duration();
if ( is_numeric( $max_duration ) && $duration > $max_duration ) {
$cart_item['data']->set_max_duration( ceil( $duration ) );
}
// Check/adjust the minimum duration.
$min_duration = $cart_item['data']->get_min_duration();
if ( is_numeric( $min_duration ) && $duration < $min_duration ) {
$cart_item['data']->set_min_duration( floor( $duration ) );
}
// Update the product data; in the cart.
$cart_item['data']->apply_changes();
// Update the booking data; in the cart.
$cart_item['booking']['_duration'] = $duration;
$cart_item['booking']['duration'] = $duration . ' ' .
_n( 'hour', 'hours', $duration, 'woocommerce-bookings' );
$cart_item['booking']['_end_date'] = $booking->get_end();
return true;
}
}
示例用法
add_action( 'woocommerce_before_calculate_totals', 'recalc_bookings_duration' );
function recalc_bookings_duration( WC_Cart $cart ) {
$cart_items = $cart->get_cart_contents();
$update_cart = false;
foreach ( $cart_items as $cart_item_key => $cart_item ) {
if ( change_booking_end_time( $cart_item, '13:30' ) ) {
$cart_items[ $cart_item_key ] = $cart_item;
$update_cart = true;
}
}
if ( $update_cart ) {
$cart->set_cart_contents( $cart_items );
}
}