Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement/317-169 Ability to set product-level check-in/out times #328

Merged
merged 14 commits into from
May 12, 2023
Merged
4 changes: 2 additions & 2 deletions includes/class-wc-accommodation-booking-cart-manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ function add_to_cart() {
*/
public function get_item_data( $other_data, $cart_item ) {
if ( 'accommodation-booking' === $cart_item['data']->get_type() && ! empty( $other_data ) ) {
$check_in = WC_Product_Accommodation_Booking::get_check_times( 'in' );
$check_out = WC_Product_Accommodation_Booking::get_check_times( 'out' );
$check_in = WC_Product_Accommodation_Booking::get_check_times( 'in', $cart_item['product_id'] );
$check_out = WC_Product_Accommodation_Booking::get_check_times( 'out', $cart_item['product_id'] );
$end_date = date_i18n( get_option( 'date_format'), $cart_item['booking']['_end_date'] );

if ( ! empty( $check_in ) ) {
Expand Down
6 changes: 3 additions & 3 deletions includes/class-wc-accommodation-booking-date-picker.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ public function __construct() {
* @return mixed
*/
public function add_accommodation_posted_data( $data, $product, $total_duration ) {
$check_in = WC_Product_Accommodation_Booking::get_check_times( 'in' );
$check_out = WC_Product_Accommodation_Booking::get_check_times( 'out' );
$check_in = WC_Product_Accommodation_Booking::get_check_times( 'in', $product->get_id() );
$check_out = WC_Product_Accommodation_Booking::get_check_times( 'out', $product->get_id() );

if ( 'night' === $product->get_duration_unit() ) {
$data['_start_date'] = strtotime( "{$data['_year']}-{$data['_month']}-{$data['_day']} $check_in" );
Expand Down Expand Up @@ -106,7 +106,7 @@ public function add_partially_booked_dates( $booked_data_array, $product ) {
continue;
}

$check_in_time = $product->get_check_times( 'in' );
$check_in_time = $product->get_check_times( 'in', $product->get_id() );
if ( 'in' === $which ) {
$check_time = strtotime( '-1 day ' . $check_in_time , $time );
} else {
Expand Down
4 changes: 2 additions & 2 deletions includes/class-wc-accommodation-booking-order-manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ public function add_checkinout_info_to_order_email( $item_id, $item, $order ) {
return;
}

$check_in = WC_Product_Accommodation_Booking::get_check_times( 'in' );
$check_out = WC_Product_Accommodation_Booking::get_check_times( 'out' );
$check_in = WC_Product_Accommodation_Booking::get_check_times( 'in', $item['product_id'] );
$check_out = WC_Product_Accommodation_Booking::get_check_times( 'out', $item['product_id'] );
?>
<p>
<strong><?php esc_html_e( 'Check-in', 'woocommerce-accommodation-bookings' ); ?> </strong>
Expand Down
16 changes: 12 additions & 4 deletions includes/class-wc-accommodation-booking-product-tabs.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
*/
class WC_Accommodation_Booking_Product_Tabs {

/**
* Product ID.
*/
public $product_id = 0;

/**
* Hook into WooCommerce..
*/
Expand All @@ -22,8 +27,8 @@ public function __construct() {
* @return boolean
*/
public function are_time_fields_filled_out() {
$check_in = WC_Product_Accommodation_Booking::get_check_times( 'in' );
$check_out = WC_Product_Accommodation_Booking::get_check_times( 'out' );
$check_in = WC_Product_Accommodation_Booking::get_check_times( 'in', $this->product_id );
$check_out = WC_Product_Accommodation_Booking::get_check_times( 'out', $this->product_id );

if ( empty( $check_in ) ) {
return false;
Expand Down Expand Up @@ -56,6 +61,9 @@ public function add_time_tab( $tabs = array() ) {
return $tabs;
}

// Set the product ID.
$this->product_id = $post->ID;

if ( ! $this->are_time_fields_filled_out() ) {
return $tabs;
}
Expand All @@ -77,8 +85,8 @@ public function add_time_tab_content() {
if ( ! $this->are_time_fields_filled_out() ) {
return;
}
$check_in = WC_Product_Accommodation_Booking::get_check_times( 'in' );
$check_out = WC_Product_Accommodation_Booking::get_check_times( 'out' );
$check_in = WC_Product_Accommodation_Booking::get_check_times( 'in', $this->product_id );
$check_out = WC_Product_Accommodation_Booking::get_check_times( 'out', $this->product_id );
?>
<h2><?php echo esc_html( apply_filters( 'woocommerce_accommodation_booking_time_tab_heading', __( 'Arriving/leaving', 'woocommerce-accommodation-bookings' ) ) ); ?></h2>
<ul>
Expand Down
11 changes: 4 additions & 7 deletions includes/class-wc-accommodation-booking.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,10 @@ public function add_checkin_time_to_booking_start_time( $date, $booking ) {
return $date;
}

$check_in = WC_Product_Accommodation_Booking::get_check_times( 'in' );

$date_format = apply_filters( 'woocommerce_bookings_date_format', wc_date_format() );
$time_format = apply_filters( 'woocommerce_bookings_time_format', ', ' . wc_time_format() );

return date_i18n( $date_format, $booking->start ) . date_i18n( $time_format, strtotime( "Today " . $check_in ) );
return date_i18n( $date_format, $booking->start ) . date_i18n( $time_format, $booking->start );
}

public function add_checkout_time_to_booking_end_time( $date, $booking ) {
Expand All @@ -123,11 +121,10 @@ public function add_checkout_time_to_booking_end_time( $date, $booking ) {
return $date;
}

$check_out = WC_Product_Accommodation_Booking::get_check_times( 'out' );
$date_format = apply_filters( 'woocommerce_bookings_date_format', wc_date_format() );
$time_format = apply_filters( 'woocommerce_bookings_time_format', ', ' . wc_time_format() );

return date_i18n( $date_format, $booking->end ) . date_i18n( $time_format, strtotime( "Today " . $check_out ) );
return date_i18n( $date_format, $booking->end ) . date_i18n( $time_format, $booking->end );
}

/**
Expand Down Expand Up @@ -181,8 +178,8 @@ public function update_start_end_time( $booking_id ) {
return;
}

$check_in = WC_Product_Accommodation_Booking::get_check_times( 'in' );
$check_out = WC_Product_Accommodation_Booking::get_check_times( 'out' );
$check_in = WC_Product_Accommodation_Booking::get_check_times( 'in', $product_id );
$check_out = WC_Product_Accommodation_Booking::get_check_times( 'out', $product_id );

$start = get_post_meta( $booking_id, '_booking_start', true );
$end = get_post_meta( $booking_id, '_booking_end', true );
Expand Down
41 changes: 28 additions & 13 deletions includes/class-wc-product-accommodation-booking.php
Original file line number Diff line number Diff line change
Expand Up @@ -195,15 +195,16 @@ public function get_price_html( $price = '' ) {
public function get_time_slots( $blocks, $resource_id = 0, $from = 0, $to = 0, $include_sold_out = false ) {
$bookable_product = $this;

$transient_name = 'book_ts_' . md5( http_build_query( array( $bookable_product->get_id(), $resource_id, $from, $to ) ) );
$product_id = $bookable_product->get_id();
$transient_name = 'book_ts_' . md5( http_build_query( array( $product_id, $resource_id, $from, $to ) ) );
$available_slots = get_transient( $transient_name );
$booking_slots_transient_keys = array_filter( (array) get_transient( 'booking_slots_transient_keys' ) );

if ( ! isset( $booking_slots_transient_keys[ $bookable_product->get_id() ] ) ) {
$booking_slots_transient_keys[ $bookable_product->get_id() ] = array();
if ( ! isset( $booking_slots_transient_keys[ $product_id ] ) ) {
$booking_slots_transient_keys[ $product_id ] = array();
}

$booking_slots_transient_keys[ $bookable_product->get_id() ][] = $transient_name;
$booking_slots_transient_keys[ $product_id ][] = $transient_name;

// Give array of keys a long ttl because if it expires we won't be able to flush the keys when needed.
// We can't use 0 to never expire because then WordPress will autoload the option on every page.
Expand All @@ -229,8 +230,8 @@ public function get_time_slots( $blocks, $resource_id = 0, $from = 0, $to = 0, $
$has_resources = $bookable_product->has_resources();

foreach ( $blocks as $block ) {
$check_in = WC_Product_Accommodation_Booking::get_check_times( 'in' );
$check_out = WC_Product_Accommodation_Booking::get_check_times( 'out' );
$check_in = WC_Product_Accommodation_Booking::get_check_times( 'in', $product_id );
$check_out = WC_Product_Accommodation_Booking::get_check_times( 'out', $product_id );
// Blocks for accommodation products are initially calculated as days but the actuall time blocks are shifted by check in and checkout times.
$block_start_time = strtotime( "{$check_in}", $block );
$block_end_time = strtotime( "{$check_out}", strtotime( "+1 days", $block ) );
Expand Down Expand Up @@ -328,20 +329,34 @@ public function get_blocks_in_range( $start_date, $end_date, $intervals = array(
/**
* Get checkin and checkout times.
*
* @param string $type
* @param string $type The type, check_in or check_out.
* @param int $product_id The product ID.
*
* @return string Time, either from options or default
* @return string The time, either from options or default or from the filtered value.
*/
public static function get_check_times( $type ) {
$option = get_option( 'woocommerce_accommodation_bookings_times_settings' );
public static function get_check_times( $type, $product_id = 0 ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might cause difficulties if a third party extends WC_Product_Accommodation_Booking and overrides this method (since there will be a signature mismatch). Not sure how likely that is, but it may be worth calling out in release notes/changelog.

$option = get_option( 'woocommerce_accommodation_bookings_times_settings' );
$check_time = '';

switch ( $type ) {
case 'in':
return isset( $option['check_in'] ) ? $option['check_in'] : '14:00';
$check_time = $option['check_in'] ?? '14:00';
break;
case 'out':
return isset( $option['check_out'] ) ? $option['check_out'] : '14:00';
$check_time = $option['check_out'] ?? '14:00';
break;
}

return '';
/**
* Filter the check-in/out times for a specific product.
*
* @param string $check_time The check-in/out time stored in the database.
* @param string $type The type, check_in or check_out.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I'm reading this correctly, $type has values of in or out, not check_in or check_out

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rtpHarry thanks for the report. We will fix it along with future fixes.

* @param int $product_id The product ID.
*
* @return string The filtered/original time.
*/
return apply_filters( 'woocommerce_accommodation_booking_get_check_times', $check_time, $type, (int) $product_id );
}

/**
Expand Down