Skip to content

Instantly share code, notes, and snippets.

@apkoponen
Last active December 8, 2015 08:07
Show Gist options
  • Select an option

  • Save apkoponen/ef66524fa666a24e0b33 to your computer and use it in GitHub Desktop.

Select an option

Save apkoponen/ef66524fa666a24e0b33 to your computer and use it in GitHub Desktop.
diff --git a/includes/admin/class-wc-bookings-admin.php b/includes/admin/class-wc-bookings-admin.php
index ca679ca..7c5fd38 100644
--- a/includes/admin/class-wc-bookings-admin.php
+++ b/includes/admin/class-wc-bookings-admin.php
@@ -28,6 +28,8 @@ class WC_Bookings_Admin {
add_action( 'woocommerce_product_options_general_product_data', array( $this, 'booking_data' ) );
add_filter( 'product_type_options', array( $this, 'booking_product_type_options' ) );
add_action( 'load-options-general.php', array( $this, 'reset_ics_exporter_timezone_cache' ) );
+ add_action( 'update_option', array($this, 'update_global_booking_availability'), 10, 3 ); // wc_global_booking_availability do_action( 'updated_option', $option, $old_value, $value );
+ add_action( 'update_postmeta', array($this, 'update_booking_availablity'), 10, 4 ); // do_action( 'updated_postmeta', $meta_id, $object_id, $meta_key, $meta_value ); _wc_booking_availability
// Ajax
add_action( 'wp_ajax_woocommerce_add_bookable_resource', array( $this, 'add_bookable_resource' ) );
@@ -709,6 +711,31 @@ class WC_Bookings_Admin {
wp_cache_delete( 'wc_bookings_timezone_string' );
}
}
+
+ /**
+ * @VALU
+ * Flush saved minute blocks if global booking availability rules have changed.
+ */
+ public function update_global_booking_availability($option, $old_value, $value ) {
+ if($option === 'wc_global_booking_availability') {
+ if($old_value !== $value) {
+ global $wpdb;
+ $wpdb->query("DELETE FROM " . $wpdb->postmeta . " WHERE meta_key = '_wc_booking_bookable_minute_blocks'");
+ }
+ }
+ }
+
+ /**
+ * @VALU
+ * Flush saved minute blocks if product or resource availability rules have changed.
+ */
+ public function update_booking_availablity($meta_id, $object_id, $meta_key, $meta_value) {
+ if($meta_key === '_wc_booking_availability') {
+ if($meta_value !== get_post_meta($object_id, '_wc_booking_availability')) {
+ delete_post_meta($object_id, '_wc_booking_bookable_minute_blocks');
+ }
+ }
+ }
}
new WC_Bookings_Admin();
diff --git a/includes/booking-form/class-wc-booking-form-date-picker.php b/includes/booking-form/class-wc-booking-form-date-picker.php
old mode 100755
new mode 100644
index ff1cb9a..ec8aaf5
--- a/includes/booking-form/class-wc-booking-form-date-picker.php
+++ b/includes/booking-form/class-wc-booking-form-date-picker.php
@@ -111,6 +111,12 @@ class WC_Booking_Form_Date_Picker extends WC_Booking_Form_Picker {
$fully_booked_days[ date( 'Y-n-j' ) ][0] = true;
}
+ //@VALU Initialize times
+ $current_time = current_time( 'timestamp' );
+ $strtotimes_ar = array(
+ "+1 day" => strtotime("+1 day", 0)
+ );
+
// Use the existing bookings to find days which are fully booked
foreach ( $existing_bookings as $existing_booking ) {
$start_date = $existing_booking->start;
@@ -122,8 +128,8 @@ class WC_Booking_Form_Date_Picker extends WC_Booking_Form_Picker {
while ( $check_date < $end_date ) {
$js_date = date( 'Y-n-j', $check_date );
- if ( $check_date < current_time( 'timestamp' ) ) {
- $check_date = strtotime( "+1 day", $check_date );
+ if ( $check_date < $current_time ) {
+ $check_date = $strtotimes_ar["+1 day"] + $check_date;
continue;
}
@@ -131,7 +137,7 @@ class WC_Booking_Form_Date_Picker extends WC_Booking_Form_Picker {
// Skip if we've already found this resource is unavailable
if ( ! empty( $fully_booked_days[ $js_date ][ $resource_id ] ) ) {
- $check_date = strtotime( "+1 day", $check_date );
+ $check_date = $strtotimes_ar["+1 day"] + $check_date;
continue;
}
@@ -158,7 +164,7 @@ class WC_Booking_Form_Date_Picker extends WC_Booking_Form_Picker {
// Skip if we've already found this product is unavailable
if ( ! empty( $fully_booked_days[ $js_date ] ) ) {
- $check_date = strtotime( "+1 day", $check_date );
+ $check_date = $strtotimes_ar["+1 day"] + $check_date;
continue;
}
@@ -173,11 +179,11 @@ class WC_Booking_Form_Date_Picker extends WC_Booking_Form_Picker {
$fully_booked_days[ $js_date ][0] = true;
}
}
- $check_date = strtotime( "+1 day", $check_date );
+ $check_date = $strtotimes_ar["+1 day"] + $check_date;
}
}
$this->args['partially_booked_days'] = $partially_booked_days;
$this->args['fully_booked_days'] = $fully_booked_days;
}
-}
\ No newline at end of file
+}
diff --git a/includes/class-wc-bookings-controller.php b/includes/class-wc-bookings-controller.php
old mode 100755
new mode 100644
diff --git a/includes/class-wc-product-booking-resource.php b/includes/class-wc-product-booking-resource.php
index c4403b5..9bfaf73 100644
--- a/includes/class-wc-product-booking-resource.php
+++ b/includes/class-wc-product-booking-resource.php
@@ -10,6 +10,7 @@ class WC_Product_Booking_Resource {
private $resource;
private $product_id;
+ private $qty;
/**
* Constructor
@@ -70,7 +71,11 @@ class WC_Product_Booking_Resource {
* @return int
*/
public function get_qty() {
- return get_post_meta( $this->get_id(), 'qty', true );
+ //@VALU Save meta to resource
+ if(is_null($this->qty)) {
+ $this->qty = get_post_meta( $this->get_id(), 'qty', true );
+ }
+ return $this->qty;
}
/**
diff --git a/includes/class-wc-product-booking.php b/includes/class-wc-product-booking.php
old mode 100755
new mode 100644
index 851e3f6..256ae1f
--- a/includes/class-wc-product-booking.php
+++ b/includes/class-wc-product-booking.php
@@ -8,6 +8,11 @@ if ( ! defined( 'ABSPATH' ) ) {
*/
class WC_Product_Booking extends WC_Product {
private $availability_rules = array();
+ //@VALU
+ private $booking_resources = array();
+ private $wc_booking_duration_unit_filtered;
+ private $min_date, $current_time;
+ private $bookable_minute_blocks;
/**
* Constructor
@@ -114,7 +119,11 @@ class WC_Product_Booking extends WC_Product {
* @return string
*/
public function get_duration_unit() {
- return apply_filters( 'woocommerce_bookings_get_duration_unit', $this->wc_booking_duration_unit, $this );
+ //@VALU Filter duration unit only once for the product
+ if( ! isset( $this->wc_booking_duration_unit_filtered ) ) {
+ $this->wc_booking_duration_unit_filtered = apply_filters( 'woocommerce_bookings_get_duration_unit', $this->wc_booking_duration_unit, $this );
+ }
+ return $this->wc_booking_duration_unit_filtered;
}
/**
@@ -252,26 +261,53 @@ class WC_Product_Booking extends WC_Product {
* @return int
*/
public function get_min_timestamp_for_date( $start_date ) {
+
+ //@VALU cache current time and offsets
+ $current_time = $this->get_current_time();
+
if ( $min = $this->get_min_date() ) {
- $today = ( date( 'y-m-d', $start_date ) === date( 'y-m-d', current_time( 'timestamp' ) ) );
- $timestamp = strtotime( ( $today ? '' : 'midnight ' ) . "+{$min['value']} {$min['unit']}", current_time( 'timestamp' ) );
+ $today = ( date( 'y-m-d', $start_date ) === date( 'y-m-d', $current_time ) );
+ $timestamp = strtotime( ( $today ? '' : 'midnight ' ) . "+{$min['value']} {$min['unit']}", $current_time );
} else {
- $timestamp = current_time( 'timestamp' );
+ $timestamp = $current_time;
}
+
return $timestamp;
}
+ /**
+ * Caching function for current_time to avoid extensive calls.
+ *
+ * @return int First time
+ */
+ public function get_current_time() {
+ if( is_null( $this->current_time ) ) {
+ $this->current_time = current_time( 'timestamp' );
+ }
+ return $this->current_time;
+ }
+
/**
* Get Min date
* @return array|bool
*/
public function get_min_date() {
- $min_date['value'] = ! empty( $this->wc_booking_min_date ) ? apply_filters( 'woocommerce_bookings_min_date_value', absint( $this->wc_booking_min_date ), $this->id ) : 0;
- $min_date['unit'] = ! empty( $this->wc_booking_min_date_unit ) ? apply_filters( 'woocommerce_bookings_min_date_unit', $this->wc_booking_min_date_unit, $this->id ) : 'month';
- if ( $min_date['value'] ) {
- return $min_date;
- }
- return false;
+ //@VALU Cache to skip the filters
+ $min_date = $this->min_date;
+
+ if( is_null( $this->min_date ) ) {
+ $this->min_date = array();
+ $this->min_date['value'] = ! empty( $this->wc_booking_min_date ) ? apply_filters( 'woocommerce_bookings_min_date_value', absint( $this->wc_booking_min_date ), $this->id ) : 0;
+ $this->min_date['unit'] = ! empty( $this->wc_booking_min_date_unit ) ? apply_filters( 'woocommerce_bookings_min_date_unit', $this->wc_booking_min_date_unit, $this->id ) : 'month';
+
+ if ( $this->min_date['value'] ) {
+ $this->min_date = $min_date;
+ } else {
+ $this->min_date = false;
+ }
+ }
+
+ return $this->min_date;
}
/**
@@ -347,12 +383,23 @@ class WC_Product_Booking extends WC_Product {
$id = absint( $id );
if ( $id ) {
- $resource = get_post( $id );
- $relationship_id = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM {$wpdb->prefix}wc_booking_relationships WHERE product_id = %d AND resource_id = %d", $this->id, $id ) );
+ // @VALU Implement "cache" a.k.a. save the booking_resource to the current product to avoid unnecessary queries
+ $booking_resource_key = 'booking_resource_'.$id;
+ $booking_resource = false;
+ if(isset($this->booking_resources[$booking_resource_key])) {
+ return $this->booking_resources[$booking_resource_key];
+ } else {
+ $resource = get_post( $id );
+ $relationship_id = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM {$wpdb->prefix}wc_booking_relationships WHERE product_id = %d AND resource_id = %d", $this->id, $id ) );
+
+ if ( is_object( $resource ) && $resource->post_type == 'bookable_resource' && 0 < $relationship_id ) {
+ $booking_resource = new WC_Product_Booking_Resource( $resource, $this->id );
+ $this->booking_resources[$booking_resource_key] = $booking_resource;
+ }
+ }
+
+ return $booking_resource;
- if ( is_object( $resource ) && $resource->post_type == 'bookable_resource' && 0 < $relationship_id ) {
- return new WC_Product_Booking_Resource( $resource, $this->id );
- }
}
return false;
@@ -532,7 +579,7 @@ class WC_Product_Booking extends WC_Product {
// Check all blocks availability
foreach ( $blocks as $block ) {
- $available_qty = $this->has_resources() && $booking_resource->has_qty() ? $booking_resource->get_qty() : $this->get_qty();
+ $available_qty = $this->has_resources() && $booking_resource->has_qty() ? $booking_resource->get_qty() : $this->get_qty();
$qty_booked_in_block = 0;
foreach ( $existing_bookings as $existing_booking ) {
@@ -754,85 +801,31 @@ class WC_Product_Booking extends WC_Product {
if ( in_array( $this->get_duration_unit(), array( 'day', 'minute', 'hour' ) ) ) {
$check_date = $start_date;
+ // @VALU Initialize necessary variables outside of the while loop!!!
+ $min_date = $this->get_min_timestamp_for_date( $start_date );
+ $product_min_date = $this->get_min_date();
+ $product_max_date = $this->get_max_date();
+
+ //Initialize times
+ $current_time = $this->get_current_time();
+ $strtotimes_ar = array(
+ "+1 day" => strtotime("+1 day", 0),
+ "+product_min_date" => strtotime("+{$product_min_date['value']} {$product_min_date['unit']}", 0),
+ "+product_max_date" => strtotime("+{$product_max_date['value']} {$product_max_date['unit']}", 0),
+ );
+
+ $booking_resource = $resource_id ? $this->get_resource( $resource_id ) : null;
+ $available_qty = $this->has_resources() && $booking_resource && $booking_resource->has_qty() ? $booking_resource->get_qty() : $this->get_qty();
+
// <= fixes https://github.com/woothemes/woocommerce-bookings/issues/325
while ( $check_date <= $end_date ) {
if ( in_array( $this->get_duration_unit(), array( 'day' ) ) && ! $this->check_availability_rules_against_date( $check_date, $resource_id ) ) {
- $check_date = strtotime( "+1 day", $check_date );
+ $check_date = $strtotimes_ar["+1 day"] + $check_date;
continue;
}
- $booking_resource = $resource_id ? $this->get_resource( $resource_id ) : null;
- $available_qty = $this->has_resources() && $booking_resource && $booking_resource->has_qty() ? $booking_resource->get_qty() : $this->get_qty();
-
// For mins and hours find valid blocks within THIS DAY ($check_date)
if ( in_array( $this->get_duration_unit(), array( 'minute', 'hour' ) ) ) {
- $first_block_time_minute = $this->wc_booking_first_block_time ? ( date( 'H', strtotime( $this->wc_booking_first_block_time ) ) * 60 ) + date( 'i', strtotime( $this->wc_booking_first_block_time ) ) : 0;
- $min_date = $this->get_min_timestamp_for_date( $start_date );
-
- // Work out what minutes are actually bookable on this day
- $bookable_minutes = $this->get_default_availability() ? range( $first_block_time_minute, 1440 ) : array();
- $rules = $this->get_availability_rules( $resource_id );
-
- // Since we evaluate all time rules and don't break out when one matches, reverse the array
- $rules = array_reverse( $rules );
-
- foreach ( $rules as $rule ) {
- $type = $rule[0];
- $rules = $rule[1];
-
- if ( strrpos( $type, 'time' ) === 0 ) {
- if ( ! empty( $rules['day'] ) ) {
- if ( $rules['day'] != date( 'N', $check_date ) ) {
- continue;
- }
- }
- $from_hour = absint( date( 'H', strtotime( $rules['from'] ) ) );
- $from_min = absint( date( 'i', strtotime( $rules['from'] ) ) );
- $to_hour = absint( date( 'H', strtotime( $rules['to'] ) ) );
- $to_min = absint( date( 'i', strtotime( $rules['to'] ) ) );
- $minute_range = array( ( $from_hour * 60 ) + $from_min, ( $to_hour * 60 ) + $to_min );
- $merge_ranges = array();
-
- if ( $minute_range[0] > $minute_range[1] ) {
- $merge_ranges[] = array( $minute_range[0], 1440 );
- $merge_ranges[] = array( 0, $minute_range[1] );
- } else {
- $merge_ranges[] = array( $minute_range[0], $minute_range[1] );
- }
-
- foreach ( $merge_ranges as $range ) {
- if ( $bookable = $rules['rule'] ) {
- // If this time range is bookable, add to bookable minutes
- $bookable_minutes = array_merge( $bookable_minutes, range( $range[0], $range[1] ) );
- } else {
- // If this time range is not bookable, remove from bookable minutes
- $bookable_minutes = array_diff( $bookable_minutes, range( $range[0] + 1, $range[1] - 1 ) );
- }
- }
- }
- }
-
- $bookable_minutes = array_unique( $bookable_minutes );
- sort( $bookable_minutes );
-
- // Break bookable minutes into sequences - bookings cannot have breaks
- $bookable_minute_blocks = array();
- $bookable_minute_block_from = current( $bookable_minutes );
-
- foreach ( $bookable_minutes as $key => $minute ) {
- if ( isset( $bookable_minutes[ $key + 1 ] ) ) {
- if ( $bookable_minutes[ $key + 1 ] - 1 === $minute ) {
- continue;
- } else {
- // There was a break in the sequence
- $bookable_minute_blocks[] = array( $bookable_minute_block_from, $minute );
- $bookable_minute_block_from = $bookable_minutes[ $key + 1 ];
- }
- } else {
- // We're at the end of the bookable minutes
- $bookable_minute_blocks[] = array( $bookable_minute_block_from, $minute );
- }
- }
// Create an array of already booked blocks
$booked_blocks = array();
@@ -845,15 +838,21 @@ class WC_Product_Booking extends WC_Product {
$booked_blocks = array_count_values( $booked_blocks );
+ //@VALU Initialize midnight
+ $check_date_midnight = strtotime( "midnight", $check_date );
+
+ //Get bookable minute blocks for resource
+ $bookable_minute_blocks = $this->get_bookable_minute_blocks($check_date, $resource_id);
+
// Loop the blocks of bookable minutes and add a block if there is enough room to book
foreach ( $bookable_minute_blocks as $time_block ) {
- $time_block_start = strtotime( "midnight +{$time_block[0]} minutes", $check_date );
+ $time_block_start = $time_block[0] * MINUTE_IN_SECONDS + $check_date_midnight;
$minutes_in_block = $time_block[1] - $time_block[0];
$base_intervals_in_block = floor( $minutes_in_block / $base_interval );
for ( $i = 0; $i < $base_intervals_in_block; $i ++ ) {
$from_interval = $i * $base_interval;
- $start_time = strtotime( "+{$from_interval} minutes", $time_block_start );
+ $start_time = $from_interval * MINUTE_IN_SECONDS + $time_block_start;
// Break if start time is after the end date being calced, or if the start time is on the next day
if ( $start_time > $end_date || date( 'ymd', $start_time ) !== date( 'ymd', $start_date ) ) {
@@ -861,7 +860,7 @@ class WC_Product_Booking extends WC_Product {
}
// Must be in the future
- if ( $start_time <= $min_date || $start_time <= current_time( 'timestamp' ) ) {
+ if ( $start_time <= $min_date || $start_time <= $current_time ) {
continue;
}
@@ -870,10 +869,9 @@ class WC_Product_Booking extends WC_Product {
}
// make sure minute & hour blocks are not past minimum & max booking settings
- $product_min_date = $this->get_min_date();
- $product_max_date = $this->get_max_date();
- $min_check_from = strtotime( "+{$product_min_date['value']} {$product_min_date['unit']}", current_time( 'timestamp' ) );
- $max_check_to = strtotime( "+{$product_max_date['value']} {$product_max_date['unit']}", current_time( 'timestamp' ) );
+
+ $min_check_from = $strtotimes_ar["+product_min_date"] + $current_time;
+ $max_check_to = $strtotimes_ar["+product_max_date"] + $current_time;
if ( $end_date < $min_check_from || $start_time > $max_check_to ) {
continue;
@@ -884,8 +882,8 @@ class WC_Product_Booking extends WC_Product {
* @note Known issue - hour blocks cannot span multi-days
*/
$to_interval = $from_interval + $interval;
- $end_time = strtotime( "+{$to_interval} minutes", $time_block_start );
- $time_block_end_time = strtotime( "midnight +{$time_block[1]} minutes", $check_date );
+ $end_time = $to_interval * MINUTE_IN_SECONDS + $time_block_start;
+ $time_block_end_time = $time_block[1] * MINUTE_IN_SECONDS + $check_date_midnight;
$loop_time = $start_time;
// This checks all minutes in block for availability
@@ -912,9 +910,9 @@ class WC_Product_Booking extends WC_Product {
}
// Check next day
- $check_date = strtotime( "+1 day", $check_date );
+ $check_date = $strtotimes_ar["+1 day"] + $check_date;
}
-
+
// For months, loop each month in the range to find blocks
} elseif ( 'month' === $this->get_duration_unit() ) {
@@ -943,6 +941,115 @@ class WC_Product_Booking extends WC_Product {
return $blocks;
}
+ /**
+ * Return bookable minute blocks. If the block does not exist, generate it.
+ *
+ * @param int $check_date time for the date to check
+ * @param int $resource_id ID of the resource to check
+ * @return Array
+ */
+ public function get_bookable_minute_blocks($check_date, $resource_id = 0) {
+ // Initialize variables
+ $resource_key = 'resource_'.$resource_id;
+ $date_key = 'date_'.$check_date;
+
+ if(is_null($this->bookable_minute_blocks)) {
+ $this->bookable_minute_blocks = get_post_meta($this->id, '_wc_booking_bookable_minute_blocks', true);
+ }
+ if(false === $this->bookable_minute_blocks) {
+ $this->bookable_minute_blocks = array();
+ }
+ if(!isset($this->bookable_minute_blocks[$resource_key])) {
+ $this->bookable_minute_blocks[$resource_key] = array();
+ }
+
+ // Work out what minutes are actually bookable on this day
+ $first_block_time_minute = $this->wc_booking_first_block_time ? ( date( 'H', strtotime( $this->wc_booking_first_block_time ) ) * 60 ) + date( 'i', strtotime( $this->wc_booking_first_block_time ) ) : 0;
+ $bookable_minutes = $this->get_default_availability() ? range( $first_block_time_minute, 1440 ) : array();
+ $rules = $this->get_availability_rules( $resource_id );
+
+ // Since we evaluate all time rules and don't break out when one matches, reverse the array
+ $rules = array_reverse( $rules );
+
+ // Check if block exists
+ if(isset($this->bookable_minute_blocks[$resource_key][$date_key])) {
+ return $this->bookable_minute_blocks[$resource_key][$date_key];
+ } else {
+ foreach ($rules as $rule ) {
+ $type = $rule[0];
+ $rules = $rule[1];
+
+ if ( strrpos( $type, 'time' ) === 0 ) {
+ if ( ! empty( $rules['day'] ) ) {
+ if ( $rules['day'] != date( 'N', $check_date ) ) {
+ continue;
+ }
+ }
+ $from_hour = absint( date( 'H', strtotime( $rules['from'] ) ) );
+ $from_min = absint( date( 'i', strtotime( $rules['from'] ) ) );
+ $to_hour = absint( date( 'H', strtotime( $rules['to'] ) ) );
+ $to_min = absint( date( 'i', strtotime( $rules['to'] ) ) );
+ $minute_range = array( ( $from_hour * 60 ) + $from_min, ( $to_hour * 60 ) + $to_min );
+ $merge_ranges = array();
+
+ if ( $minute_range[0] > $minute_range[1] ) {
+ $merge_ranges[] = array( $minute_range[0], 1440 );
+ $merge_ranges[] = array( 0, $minute_range[1] );
+ } else {
+ $merge_ranges[] = array( $minute_range[0], $minute_range[1] );
+ }
+
+ foreach ( $merge_ranges as $range ) {
+ if ( $bookable = $rules['rule'] ) {
+ // If this time range is bookable, add to bookable minutes
+ $bookable_minutes = array_merge( $bookable_minutes, range( $range[0], $range[1] ) );
+ } else {
+ // If this time range is not bookable, remove from bookable minutes
+ $bookable_minutes = array_diff( $bookable_minutes, range( $range[0] + 1, $range[1] - 1 ) );
+ }
+ }
+ }
+ }
+
+ $bookable_minutes = array_unique( $bookable_minutes );
+ sort( $bookable_minutes );
+
+ // Break bookable minutes into sequences - bookings cannot have breaks
+ $bookable_minute_blocks = array();
+ $bookable_minute_block_from = current( $bookable_minutes );
+
+ foreach ( $bookable_minutes as $key => $minute ) {
+ if ( isset( $bookable_minutes[ $key + 1 ] ) ) {
+ if ( $bookable_minutes[ $key + 1 ] - 1 === $minute ) {
+ continue;
+ } else {
+ // There was a break in the sequence
+ $bookable_minute_blocks[] = array( $bookable_minute_block_from, $minute );
+ $bookable_minute_block_from = $bookable_minutes[ $key + 1 ];
+ }
+ } else {
+ // We're at the end of the bookable minutes
+ $bookable_minute_blocks[] = array( $bookable_minute_block_from, $minute );
+ }
+ }
+ //Save changes
+ $this->bookable_minute_blocks[$resource_key][$date_key] = $bookable_minute_blocks;
+ add_action('shutdown', array($this, 'save_bookable_minute_blocks'));
+
+ return $this->bookable_minute_blocks[$resource_key][$date_key];
+ }
+ }
+
+ /**
+ * Save bookable minute blocks at the end of execution, because
+ * serialization of the array is extremely heavy. Load times bump about
+ * 10x if this is done every time when get_bookable_minute_blocks is
+ * called
+ */
+ public function save_bookable_minute_blocks() {
+ update_post_meta($this->id, '_wc_booking_bookable_minute_blocks', $this->bookable_minute_blocks);
+ }
+
/**
* Returns available blocks from a range of blocks by looking at existing bookings.
* @param array $blocks The blocks we'll be checking availability for.
diff --git a/includes/emails/class-wc-email-booking-confirmed.php b/includes/emails/class-wc-email-booking-confirmed.php
index 79a2032..2adc062 100644
--- a/includes/emails/class-wc-email-booking-confirmed.php
+++ b/includes/emails/class-wc-email-booking-confirmed.php
@@ -52,6 +52,7 @@ class WC_Email_Booking_Confirmed extends WC_Email {
unset( $this->replace[ $key ] );
}
$this->find[] = '{product_title}';
+
$this->replace[] = $this->object->get_product()->get_title();
if ( $this->object->get_order() ) {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment