Version Description
(2020-08-31) = - It now shows the section label for combined tables. - It now disallows bookings with the exact same information (date, time, party, name, email & phone), to prevent duplicate bookings when the page is refreshed. - Update to prevent overbooking (allowing more reservations than the set maximum) that was sometimes occurring if multiple people had the booking form open at the same time.
Download this release
Release Info
Developer | Rustaurius |
Plugin | Restaurant Reservations |
Version | 2.1.20 |
Comparing to | |
See all releases |
Code changes from version 2.1.19 to 2.1.20
- includes/Ajax.class.php +22 -2
- includes/Booking.class.php +181 -3
- includes/Settings.class.php +1 -1
- readme.txt +5 -0
- restaurant-reservations.php +1 -1
includes/Ajax.class.php
CHANGED
@@ -593,7 +593,9 @@ if ( !class_exists( 'rtbAJAX' ) ) {
|
|
593 |
|
594 |
$combination = $this->get_combinations_chain( $tables, $valid_tables, $valid_table, $tables[ $valid_table ]->max_people, $this->party );
|
595 |
|
596 |
-
if ( $combination ) {
|
|
|
|
|
597 |
}
|
598 |
|
599 |
$return_tables = $this->format_tables( $possible_combinations );
|
@@ -678,15 +680,33 @@ if ( !class_exists( 'rtbAJAX' ) ) {
|
|
678 |
$table_values['numbers'] .= ( strlen( $table_values['numbers'] ) ? ', ' : '' ) . $table->number;
|
679 |
$table_values['min_people'] += $table->min_people;
|
680 |
$table_values['max_people'] += $table->max_people;
|
|
|
|
|
681 |
}
|
682 |
}
|
683 |
|
684 |
-
$formatted_tables[ $table_values['numbers'] ] = $table_values['numbers'] . ' - (min. ' . $table_values['min_people'] . '/max. ' . $table_values['max_people'] . ')';
|
|
|
|
|
685 |
}
|
686 |
|
687 |
return $formatted_tables;
|
688 |
}
|
689 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
690 |
public function format_pickadate_time( $time ) {
|
691 |
return array( date( 'G', $time ), date( 'i', $time ) );
|
692 |
}
|
593 |
|
594 |
$combination = $this->get_combinations_chain( $tables, $valid_tables, $valid_table, $tables[ $valid_table ]->max_people, $this->party );
|
595 |
|
596 |
+
if ( $combination ) {
|
597 |
+
$possible_combinations[] = $combination;
|
598 |
+
}
|
599 |
}
|
600 |
|
601 |
$return_tables = $this->format_tables( $possible_combinations );
|
680 |
$table_values['numbers'] .= ( strlen( $table_values['numbers'] ) ? ', ' : '' ) . $table->number;
|
681 |
$table_values['min_people'] += $table->min_people;
|
682 |
$table_values['max_people'] += $table->max_people;
|
683 |
+
|
684 |
+
if ( ! isset( $section_name ) ) { $section_name = $this->get_section_name( $table->section ); }
|
685 |
}
|
686 |
}
|
687 |
|
688 |
+
$formatted_tables[ $table_values['numbers'] ] = $table_values['numbers'] . ' - ' . $section_name . ' (min. ' . $table_values['min_people'] . '/max. ' . $table_values['max_people'] . ')';
|
689 |
+
|
690 |
+
unset( $section_name );
|
691 |
}
|
692 |
|
693 |
return $formatted_tables;
|
694 |
}
|
695 |
|
696 |
+
public function get_section_name( $section_id ) {
|
697 |
+
global $rtb_controller;
|
698 |
+
|
699 |
+
$sections = json_decode( html_entity_decode( $rtb_controller->settings->get_setting( 'rtb-table-sections' ) ) ); update_option("EWD_Debugging", print_r( $sections, true ) );
|
700 |
+
$sections = is_array( $sections ) ? $sections : array();
|
701 |
+
|
702 |
+
foreach ( $sections as $section ) {
|
703 |
+
|
704 |
+
if ( $section->section_id == $section_id ) { return $section->name; }
|
705 |
+
}
|
706 |
+
|
707 |
+
return false;
|
708 |
+
}
|
709 |
+
|
710 |
public function format_pickadate_time( $time ) {
|
711 |
return array( date( 'G', $time ), date( 'i', $time ) );
|
712 |
}
|
includes/Booking.class.php
CHANGED
@@ -567,7 +567,7 @@ class rtbBooking {
|
|
567 |
$this->validation_errors[] = array(
|
568 |
'field' => 'date',
|
569 |
'post_variable' => $ip,
|
570 |
-
'message'
|
571 |
);
|
572 |
} elseif ( empty( $this->ip ) ) {
|
573 |
$this->ip = sanitize_text_field( $ip );
|
@@ -575,6 +575,33 @@ class rtbBooking {
|
|
575 |
} elseif ( empty( $this->ip ) ) {
|
576 |
$this->ip = sanitize_text_field( $_SERVER['REMOTE_ADDR'] );
|
577 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
578 |
|
579 |
do_action( 'rtb_validate_booking_submission', $this );
|
580 |
|
@@ -710,6 +737,157 @@ class rtbBooking {
|
|
710 |
return $this->table == array_intersect( $this->table, $valid_tables );
|
711 |
}
|
712 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
713 |
/**
|
714 |
* Check whether the number of reservations occurring at the same time is below the threshold
|
715 |
* where reservations get automatically confirmed
|
@@ -722,7 +900,7 @@ class rtbBooking {
|
|
722 |
$max_reservations_setting = $rtb_controller->settings->get_setting( 'auto-confirm-max-reservations' );
|
723 |
$max_reservations = substr( $max_reservations_setting, 0, strpos( $max_reservations_setting, '_' ) );
|
724 |
|
725 |
-
if ($max_reservations == 'undefined' or $max_reservations <= 1) { return false; }
|
726 |
|
727 |
$dining_block_setting = $rtb_controller->settings->get_setting( 'rtb-dining-block-length' );
|
728 |
$dining_block = substr( $dining_block_setting, 0, strpos( $dining_block_setting, '_' ) );
|
@@ -776,7 +954,7 @@ class rtbBooking {
|
|
776 |
$max_seats_setting = $rtb_controller->settings->get_setting( 'auto-confirm-max-seats' );
|
777 |
$max_seats = substr( $max_seats_setting, 0, strpos( $max_seats_setting, '_' ) );
|
778 |
|
779 |
-
if ($max_seats == 'undefined' or $max_seats <= 1 or $this->party >= $max_seats) { return false; }
|
780 |
|
781 |
$dining_block_setting = $rtb_controller->settings->get_setting( 'rtb-dining-block-length' );
|
782 |
$dining_block = substr( $dining_block_setting, 0, strpos( $dining_block_setting, '_' ) );
|
567 |
$this->validation_errors[] = array(
|
568 |
'field' => 'date',
|
569 |
'post_variable' => $ip,
|
570 |
+
'message' => __( 'Your booking has been rejected. Please call us if you would like to make a booking.', 'restaurant-reservations' ),
|
571 |
);
|
572 |
} elseif ( empty( $this->ip ) ) {
|
573 |
$this->ip = sanitize_text_field( $ip );
|
575 |
} elseif ( empty( $this->ip ) ) {
|
576 |
$this->ip = sanitize_text_field( $_SERVER['REMOTE_ADDR'] );
|
577 |
}
|
578 |
+
|
579 |
+
// Check to make sure that the maximum number of reservations has not already been made
|
580 |
+
if ( ! $this->is_under_max_reservations() ){
|
581 |
+
$this->validation_errors[] = array(
|
582 |
+
'field' => 'time',
|
583 |
+
'error_msg' => 'maximum reservations exceeded',
|
584 |
+
'message' => __( 'The maximum number of reservations for that timeslot has been reached. Please select a different timeslot.', 'restaurant-reservations' ),
|
585 |
+
);
|
586 |
+
}
|
587 |
+
|
588 |
+
// Check to make sure that the maximum number of seats has not already been made
|
589 |
+
if ( ! $this->is_under_max_seats() ){
|
590 |
+
$this->validation_errors[] = array(
|
591 |
+
'field' => 'time',
|
592 |
+
'error_msg' => 'maximum seats exceeded',
|
593 |
+
'message' => __( 'With your party, the maximum number of seats for that timeslot would be exceeded. Please select a different timeslot or reduce your party size.', 'restaurant-reservations' ),
|
594 |
+
);
|
595 |
+
}
|
596 |
+
|
597 |
+
// Check if there is a booking already made with the exact same information, to prevent double bookings on refresh
|
598 |
+
if ( $this->is_duplicate_booking() ){
|
599 |
+
$this->validation_errors[] = array(
|
600 |
+
'field' => 'date',
|
601 |
+
'error_msg' => 'duplicate booking',
|
602 |
+
'message' => __( 'Your booking and personal information exactly matches another booking. If this was not caused by refreshing the page, please call us to make a booking.', 'restaurant-reservations' ),
|
603 |
+
);
|
604 |
+
}
|
605 |
|
606 |
do_action( 'rtb_validate_booking_submission', $this );
|
607 |
|
737 |
return $this->table == array_intersect( $this->table, $valid_tables );
|
738 |
}
|
739 |
|
740 |
+
/**
|
741 |
+
* Check if this booking would put the restaurant over the maximum, if set
|
742 |
+
*
|
743 |
+
* @return bool
|
744 |
+
* @since 2.1.20
|
745 |
+
*/
|
746 |
+
public function is_under_max_reservations() {
|
747 |
+
global $rtb_controller;
|
748 |
+
|
749 |
+
$max_reservations_enabled = $rtb_controller->settings->get_setting( 'rtb-enable-max-tables' );
|
750 |
+
|
751 |
+
if ( ! $max_reservations_enabled ) { return true; }
|
752 |
+
|
753 |
+
$max_reservations_setting = $rtb_controller->settings->get_setting( 'rtb-max-tables-count' );
|
754 |
+
$max_reservations = substr( $max_reservations_setting, 0, strpos( $max_reservations_setting, '_' ) );
|
755 |
+
|
756 |
+
if ($max_reservations == 'undefined' or ! $max_reservations ) { return true; }
|
757 |
+
|
758 |
+
$dining_block_setting = $rtb_controller->settings->get_setting( 'rtb-dining-block-length' );
|
759 |
+
$dining_block = substr( $dining_block_setting, 0, strpos( $dining_block_setting, '_' ) );
|
760 |
+
$dining_block_seconds = ( $dining_block * 60 - 1 ); // Take 1 second off, to avoid bookings that start or end exactly at the beginning of a booking block
|
761 |
+
|
762 |
+
$after_time = strtotime($this->date) - $dining_block_seconds - (3600 * get_option( 'gmt_offset' ) );
|
763 |
+
$before_time = strtotime($this->date) + $dining_block_seconds - (3600 * get_option( 'gmt_offset' ) );
|
764 |
+
|
765 |
+
$args = array(
|
766 |
+
'posts_per_page' => -1,
|
767 |
+
'date_query' => array(
|
768 |
+
'before' => date( 'c', $before_time ),
|
769 |
+
'after' => date( 'c', $after_time )
|
770 |
+
)
|
771 |
+
);
|
772 |
+
|
773 |
+
require_once( RTB_PLUGIN_DIR . '/includes/Query.class.php' );
|
774 |
+
$query = new rtbQuery( $args );
|
775 |
+
$query->prepare_args();
|
776 |
+
|
777 |
+
$times = array();
|
778 |
+
foreach ( $query->get_bookings() as $booking ) {
|
779 |
+
$times[] = strtotime( $booking->date );
|
780 |
+
}
|
781 |
+
|
782 |
+
sort( $times );
|
783 |
+
|
784 |
+
$accept_reservation = true;
|
785 |
+
$current_times = array();
|
786 |
+
foreach ( $times as $time ) {
|
787 |
+
$current_times[] = $time;
|
788 |
+
|
789 |
+
if ( reset( $current_times ) < ($time - $dining_block_seconds) ) { array_shift( $current_times ); }
|
790 |
+
|
791 |
+
// Check if we go above the max confirmation number
|
792 |
+
if ( sizeOf( $current_times ) + 1 > $max_reservations ) { $accept_reservation = false; break; }
|
793 |
+
}
|
794 |
+
|
795 |
+
return $accept_reservation;
|
796 |
+
}
|
797 |
+
|
798 |
+
/**
|
799 |
+
* Check if this booking would put the restaurant over the maximum number of people, if set
|
800 |
+
*
|
801 |
+
* @return bool
|
802 |
+
* @since 2.1.20
|
803 |
+
*/
|
804 |
+
public function is_under_max_seats() {
|
805 |
+
global $rtb_controller;
|
806 |
+
|
807 |
+
$max_reservations_enabled = $rtb_controller->settings->get_setting( 'rtb-enable-max-tables' );
|
808 |
+
|
809 |
+
if ( ! $max_reservations_enabled ) { return true; }
|
810 |
+
|
811 |
+
$max_seats_setting = $rtb_controller->settings->get_setting( 'rtb-max-people-count' );
|
812 |
+
$max_seats = substr( $max_seats_setting, 0, strpos( $max_seats_setting, '_' ) );
|
813 |
+
|
814 |
+
if ( $max_seats == 'undefined' or ! $max_seats ) { return true; }
|
815 |
+
if ( $this->party > $max_seats ) { return false; }
|
816 |
+
|
817 |
+
$dining_block_setting = $rtb_controller->settings->get_setting( 'rtb-dining-block-length' );
|
818 |
+
$dining_block = substr( $dining_block_setting, 0, strpos( $dining_block_setting, '_' ) );
|
819 |
+
$dining_block_seconds = ( $dining_block * 60 - 1 ); // Take 1 second off, to avoid bookings that start or end exactly at the beginning of a booking block
|
820 |
+
|
821 |
+
$after_time = strtotime($this->date) - $dining_block_seconds - (3600 * get_option( 'gmt_offset' ) );
|
822 |
+
$before_time = strtotime($this->date) + $dining_block_seconds - (3600 * get_option( 'gmt_offset' ) );
|
823 |
+
|
824 |
+
$args = array(
|
825 |
+
'posts_per_page' => -1,
|
826 |
+
'date_query' => array(
|
827 |
+
'before' => date( 'c', $before_time ),
|
828 |
+
'after' => date( 'c', $after_time )
|
829 |
+
)
|
830 |
+
);
|
831 |
+
|
832 |
+
require_once( RTB_PLUGIN_DIR . '/includes/Query.class.php' );
|
833 |
+
$query = new rtbQuery( $args );
|
834 |
+
|
835 |
+
$times = array();
|
836 |
+
foreach ( $query->get_bookings() as $booking ) {
|
837 |
+
$booking_time = strtotime( $booking->date );
|
838 |
+
if ( isset( $times[$booking_time] ) ) { $times[$booking_time] += $booking->party; }
|
839 |
+
else { $times[$booking_time] = $booking->party; }
|
840 |
+
}
|
841 |
+
|
842 |
+
ksort( $times );
|
843 |
+
|
844 |
+
$accept_reservation = true;
|
845 |
+
$current_seats = array();
|
846 |
+
foreach ( $times as $time => $seats ) {
|
847 |
+
$current_seats[$time] = $seats;
|
848 |
+
|
849 |
+
reset( $current_seats );
|
850 |
+
|
851 |
+
if ( key ( $current_seats ) < $time - $dining_block_seconds ) { array_shift( $current_seats ); }
|
852 |
+
|
853 |
+
// Check if adding the current party puts us above the max confirmation number
|
854 |
+
if ( array_sum( $current_seats ) + $this->party > $max_seats ) { $accept_reservation = false; break; }
|
855 |
+
}
|
856 |
+
|
857 |
+
return $accept_reservation;
|
858 |
+
|
859 |
+
}
|
860 |
+
|
861 |
+
/**
|
862 |
+
* Check if the information in a booking exactly matches another booking
|
863 |
+
*
|
864 |
+
* @return bool
|
865 |
+
* @since 2.1.20
|
866 |
+
*/
|
867 |
+
public function is_duplicate_booking() {
|
868 |
+
global $wpdb;
|
869 |
+
|
870 |
+
$booking_result = $wpdb->get_row( $wpdb->prepare(
|
871 |
+
"SELECT ID FROM $wpdb->posts WHERE post_type=%s AND post_date=%s AND post_title=%s",
|
872 |
+
RTB_BOOKING_POST_TYPE,
|
873 |
+
$this->date,
|
874 |
+
$this->name
|
875 |
+
) );
|
876 |
+
|
877 |
+
if ( $booking_result ) {
|
878 |
+
|
879 |
+
$meta = get_post_meta( $booking_result->ID, 'rtb', true );
|
880 |
+
$meta = is_array( $meta ) ? $meta : array();
|
881 |
+
|
882 |
+
if ( $this->party = $meta['party'] and $this->email = $meta['email'] and $this->phone = $meta['phone'] ) {
|
883 |
+
|
884 |
+
return true;
|
885 |
+
}
|
886 |
+
}
|
887 |
+
|
888 |
+
return false;
|
889 |
+
}
|
890 |
+
|
891 |
/**
|
892 |
* Check whether the number of reservations occurring at the same time is below the threshold
|
893 |
* where reservations get automatically confirmed
|
900 |
$max_reservations_setting = $rtb_controller->settings->get_setting( 'auto-confirm-max-reservations' );
|
901 |
$max_reservations = substr( $max_reservations_setting, 0, strpos( $max_reservations_setting, '_' ) );
|
902 |
|
903 |
+
if ( $max_reservations == 'undefined' or $max_reservations <= 1 ) { return false; }
|
904 |
|
905 |
$dining_block_setting = $rtb_controller->settings->get_setting( 'rtb-dining-block-length' );
|
906 |
$dining_block = substr( $dining_block_setting, 0, strpos( $dining_block_setting, '_' ) );
|
954 |
$max_seats_setting = $rtb_controller->settings->get_setting( 'auto-confirm-max-seats' );
|
955 |
$max_seats = substr( $max_seats_setting, 0, strpos( $max_seats_setting, '_' ) );
|
956 |
|
957 |
+
if ( $max_seats == 'undefined' or $max_seats <= 1 or $this->party >= $max_seats ) { return false; }
|
958 |
|
959 |
$dining_block_setting = $rtb_controller->settings->get_setting( 'rtb-dining-block-length' );
|
960 |
$dining_block = substr( $dining_block_setting, 0, strpos( $dining_block_setting, '_' ) );
|
includes/Settings.class.php
CHANGED
@@ -1354,7 +1354,7 @@ If you were not the one to cancel this booking, please contact us.
|
|
1354 |
array(
|
1355 |
'id' => 'rtb-max-people-count',
|
1356 |
'title' => __( 'Max People', 'restaurant-reservations' ),
|
1357 |
-
'description' => __( 'How many people, if enabled above, should be allowed to be present in the restaurant at the same time? Set dining block length setting above to change how long a meal typically lasts.
|
1358 |
'min_value' => 1,
|
1359 |
'max_value' => 100,
|
1360 |
'increment' => 1
|
1354 |
array(
|
1355 |
'id' => 'rtb-max-people-count',
|
1356 |
'title' => __( 'Max People', 'restaurant-reservations' ),
|
1357 |
+
'description' => __( 'How many people, if enabled above, should be allowed to be present in the restaurant at the same time? Set dining block length setting above to change how long a meal typically lasts. May not work correctly if max reservations is set.', 'restaurant-reservations' ),
|
1358 |
'min_value' => 1,
|
1359 |
'max_value' => 100,
|
1360 |
'increment' => 1
|
readme.txt
CHANGED
@@ -196,6 +196,11 @@ Find answers to even more questions in the [FAQ](http://doc.fivestarplugins.com/
|
|
196 |
|
197 |
== Changelog ==
|
198 |
|
|
|
|
|
|
|
|
|
|
|
199 |
= 2.1.19 (2020-08-20) =
|
200 |
- Fixed issue with booking edit panel that was making it so, if there was only one table available, it wouldn't save correctly if you tried to change the booking status.
|
201 |
- Generated a new .pot file.
|
196 |
|
197 |
== Changelog ==
|
198 |
|
199 |
+
= 2.1.20 (2020-08-31) =
|
200 |
+
- It now shows the section label for combined tables.
|
201 |
+
- It now disallows bookings with the exact same information (date, time, party, name, email & phone), to prevent duplicate bookings when the page is refreshed.
|
202 |
+
- Update to prevent overbooking (allowing more reservations than the set maximum) that was sometimes occurring if multiple people had the booking form open at the same time.
|
203 |
+
|
204 |
= 2.1.19 (2020-08-20) =
|
205 |
- Fixed issue with booking edit panel that was making it so, if there was only one table available, it wouldn't save correctly if you tried to change the booking status.
|
206 |
- Generated a new .pot file.
|
restaurant-reservations.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
* Plugin Name: Five Star Restaurant Reservations - WordPress Booking Plugin
|
4 |
* Plugin URI: http://www.fivestarplugins.com/plugins/five-star-restaurant-reservations/
|
5 |
* Description: Restaurant reservations made easy. Accept bookings online. Quickly confirm or reject reservations, send email notifications, set booking times and more.
|
6 |
-
* Version: 2.1.
|
7 |
* Author: FiveStarPlugins
|
8 |
* Author URI: https://profiles.wordpress.org/fivestarplugins/
|
9 |
* Text Domain: restaurant-reservations
|
3 |
* Plugin Name: Five Star Restaurant Reservations - WordPress Booking Plugin
|
4 |
* Plugin URI: http://www.fivestarplugins.com/plugins/five-star-restaurant-reservations/
|
5 |
* Description: Restaurant reservations made easy. Accept bookings online. Quickly confirm or reject reservations, send email notifications, set booking times and more.
|
6 |
+
* Version: 2.1.20
|
7 |
* Author: FiveStarPlugins
|
8 |
* Author URI: https://profiles.wordpress.org/fivestarplugins/
|
9 |
* Text Domain: restaurant-reservations
|