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
8 changes: 4 additions & 4 deletions includes/class-wc-accommodation-booking.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public function add_checkin_time_to_booking_start_time( $date, $booking ) {
return $date;
}

$check_in = WC_Product_Accommodation_Booking::get_check_times( 'in' );
$check_in = WC_Product_Accommodation_Booking::get_check_times( 'in', $product->get_id() );

$date_format = apply_filters( 'woocommerce_bookings_date_format', wc_date_format() );
$time_format = apply_filters( 'woocommerce_bookings_time_format', ', ' . wc_time_format() );
Expand All @@ -123,7 +123,7 @@ public function add_checkout_time_to_booking_end_time( $date, $booking ) {
return $date;
}

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

Expand Down Expand Up @@ -181,8 +181,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
43 changes: 30 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,36 @@ 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 = isset( $option['check_in'] ) ? $option['check_in'] : '14:00';
dkotter marked this conversation as resolved.
Show resolved Hide resolved
break;
case 'out':
return isset( $option['check_out'] ) ? $option['check_out'] : '14:00';
$check_time = isset( $option['check_out'] ) ? $option['check_out'] : '14:00';
dkotter marked this conversation as resolved.
Show resolved Hide resolved
break;
}

return '';
/**
* Filter the check-in/out times for a specific product.
*
* @hook woocommerce_accommodation_booking_get_check_times
dkotter marked this conversation as resolved.
Show resolved Hide resolved
*
* @param {string} $check_time The check-in/out time stored in the database.
* @param {string} $type The type, check_in or check_out.
* @param {int} $product_id The product ID.
*
* @return {string} The filtered/original time.
dkotter marked this conversation as resolved.
Show resolved Hide resolved
*/
return apply_filters( 'woocommerce_accommodation_booking_get_check_times', $check_time, $type, $product_id );
}

/**
Expand Down