Restaurant Reservations - Version 2.1.5

Version Description

(2020-05-28) = - New option to enable a maximum number of seats at one time in the premium section

Download this release

Release Info

Developer Rustaurius
Plugin Icon 128x128 Restaurant Reservations
Version 2.1.5
Comparing to
See all releases

Code changes from version 2.1.4 to 2.1.5

assets/js/booking-form.js CHANGED
@@ -161,6 +161,13 @@ jQuery(document).ready(function ($) {
161
  rtb_booking_form.datepicker.on( {
162
  close: function() {
163
  rtb_booking_form.update_timepicker_range();
 
 
 
 
 
 
 
164
  }
165
  });
166
  }
@@ -418,6 +425,47 @@ jQuery(document).ready(function ($) {
418
  return start_time;
419
  };
420
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
421
 
422
  rtb_booking_form.init();
423
  });
161
  rtb_booking_form.datepicker.on( {
162
  close: function() {
163
  rtb_booking_form.update_timepicker_range();
164
+ rtb_booking_form.update_party_size_select();
165
+ }
166
+ });
167
+
168
+ rtb_booking_form.timepicker.on( {
169
+ close: function() {
170
+ rtb_booking_form.update_party_size_select();
171
  }
172
  });
173
  }
425
  return start_time;
426
  };
427
 
428
+ rtb_booking_form.update_party_size_select = function() {
429
+ if ( rtb_pickadate.enable_max_reservations && rtb_pickadate.max_people ) {
430
+ var partySelect = $('#rtb-party'),
431
+ selected_date = new Date( rtb_booking_form.datepicker.get( 'select', 'yyyy/mm/dd' ) ),
432
+ selected_date_year = selected_date.getFullYear(),
433
+ selected_date_month = selected_date.getMonth(),
434
+ selected_date_date = selected_date.getDate(),
435
+ selected_time = rtb_booking_form.timepicker.get('value');
436
+
437
+ if ( ! selected_time ) { return; }
438
+
439
+ selected_date_month = ('0' + (selected_date_month + 1)).slice(-2);
440
+ selected_date_date = ('0' + selected_date_date).slice(-2);
441
+
442
+ //reset party size
443
+ partySelect.prop("selectedIndex", 0).change();
444
+
445
+ var data = 'year=' + selected_date_year + '&month=' + selected_date_month + '&day=' + selected_date_date + '&time=' + selected_time + '&action=rtb_get_available_party_size';
446
+ jQuery.post( ajaxurl, data, function( response ) {
447
+ if ( ! response ) {
448
+ return;
449
+ }
450
+
451
+ response = jQuery.parseJSON(response);
452
+
453
+ var available_spots = response.available_spots;
454
+
455
+ partySelect.prop('disabled', false);
456
+
457
+ partySelect.find('> option').each(function() {
458
+ var that = $(this);
459
+ if (this.value > available_spots) {
460
+ that.prop('disabled', true);
461
+ } else {
462
+ that.prop('disabled', false);
463
+ }
464
+ });
465
+ });
466
+ }
467
+ }
468
+
469
 
470
  rtb_booking_form.init();
471
  });
includes/Ajax.class.php CHANGED
@@ -2,405 +2,531 @@
2
  if ( !defined( 'ABSPATH' ) ) exit;
3
 
4
  if ( !class_exists( 'rtbAJAX' ) ) {
5
- /**
6
- * Class to handle AJAX date interactions for Restaurant Reservations
7
- *
8
- * @since 2.0.0
9
- */
10
- class rtbAJAX {
11
-
12
  /**
13
- * The year of the booking date we're getting timeslots for
 
14
  * @since 2.0.0
15
  */
16
- public $year;
17
 
18
- /**
19
- * The month of the booking date we're getting timeslots for
20
- * @since 2.0.0
21
- */
22
- public $month;
23
 
24
- /**
25
- * The day of the booking date we're getting timeslots for
26
- * @since 2.0.0
27
- */
28
- public $day;
29
 
30
- public function __construct() {
 
 
 
 
31
 
32
- add_action( 'wp_ajax_rtb_get_available_time_slots', array( $this, 'get_time_slots' ) );
33
- add_action( 'wp_ajax_nopriv_rtb_get_available_time_slots', array( $this, 'get_time_slots' ) );
 
 
 
34
 
35
- add_action( 'wp_ajax_rtb_find_reservations', array( $this, 'get_reservations' ) );
36
- add_action( 'wp_ajax_nopriv_rtb_find_reservations', array( $this, 'get_reservations' ) );
37
 
38
- add_action( 'wp_ajax_rtb_cancel_reservations', array( $this, 'cancel_reservation' ) );
39
- add_action( 'wp_ajax_nopriv_rtb_cancel_reservations', array( $this, 'cancel_reservation' ) );
40
- }
41
 
42
- /**
43
- * Get reservations that are associated with the email address that was sent
44
- * @since 2.1.0
45
- */
46
- public function get_reservations() {
47
- global $wpdb;
48
 
49
- $email = isset($_POST['booking_email']) ? sanitize_email( $_POST['booking_email'] ) : '';
 
50
 
51
- if ( ! $email ) {
52
- wp_send_json_error(
53
- array(
54
- 'error' => 'noemail',
55
- 'msg' => __( 'The email you entered is not valid.', 'restaurant-reservations' ),
56
- )
57
- );
58
  }
59
 
60
- require_once( RTB_PLUGIN_DIR . '/includes/Booking.class.php' );
 
 
 
 
 
61
 
62
- $bookings = array();
63
- $booking_ids = $wpdb->get_results($wpdb->prepare("SELECT post_id FROM $wpdb->postmeta WHERE meta_key='rtb' AND meta_value LIKE %s", '%' . $email . '%'));
64
- foreach ( $booking_ids as $booking_id ) {
65
- $booking = new rtbBooking();
66
- if ( $booking->load_post( $booking_id->post_id ) ) {
67
- if ( ( $booking->post_status == 'pending' or $booking->post_status == 'confirmed' ) and time() < strtotime( $booking->date ) ) {
68
- $bookings[] = array(
69
- 'ID' => $booking->ID,
70
- 'email' => $booking->email,
71
- 'datetime' => $booking->format_date( $booking->date ),
72
- 'party' => $booking->party
73
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  }
75
  }
76
- }
77
 
78
- if ( ! empty($bookings) ) {
79
- wp_send_json_success(
80
- array(
81
- 'bookings' => $bookings
82
- )
83
- );
84
- }
85
- else {
86
- wp_send_json_error(
87
- array(
88
- 'error' => 'nobookings',
89
- 'msg' => __( 'No bookings were found for the email address you entered.', 'restaurant-reservations' ),
90
- )
91
- );
92
- }
93
 
94
- die();
95
- }
96
 
97
- /**
98
- * Cancel a reservation based on its ID, with the email address used for confirmation
99
- * @since 2.1.0
100
- */
101
- public function cancel_reservation( $non_ajax = true ) {
102
- global $rtb_controller;
103
 
104
- $booking_id = isset($_REQUEST['booking_id']) ? absint( $_REQUEST['booking_id'] ) : '';
105
- $booking_email = isset($_REQUEST['booking_email']) ? sanitize_email( $_REQUEST['booking_email'] ) : '';
106
 
107
- require_once( RTB_PLUGIN_DIR . '/includes/Booking.class.php' );
108
 
109
- $success = false;
110
 
111
- $booking = new rtbBooking();
112
- if ( $booking->load_post( $booking_id ) ) {
113
- if ( $booking_email == $booking->email ) {
114
- wp_update_post( array( 'ID' => $booking->ID, 'post_status' => 'cancelled' ) );
115
 
116
- $success = true;
 
 
 
 
 
 
 
 
 
117
  }
118
  else {
119
  wp_send_json_error(
120
  array(
121
- 'error' => 'invalidemail',
122
  'msg' => __( 'No booking matches the information that was sent.', 'restaurant-reservations' ),
123
  )
124
  );
125
  }
126
- }
127
- else {
128
- wp_send_json_error(
129
- array(
130
- 'error' => 'invalidid',
131
- 'msg' => __( 'No booking matches the information that was sent.', 'restaurant-reservations' ),
132
- )
133
- );
134
- }
135
 
136
- if ( $ajax ) {
137
- if ( $success ) {
138
- wp_send_json_success(
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  array(
140
- 'booking_id' => $booking_id
141
- )
 
142
  );
143
- }
144
 
145
- die();
 
146
  }
147
- elseif ( $success ) {
148
- $booking_page_id = $rtb_controller->settings->get_setting( 'booking-page' );
149
- $booking_page_url = get_permalink( $booking_page_id );
150
-
151
- $cancelled_url = add_query_arg(
152
- array(
153
- 'bookingCancelled' => 'success'
154
- ),
155
- $booking_page_url
156
- );
157
 
158
- header( 'location:' . $cancelled_url );
159
- }
160
- }
 
 
 
161
 
162
- /**
163
- * Get available timeslots when "Max Reservations" is enabled
164
- * @since 2.0.0
165
- */
166
- public function get_time_slots() {
167
- global $rtb_controller;
168
 
169
- $max_reservations_setting = $rtb_controller->settings->get_setting( 'rtb-max-tables-count' );
170
- $max_reservations = substr( $max_reservations_setting, 0, strpos( $max_reservations_setting, '_' ) );
171
-
172
- $this->year = sanitize_text_field( $_POST['year'] );
173
- $this->month = sanitize_text_field( $_POST['month'] );
174
- $this->day = sanitize_text_field( $_POST['day'] );
175
-
176
- $dining_block_setting = $rtb_controller->settings->get_setting( 'rtb-dining-block-length' );
177
- $dining_block = substr( $dining_block_setting, 0, strpos( $dining_block_setting, '_' ) );
178
- $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
179
-
180
- // Get opening/closing times for this particular day
181
- $hours = $this->get_opening_hours();
182
-
183
- // If the restaurant is closed that day, return false
184
- if ( ! $hours ) { echo $hours; die(); }
185
-
186
- $args = array(
187
- 'posts_per_page' => -1,
188
- 'date_range' => 'dates',
189
- 'start_date' => $this->year . '-' . $this->month . '-' . $this->day,
190
- 'end_date' => $this->year . '-' . $this->month . '-' . $this->day
191
- );
192
-
193
- require_once( RTB_PLUGIN_DIR . '/includes/Query.class.php' );
194
- $query = new rtbQuery( $args );
195
- $query->prepare_args();
196
 
197
- // Get all current booking times in seconds from UNIX
198
- $times = array();
199
- foreach ( $query->get_bookings() as $booking ) {
200
- $times[] = strtotime( $booking->date );
201
- }
202
-
203
- sort( $times );
204
-
205
- // Go through all current booking times and figure out when we're at or above the max
206
- $blocked = false;
207
- $blocked_times = array();
208
- $current_times = array();
209
- if ($max_reservations != 'undefined' and $max_reservations != 0) {
210
- foreach ( $times as $key => $time ) {
211
- $current_times[] = $time;
212
 
213
- while ( sizeOf( $current_times ) > 0 and reset( $current_times ) < $time - $dining_block_seconds ) {
214
- //save the time to know when the blocking potentially ends
215
- $removed_time = reset( $current_times );
216
-
217
- // remove the expired time
218
- array_shift( $current_times );
219
 
220
- // remove the block if we've dropped below the max reservation count
221
- if ( $blocked and sizeOf( $current_times ) < $max_reservations ) {
222
- $blocked = false;
223
- $blocked_times[] = $removed_time + $dining_block_seconds;
224
- }
225
- }
226
 
227
- // Check if we're at or above the maximum number of reservations
228
- if ( ! $blocked and sizeOf( $current_times ) >= $max_reservations ) {
229
- $blocked = true;
230
- $blocked_times[] = $time - $dining_block_seconds;
231
- }
232
- }
233
- }
234
-
235
- if ( $blocked ) { $blocked_times[] = end( $current_times ) + $dining_block_seconds; }
236
-
237
- $combined_times = array_merge( $blocked_times, $hours );
238
- sort( $combined_times );
239
-
240
- //Go through all of times to determine when the restaurant is open and not blocked
241
- $open = false;
242
- $blocked = false;
243
- $valid_times = array();
244
- foreach ( $combined_times as $time ) {
245
- if ( in_array( $time, $blocked_times ) ) {
246
- if ( ! $blocked ) {
247
- $blocked = true;
248
- if ( $open ) {
249
- $valid_times[] = (object) array( 'from' => $this->format_pickadate_time( $open_time ), 'to' => $this->format_pickadate_time( $time ), 'inverted' => true );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
250
  }
 
 
 
 
 
 
251
  }
252
- else {
253
- $blocked = false;
254
- if ( $open ) { $open_time = $time; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
255
  }
256
  }
257
- else {
258
- if ( ! $open ) {
259
- $open = true;
260
- if ( ! $blocked ) { $open_time = $time; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
261
  }
262
  else {
263
- $open = false;
264
- if ( ! $blocked ) { $valid_times[] = (object) array( 'from' => $this->format_pickadate_time( $open_time ), 'to' => $this->format_pickadate_time( $time ), 'inverted' => true ); }
 
 
 
 
 
 
265
  }
266
  }
 
 
 
 
267
  }
268
-
269
- echo json_encode( $valid_times );
270
-
271
- die();
272
- }
273
 
274
- public function get_opening_hours() {
275
- global $rtb_controller;
276
 
277
- $schedule_closed = $rtb_controller->settings->get_setting( 'schedule-closed' );
278
 
279
- $valid_times = array();
280
 
281
- // Check if this date is an exception to the rules
282
- if ( $schedule_closed !== 'undefined' ) {
283
 
284
- foreach ( $schedule_closed as $closing ) {
285
- $time = strtotime( $closing['date'] );
286
 
287
- if ( date( 'Y', $time ) == $this->year &&
288
- date( 'm', $time ) == $this->month &&
289
- date( 'd', $time ) == $this->day
290
- ) {
291
 
292
- // Closed all day
293
- if ( $closing['time'] == 'undefined' ) {
294
- return false;
295
- }
296
 
297
- if ( $closing['time']['start'] !== 'undefined' ) {
298
- $open_time = strtotime( $closing['date'] . ' ' . $closing['time']['start'] );
299
- } else {
300
- $open_time = strtotime( $closing['date'] ); // Start of the day
301
- }
302
 
303
- if ( $closing['time']['end'] !== 'undefined' ) {
304
- $close_time = strtotime( $closing['date'] . ' ' . $closing['time']['end'] );
305
- } else {
306
- $close_time = strtotime( $closing['date'] . ' 23:59:59' ); // End of the day
307
- }
308
 
309
- $open_time = $this->get_earliest_time( $open_time );
310
 
311
- if ( $open_time < $close_time ) {
312
- $valid_times[] = $open_time;
313
- $valid_times[] = $close_time;
314
- }
315
- else {
316
- return false;
 
317
  }
318
  }
319
- }
320
 
321
- // Exit early if this date is an exception
322
- if ( isset( $open_time ) ) {
323
- return $valid_times;
 
324
  }
325
- }
326
 
327
- $schedule_open = $rtb_controller->settings->get_setting( 'schedule-open' );
328
 
329
- // Get any rules which apply to this weekday
330
- if ( $schedule_open != 'undefined' ) {
331
 
332
- $day_of_week = strtolower( date( 'l', strtotime( $this->year . '-' . $this->month . '-' . $this->day . ' 1:00:00' ) ) );
333
 
334
- foreach ( $schedule_open as $opening ) {
335
 
336
- if ( $opening['weekdays'] !== 'undefined' ) {
337
- foreach ( $opening['weekdays'] as $weekday => $value ) {
338
- if ( $weekday == $day_of_week ) {
339
 
340
- // Closed all day
341
- if ( $opening->time == 'undefined' ) {
342
- return false;
343
- }
344
 
345
- if ( $opening['time']['start'] !== 'undefined' ) {
346
- $open_time = strtotime( $this->year . '-' . $this->month . '-' . $this->day . ' ' . $opening['time']['start'] );
347
- } else {
348
- $open_time = strtotime( $this->year . '-' . $this->month . '-' . $this->day );
349
- }
350
 
351
- if ( $opening['time']['end'] !== 'undefined' ) {
352
- $close_time = strtotime( $this->year . '-' . $this->month . '-' . $this->day . ' ' . $opening['time']['end'] );
353
- } else {
354
- $close_time = strtotime( $this->year . '-' . $this->month . '-' . $this->day . ' 23:59:59' ); // End of the day
355
- }
356
 
357
- $open_time = $this->get_earliest_time( $open_time );
358
 
359
- if ( $open_time < $close_time ) {
360
- $valid_times[] = $open_time;
361
- $valid_times[] = $close_time;
362
- }
363
- else {
364
- return false;
 
365
  }
366
  }
367
  }
368
  }
369
- }
370
 
371
- // Pass any valid times located
372
- if ( sizeOf( $valid_times ) >= 1 ) {
373
- return $valid_times;
 
374
  }
 
 
375
  }
376
 
377
- return false;
378
- }
 
 
 
 
 
379
 
380
- public function get_earliest_time( $open_time ) {
381
- global $rtb_controller;
 
 
 
 
 
 
 
382
 
383
- // Only make adjustments for current day selections
384
- if ( date( 'y-m-d', strtotime( $this->year . '-' . $this->month . '-' . $this->day ) ) !== date( 'y-m-d' ) ) {
385
  return $open_time;
386
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
387
 
388
- $late_bookings = ( is_admin() && current_user_can( 'manage_bookings' ) ) ? '' : $rtb_controller->settings->get_setting( 'late-bookings' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
389
 
390
- $open_time = time() > $open_time ? time() : $open_time;
391
 
392
- if ( $late_bookings === 'number' && $late_bookings % 1 === 0 ) {
393
- if ( time() + $late_bookings * 60 > $open_time ) {
394
- $open_time = time() + $late_bookings;
 
 
395
  }
396
  }
397
 
398
- return $open_time;
399
- }
400
-
401
- public function format_pickadate_time( $time ) {
402
- return array( date( 'G', $time ), date( 'i', $time ) );
403
  }
404
- }
405
-
406
  }
2
  if ( !defined( 'ABSPATH' ) ) exit;
3
 
4
  if ( !class_exists( 'rtbAJAX' ) ) {
 
 
 
 
 
 
 
5
  /**
6
+ * Class to handle AJAX date interactions for Restaurant Reservations
7
+ *
8
  * @since 2.0.0
9
  */
10
+ class rtbAJAX {
11
 
12
+ /**
13
+ * The year of the booking date we're getting timeslots for
14
+ * @since 2.0.0
15
+ */
16
+ public $year;
17
 
18
+ /**
19
+ * The month of the booking date we're getting timeslots for
20
+ * @since 2.0.0
21
+ */
22
+ public $month;
23
 
24
+ /**
25
+ * The day of the booking date we're getting timeslots for
26
+ * @since 2.0.0
27
+ */
28
+ public $day;
29
 
30
+ /**
31
+ * The time of the booking we're getting timeslots for
32
+ * @since 2.1.5
33
+ */
34
+ public $time;
35
 
36
+ public function __construct() {
 
37
 
38
+ add_action( 'wp_ajax_rtb_get_available_time_slots', array( $this, 'get_time_slots' ) );
39
+ add_action( 'wp_ajax_nopriv_rtb_get_available_time_slots', array( $this, 'get_time_slots' ) );
 
40
 
41
+ add_action( 'wp_ajax_rtb_find_reservations', array( $this, 'get_reservations' ) );
42
+ add_action( 'wp_ajax_nopriv_rtb_find_reservations', array( $this, 'get_reservations' ) );
 
 
 
 
43
 
44
+ add_action( 'wp_ajax_rtb_cancel_reservations', array( $this, 'cancel_reservation' ) );
45
+ add_action( 'wp_ajax_nopriv_rtb_cancel_reservations', array( $this, 'cancel_reservation' ) );
46
 
47
+ add_action( 'wp_ajax_rtb_get_available_party_size', array( $this, 'get_available_party_size' ) );
48
+ add_action( 'wp_ajax_nopriv_rtb_get_available_party_size', array( $this, 'get_available_party_size' ) );
 
 
 
 
 
49
  }
50
 
51
+ /**
52
+ * Get reservations that are associated with the email address that was sent
53
+ * @since 2.1.0
54
+ */
55
+ public function get_reservations() {
56
+ global $wpdb;
57
 
58
+ $email = isset($_POST['booking_email']) ? sanitize_email( $_POST['booking_email'] ) : '';
59
+
60
+ if ( ! $email ) {
61
+ wp_send_json_error(
62
+ array(
63
+ 'error' => 'noemail',
64
+ 'msg' => __( 'The email you entered is not valid.', 'restaurant-reservations' ),
65
+ )
66
+ );
67
+ }
68
+
69
+ require_once( RTB_PLUGIN_DIR . '/includes/Booking.class.php' );
70
+
71
+ $bookings = array();
72
+ $booking_ids = $wpdb->get_results($wpdb->prepare("SELECT post_id FROM $wpdb->postmeta WHERE meta_key='rtb' AND meta_value LIKE %s", '%' . $email . '%'));
73
+ foreach ( $booking_ids as $booking_id ) {
74
+ $booking = new rtbBooking();
75
+ if ( $booking->load_post( $booking_id->post_id ) ) {
76
+ if ( ( $booking->post_status == 'pending' or $booking->post_status == 'confirmed' ) and time() < strtotime( $booking->date ) ) {
77
+ $bookings[] = array(
78
+ 'ID' => $booking->ID,
79
+ 'email' => $booking->email,
80
+ 'datetime' => $booking->format_date( $booking->date ),
81
+ 'party' => $booking->party
82
+ );
83
+ }
84
  }
85
  }
 
86
 
87
+ if ( ! empty($bookings) ) {
88
+ wp_send_json_success(
89
+ array(
90
+ 'bookings' => $bookings
91
+ )
92
+ );
93
+ }
94
+ else {
95
+ wp_send_json_error(
96
+ array(
97
+ 'error' => 'nobookings',
98
+ 'msg' => __( 'No bookings were found for the email address you entered.', 'restaurant-reservations' ),
99
+ )
100
+ );
101
+ }
102
 
103
+ die();
104
+ }
105
 
106
+ /**
107
+ * Cancel a reservation based on its ID, with the email address used for confirmation
108
+ * @since 2.1.0
109
+ */
110
+ public function cancel_reservation( $non_ajax = true ) {
111
+ global $rtb_controller;
112
 
113
+ $booking_id = isset($_REQUEST['booking_id']) ? absint( $_REQUEST['booking_id'] ) : '';
114
+ $booking_email = isset($_REQUEST['booking_email']) ? sanitize_email( $_REQUEST['booking_email'] ) : '';
115
 
116
+ require_once( RTB_PLUGIN_DIR . '/includes/Booking.class.php' );
117
 
118
+ $success = false;
119
 
120
+ $booking = new rtbBooking();
121
+ if ( $booking->load_post( $booking_id ) ) {
122
+ if ( $booking_email == $booking->email ) {
123
+ wp_update_post( array( 'ID' => $booking->ID, 'post_status' => 'cancelled' ) );
124
 
125
+ $success = true;
126
+ }
127
+ else {
128
+ wp_send_json_error(
129
+ array(
130
+ 'error' => 'invalidemail',
131
+ 'msg' => __( 'No booking matches the information that was sent.', 'restaurant-reservations' ),
132
+ )
133
+ );
134
+ }
135
  }
136
  else {
137
  wp_send_json_error(
138
  array(
139
+ 'error' => 'invalidid',
140
  'msg' => __( 'No booking matches the information that was sent.', 'restaurant-reservations' ),
141
  )
142
  );
143
  }
 
 
 
 
 
 
 
 
 
144
 
145
+ if ( $ajax ) {
146
+ if ( $success ) {
147
+ wp_send_json_success(
148
+ array(
149
+ 'booking_id' => $booking_id
150
+ )
151
+ );
152
+ }
153
+
154
+ die();
155
+ }
156
+ elseif ( $success ) {
157
+ $booking_page_id = $rtb_controller->settings->get_setting( 'booking-page' );
158
+ $booking_page_url = get_permalink( $booking_page_id );
159
+
160
+ $cancelled_url = add_query_arg(
161
  array(
162
+ 'bookingCancelled' => 'success'
163
+ ),
164
+ $booking_page_url
165
  );
 
166
 
167
+ header( 'location:' . $cancelled_url );
168
+ }
169
  }
 
 
 
 
 
 
 
 
 
 
170
 
171
+ /**
172
+ * Get available timeslots when "Max Reservations" or "Max People" is enabled
173
+ * @since 2.0.0
174
+ */
175
+ public function get_time_slots() {
176
+ global $rtb_controller;
177
 
178
+ $max_reservations_setting = $rtb_controller->settings->get_setting( 'rtb-max-tables-count' );
179
+ $max_reservations = substr( $max_reservations_setting, 0, strpos( $max_reservations_setting, '_' ) );
 
 
 
 
180
 
181
+ $max_people_setting = $rtb_controller->settings->get_setting( 'rtb-max-people-count' );
182
+ $max_people = substr( $max_people_setting, 0, strpos( $max_people_setting, '_' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
 
184
+ $this->year = sanitize_text_field( $_POST['year'] );
185
+ $this->month = sanitize_text_field( $_POST['month'] );
186
+ $this->day = sanitize_text_field( $_POST['day'] );
 
 
 
 
 
 
 
 
 
 
 
 
187
 
188
+ $dining_block_setting = $rtb_controller->settings->get_setting( 'rtb-dining-block-length' );
189
+ $dining_block = substr( $dining_block_setting, 0, strpos( $dining_block_setting, '_' ) );
190
+ $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
191
+
192
+ // Get opening/closing times for this particular day
193
+ $hours = $this->get_opening_hours();
194
 
195
+ // var_dump($hours);
 
 
 
 
 
196
 
197
+ // If the restaurant is closed that day, return false
198
+ if ( ! $hours ) { echo $hours; die(); }
199
+
200
+ $args = array(
201
+ 'posts_per_page' => -1,
202
+ 'date_range' => 'dates',
203
+ 'start_date' => $this->year . '-' . $this->month . '-' . $this->day,
204
+ 'end_date' => $this->year . '-' . $this->month . '-' . $this->day
205
+ );
206
+
207
+ require_once( RTB_PLUGIN_DIR . '/includes/Query.class.php' );
208
+ $query = new rtbQuery( $args );
209
+ $query->prepare_args();
210
+
211
+ // Get all current bookings sorted by date
212
+ $bookings = $query->get_bookings();
213
+
214
+ // Go through all current booking times and figure out when we're at or above the max
215
+ $blocked = false;
216
+ $blocked_times = array();
217
+ $current_times = array();
218
+ $party_sizes = array();
219
+ if ($max_reservations != 'undefined' and $max_reservations != 0) {
220
+ foreach ( $bookings as $key => $booking ) {
221
+ // Convert booking date to seconds from UNIX
222
+ $booking_time = strtotime($booking->date);
223
+ $current_times[] = $booking_time;
224
+
225
+ while ( sizeOf( $current_times ) > 0 and reset( $current_times ) < $booking_time - $dining_block_seconds ) {
226
+ //save the time to know when the blocking potentially ends
227
+ $removed_time = reset( $current_times );
228
+
229
+ // remove the expired time
230
+ array_shift( $current_times );
231
+
232
+ // remove the block if we've dropped below the max reservation
233
+ if ( $blocked and sizeOf( $current_times ) < $max_reservations ) {
234
+ $blocked = false;
235
+ $blocked_times[] = $removed_time + $dining_block_seconds;
236
+ }
237
  }
238
+
239
+ // Check if we're at or above the maximum number of reservations
240
+ if ( ! $blocked and sizeOf( $current_times ) >= $max_reservations ) {
241
+ $blocked = true;
242
+ $blocked_times[] = $booking_time - $dining_block_seconds;
243
+ }
244
  }
245
+ } else if ( $max_people != 'undefined' and $max_people != 0 ) {
246
+ foreach ( $bookings as $key => $booking ) {
247
+ // Convert booking date to seconds from UNIX
248
+ $booking_time = strtotime($booking->date);
249
+ $current_times[] = $booking_time;
250
+ $party_sizes[] = (int) $booking->party;
251
+
252
+ while ( sizeOf( $current_times ) > 0 and reset( $current_times ) < $booking_time - $dining_block_seconds ) {
253
+ //save the time to know when the blocking potentially ends
254
+ $removed_time = reset( $current_times );
255
+
256
+ // remove the expired time and party size
257
+ array_shift( $current_times );
258
+ array_shift( $party_sizes );
259
+
260
+ // remove the block if we've dropped below the max people count
261
+ if ( $blocked and array_sum($party_sizes) < $max_people ) {
262
+ $blocked = false;
263
+ $blocked_times[] = $removed_time + $dining_block_seconds;
264
+ }
265
+ }
266
+
267
+ // Check if we're at or above the maximum number of people
268
+ if ( ! $blocked and array_sum($party_sizes) >= $max_people ) {
269
+ $blocked = true;
270
+ $blocked_times[] = $booking_time - $dining_block_seconds;
271
+ }
272
  }
273
  }
274
+
275
+ if ( $blocked ) { $blocked_times[] = end( $current_times ) + $dining_block_seconds; }
276
+
277
+ $combined_times = array_merge( $blocked_times, $hours );
278
+ sort( $combined_times );
279
+
280
+ //Go through all of times to determine when the restaurant is open and not blocked
281
+ $open = false;
282
+ $blocked = false;
283
+ $valid_times = array();
284
+ foreach ( $combined_times as $time ) {
285
+ if ( in_array( $time, $blocked_times ) ) {
286
+ if ( ! $blocked ) {
287
+ $blocked = true;
288
+ if ( $open ) {
289
+ $valid_times[] = (object) array( 'from' => $this->format_pickadate_time( $open_time ), 'to' => $this->format_pickadate_time( $time ), 'inverted' => true );
290
+ }
291
+ }
292
+ else {
293
+ $blocked = false;
294
+ if ( $open ) { $open_time = $time; }
295
+ }
296
  }
297
  else {
298
+ if ( ! $open ) {
299
+ $open = true;
300
+ if ( ! $blocked ) { $open_time = $time; }
301
+ }
302
+ else {
303
+ $open = false;
304
+ if ( ! $blocked ) { $valid_times[] = (object) array( 'from' => $this->format_pickadate_time( $open_time ), 'to' => $this->format_pickadate_time( $time ), 'inverted' => true ); }
305
+ }
306
  }
307
  }
308
+
309
+ echo json_encode( $valid_times );
310
+
311
+ die();
312
  }
 
 
 
 
 
313
 
314
+ public function get_opening_hours() {
315
+ global $rtb_controller;
316
 
317
+ $schedule_closed = $rtb_controller->settings->get_setting( 'schedule-closed' );
318
 
319
+ $valid_times = array();
320
 
321
+ // Check if this date is an exception to the rules
322
+ if ( $schedule_closed !== 'undefined' ) {
323
 
324
+ foreach ( $schedule_closed as $closing ) {
325
+ $time = strtotime( $closing['date'] );
326
 
327
+ if ( date( 'Y', $time ) == $this->year &&
328
+ date( 'm', $time ) == $this->month &&
329
+ date( 'd', $time ) == $this->day
330
+ ) {
331
 
332
+ // Closed all day
333
+ if ( $closing['time'] == 'undefined' ) {
334
+ return false;
335
+ }
336
 
337
+ if ( $closing['time']['start'] !== 'undefined' ) {
338
+ $open_time = strtotime( $closing['date'] . ' ' . $closing['time']['start'] );
339
+ } else {
340
+ $open_time = strtotime( $closing['date'] ); // Start of the day
341
+ }
342
 
343
+ if ( $closing['time']['end'] !== 'undefined' ) {
344
+ $close_time = strtotime( $closing['date'] . ' ' . $closing['time']['end'] );
345
+ } else {
346
+ $close_time = strtotime( $closing['date'] . ' 23:59:59' ); // End of the day
347
+ }
348
 
349
+ $open_time = $this->get_earliest_time( $open_time );
350
 
351
+ if ( $open_time <= $close_time ) {
352
+ $valid_times[] = $open_time;
353
+ $valid_times[] = $close_time;
354
+ }
355
+ else {
356
+ return false;
357
+ }
358
  }
359
  }
 
360
 
361
+ // Exit early if this date is an exception
362
+ if ( isset( $open_time ) ) {
363
+ return $valid_times;
364
+ }
365
  }
 
366
 
367
+ $schedule_open = $rtb_controller->settings->get_setting( 'schedule-open' );
368
 
369
+ // Get any rules which apply to this weekday
370
+ if ( $schedule_open != 'undefined' ) {
371
 
372
+ $day_of_week = strtolower( date( 'l', strtotime( $this->year . '-' . $this->month . '-' . $this->day . ' 1:00:00' ) ) );
373
 
374
+ foreach ( $schedule_open as $opening ) {
375
 
376
+ if ( $opening['weekdays'] !== 'undefined' ) {
377
+ foreach ( $opening['weekdays'] as $weekday => $value ) {
378
+ if ( $weekday == $day_of_week ) {
379
 
380
+ // Closed all day
381
+ if ( $opening->time == 'undefined' ) {
382
+ return false;
383
+ }
384
 
385
+ if ( $opening['time']['start'] !== 'undefined' ) {
386
+ $open_time = strtotime( $this->year . '-' . $this->month . '-' . $this->day . ' ' . $opening['time']['start'] );
387
+ } else {
388
+ $open_time = strtotime( $this->year . '-' . $this->month . '-' . $this->day );
389
+ }
390
 
391
+ if ( $opening['time']['end'] !== 'undefined' ) {
392
+ $close_time = strtotime( $this->year . '-' . $this->month . '-' . $this->day . ' ' . $opening['time']['end'] );
393
+ } else {
394
+ $close_time = strtotime( $this->year . '-' . $this->month . '-' . $this->day . ' 23:59:59' ); // End of the day
395
+ }
396
 
397
+ $open_time = $this->get_earliest_time( $open_time );
398
 
399
+ if ( $open_time <= $close_time ) {
400
+ $valid_times[] = $open_time;
401
+ $valid_times[] = $close_time;
402
+ }
403
+ else {
404
+ return false;
405
+ }
406
  }
407
  }
408
  }
409
  }
 
410
 
411
+ // Pass any valid times located
412
+ if ( sizeOf( $valid_times ) >= 1 ) {
413
+ return $valid_times;
414
+ }
415
  }
416
+
417
+ return false;
418
  }
419
 
420
+ public function get_earliest_time( $open_time ) {
421
+ global $rtb_controller;
422
+
423
+ // Only make adjustments for current day selections
424
+ if ( date( 'y-m-d', strtotime( $this->year . '-' . $this->month . '-' . $this->day ) ) !== date( 'y-m-d' ) ) {
425
+ return $open_time;
426
+ }
427
 
428
+ $late_bookings = ( is_admin() && current_user_can( 'manage_bookings' ) ) ? '' : $rtb_controller->settings->get_setting( 'late-bookings' );
429
+
430
+ $open_time = time() > $open_time ? time() : $open_time;
431
+
432
+ if ( $late_bookings === 'number' && $late_bookings % 1 === 0 ) {
433
+ if ( time() + $late_bookings * 60 > $open_time ) {
434
+ $open_time = time() + $late_bookings;
435
+ }
436
+ }
437
 
 
 
438
  return $open_time;
439
+ }
440
+
441
+ /**
442
+ * Get number of seats remaining avilable to be booked
443
+ * @since 2.1.5
444
+ */
445
+ public function get_available_party_size() {
446
+ global $rtb_controller;
447
+
448
+ $max_people_setting = $rtb_controller->settings->get_setting( 'rtb-max-people-count' );
449
+ $max_people = substr( $max_people_setting, 0, strpos( $max_people_setting, '_' ) );
450
+
451
+ $this->year = sanitize_text_field( $_POST['year'] );
452
+ $this->month = sanitize_text_field( $_POST['month'] );
453
+ $this->day = sanitize_text_field( $_POST['day'] );
454
+ $this->time = sanitize_text_field( $_POST['time'] );
455
+
456
+ $dining_block_setting = $rtb_controller->settings->get_setting( 'rtb-dining-block-length' );
457
+ $dining_block = substr( $dining_block_setting, 0, strpos( $dining_block_setting, '_' ) );
458
+ $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
459
+
460
+ // Get opening/closing times for this particular day
461
+ $hours = $this->get_opening_hours();
462
+
463
+ // If the restaurant is closed that day, return false
464
+ if ( ! $hours ) { die(); }
465
 
466
+ // If no time is selected, return false
467
+ if ( ! $this->time ) { die(); }
468
+
469
+ $args = array(
470
+ 'posts_per_page' => -1,
471
+ 'date_range' => 'dates',
472
+ 'start_date' => $this->year . '-' . $this->month . '-' . $this->day,
473
+ 'end_date' => $this->year . '-' . $this->month . '-' . $this->day
474
+ );
475
+
476
+ require_once( RTB_PLUGIN_DIR . '/includes/Query.class.php' );
477
+ $query = new rtbQuery( $args );
478
+ $query->prepare_args();
479
+
480
+ // Get all current bookings sorted by date
481
+ $bookings = $query->get_bookings();
482
+
483
+ $selected_date_time = strtotime($this->year . '-' . $this->month . '-' . $this->day . ' ' . $this->time);
484
+ $selected_date_time_start = $selected_date_time - $dining_block_seconds;
485
+ $selected_date_time_end = $selected_date_time + $dining_block_seconds;
486
+ $party_sizes = [];
487
+
488
+ if ($max_people != 'undefined' and $max_people != 0) {
489
+
490
+ $max_time_size = 0;
491
+ $current_times = array();
492
+ $party_sizes = array();
493
+
494
+ // Go through all current booking and collect the total party size
495
+ foreach ( $bookings as $key => $booking ) {
496
+
497
+ // Convert booking date to seconds from UNIX
498
+ $booking_time = strtotime($booking->date);
499
+
500
+ // Ignore bookings outside of our time range
501
+ if ($booking_time < $selected_date_time_start or $booking_time > $selected_date_time_end) { continue; }
502
+
503
+ $current_times[] = $booking_time;
504
+ $party_sizes[] = (int) $booking->party;
505
+
506
+ while ( sizeOf( $current_times ) > 0 and reset( $current_times ) < $booking_time - $dining_block_seconds ) {
507
+ //save the time to know when the blocking potentially ends
508
+ $removed_time = reset( $current_times );
509
+
510
+ // remove the expired time and party size
511
+ array_shift( $current_times );
512
+ array_shift( $party_sizes );
513
+ }
514
+
515
+ $max_time_size = max( $max_time_size, array_sum( $party_sizes ) );
516
+ }
517
 
518
+ $response = (object) array( 'available_spots' => $max_people - $max_time_size);
519
 
520
+ echo json_encode($response);
521
+
522
+ die();
523
+ } else {
524
+ return false;
525
  }
526
  }
527
 
528
+ public function format_pickadate_time( $time ) {
529
+ return array( date( 'G', $time ), date( 'i', $time ) );
530
+ }
 
 
531
  }
 
 
532
  }
includes/InstallationWalkthrough.class.php CHANGED
@@ -162,9 +162,9 @@ class rtbInstallationWalkthrough {
162
  <p><?php _e('Thanks for choosing the Five-Star Restaurant Reservations! The following will help you get started with the setup of your reservations system by creating your reservations page, setting times when bookings are allowed as well as configuring a few key options.', 'restaurant-reservations'); ?></p>
163
  </div>
164
  <?php } ?>
165
-
166
  <div class='rtb-welcome-screen-box rtb-welcome-screen-reservations_page rtb-welcome-screen-open' data-screen='reservations_page'>
167
- <h2><?php _e('1. Add a Reservations Page', 'restaurant-reservations'); ?></h2>
168
  <div class='rtb-welcome-screen-box-content'>
169
  <p><?php _e('You can create a dedicated reservations booking page below, or skip this step and add your reservations to a page you\'ve already created manually.', 'restaurant-reservations'); ?></p>
170
  <div class='rtb-welcome-screen-menu-page'>
@@ -175,9 +175,9 @@ class rtbInstallationWalkthrough {
175
  <div class='clear'></div>
176
  </div>
177
  </div>
178
-
179
  <div class='rtb-welcome-screen-box rtb-welcome-screen-schedule_open' data-screen='schedule_open'>
180
- <h2><?php _e('2. Create Booking Schedule', 'restaurant-reservations'); ?></h2>
181
  <div class='rtb-welcome-screen-box-content'>
182
  <p><?php _e('Choose what times each week your restaurant is available to book reservations.', 'restaurant-reservations'); ?></p>
183
  <div class='rtb-welcome-screen-created-schedule-open'>
@@ -197,7 +197,7 @@ class rtbInstallationWalkthrough {
197
  </div>
198
 
199
  <div class='rtb-welcome-screen-box rtb-welcome-screen-options' data-screen='options'>
200
- <h2><?php _e('3. Set Key Options', 'restaurant-reservations'); ?></h2>
201
  <div class='rtb-welcome-screen-box-content'>
202
  <p><?php _e('Set a min/max party size for bookings, choose how early and late bookings can be made, and pick the time interval between different booking options.', 'restaurant-reservations'); ?></p>
203
  <div class='rtb-welcome-screen-option'>
162
  <p><?php _e('Thanks for choosing the Five-Star Restaurant Reservations! The following will help you get started with the setup of your reservations system by creating your reservations page, setting times when bookings are allowed as well as configuring a few key options.', 'restaurant-reservations'); ?></p>
163
  </div>
164
  <?php } ?>
165
+ <?php if (!isset($_GET['exclude'])) { ?>
166
  <div class='rtb-welcome-screen-box rtb-welcome-screen-reservations_page rtb-welcome-screen-open' data-screen='reservations_page'>
167
+ <h2><?php _e('Add a Reservations Page', 'restaurant-reservations'); ?></h2>
168
  <div class='rtb-welcome-screen-box-content'>
169
  <p><?php _e('You can create a dedicated reservations booking page below, or skip this step and add your reservations to a page you\'ve already created manually.', 'restaurant-reservations'); ?></p>
170
  <div class='rtb-welcome-screen-menu-page'>
175
  <div class='clear'></div>
176
  </div>
177
  </div>
178
+ <?php } ?>
179
  <div class='rtb-welcome-screen-box rtb-welcome-screen-schedule_open' data-screen='schedule_open'>
180
+ <h2><?php echo (isset($_GET['exclude']) ? '1.' : '2.') . __(' Create Booking Schedule', 'restaurant-reservations'); ?></h2>
181
  <div class='rtb-welcome-screen-box-content'>
182
  <p><?php _e('Choose what times each week your restaurant is available to book reservations.', 'restaurant-reservations'); ?></p>
183
  <div class='rtb-welcome-screen-created-schedule-open'>
197
  </div>
198
 
199
  <div class='rtb-welcome-screen-box rtb-welcome-screen-options' data-screen='options'>
200
+ <h2><?php echo (isset($_GET['exclude']) ? '2.' : '3.') . __(' Set Key Options', 'restaurant-reservations'); ?></h2>
201
  <div class='rtb-welcome-screen-box-content'>
202
  <p><?php _e('Set a min/max party size for bookings, choose how early and late bookings can be made, and pick the time interval between different booking options.', 'restaurant-reservations'); ?></p>
203
  <div class='rtb-welcome-screen-option'>
includes/Settings.class.php CHANGED
@@ -1256,6 +1256,20 @@ If you were not the one to cancel this booking, please contact us.
1256
  )
1257
  );
1258
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1259
  $sap->add_setting(
1260
  'rtb-settings',
1261
  'rtb-table-seat-assignments',
1256
  )
1257
  );
1258
 
1259
+ $sap->add_setting(
1260
+ 'rtb-settings',
1261
+ 'rtb-table-seat-assignments',
1262
+ 'count',
1263
+ array(
1264
+ 'id' => 'rtb-max-people-count',
1265
+ 'title' => __( 'Max People', 'restaurant-reservations' ),
1266
+ '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. Will be ignored if max reservations is set.', 'restaurant-reservations' ),
1267
+ 'min_value' => 1,
1268
+ 'max_value' => 100,
1269
+ 'increment' => 1
1270
+ )
1271
+ );
1272
+
1273
  $sap->add_setting(
1274
  'rtb-settings',
1275
  'rtb-table-seat-assignments',
includes/template-functions.php CHANGED
@@ -690,18 +690,19 @@ function rtb_enqueue_assets() {
690
  apply_filters(
691
  'rtb_pickadate_args',
692
  array(
693
- 'date_format' => rtb_esc_js( $rtb_controller->settings->get_setting( 'date-format' ) ),
694
- 'time_format' => rtb_esc_js( $rtb_controller->settings->get_setting( 'time-format' ) ),
695
- 'disable_dates' => rtb_get_datepicker_rules(),
696
- 'schedule_open' => $rtb_controller->settings->get_setting( 'schedule-open' ),
697
- 'schedule_closed' => $rtb_controller->settings->get_setting( 'schedule-closed' ),
698
- 'early_bookings' => is_admin() && current_user_can( 'manage_bookings' ) ? '' : $rtb_controller->settings->get_setting( 'early-bookings' ),
699
- 'late_bookings' => is_admin() && current_user_can( 'manage_bookings' ) ? '' : $rtb_controller->settings->get_setting( 'late-bookings' ),
700
- 'enable_max_reservations' => is_admin() && current_user_can( 'manage_bookings' ) ? false : $rtb_controller->settings->get_setting( 'rtb-enable-max-tables' ),
701
- 'date_onload' => $rtb_controller->settings->get_setting( 'date-onload' ),
702
- 'time_interval' => $rtb_controller->settings->get_setting( 'time-interval' ),
703
- 'first_day' => $rtb_controller->settings->get_setting( 'week-start' ),
704
- 'allow_past' => is_admin() && current_user_can( 'manage_bookings' ),
 
705
  )
706
  )
707
  );
@@ -1118,4 +1119,4 @@ if ( !function_exists('rtb_esc_js') ) {
1118
 
1119
  return preg_replace( '/[^a-zA-Z ,.-:\/]/', '', $value );
1120
  }
1121
- }
690
  apply_filters(
691
  'rtb_pickadate_args',
692
  array(
693
+ 'date_format' => rtb_esc_js( $rtb_controller->settings->get_setting( 'date-format' ) ),
694
+ 'time_format' => rtb_esc_js( $rtb_controller->settings->get_setting( 'time-format' ) ),
695
+ 'disable_dates' => rtb_get_datepicker_rules(),
696
+ 'schedule_open' => $rtb_controller->settings->get_setting( 'schedule-open' ),
697
+ 'schedule_closed' => $rtb_controller->settings->get_setting( 'schedule-closed' ),
698
+ 'early_bookings' => is_admin() && current_user_can( 'manage_bookings' ) ? '' : $rtb_controller->settings->get_setting( 'early-bookings' ),
699
+ 'late_bookings' => is_admin() && current_user_can( 'manage_bookings' ) ? '' : $rtb_controller->settings->get_setting( 'late-bookings' ),
700
+ 'enable_max_reservations' => is_admin() && current_user_can( 'manage_bookings' ) ? false : $rtb_controller->settings->get_setting( 'rtb-enable-max-tables' ),
701
+ 'max_people' => is_admin() && current_user_can( 'manage_bookings' ) ? 100 : $rtb_controller->settings->get_setting( 'rtb-max-people-count' ),
702
+ 'date_onload' => $rtb_controller->settings->get_setting( 'date-onload' ),
703
+ 'time_interval' => $rtb_controller->settings->get_setting( 'time-interval' ),
704
+ 'first_day' => $rtb_controller->settings->get_setting( 'week-start' ),
705
+ 'allow_past' => is_admin() && current_user_can( 'manage_bookings' ),
706
  )
707
  )
708
  );
1119
 
1120
  return preg_replace( '/[^a-zA-Z ,.-:\/]/', '', $value );
1121
  }
1122
+ }
lib/simple-admin-pages/classes/AdminPageSetting.Scheduler.class.php CHANGED
@@ -123,7 +123,7 @@ class sapAdminPageSettingScheduler_2_2_0 extends sapAdminPageSetting_2_2_0 {
123
  'delete' => null, // _x( 'Delete rule', 'Delete a scheduling rule', 'textdomain' ),
124
  'delete_schedule' => null, // __( 'Delete scheduling rule', 'textdomain' ),
125
  'never' => null, // _x( 'Never', 'Brief default description of a scheduling rule when no weekdays or weeks are included in the rule', 'textdomain' ),
126
- 'weekly_always' => null, // _x( 'Every day', 'Brief default description of a scheduling rule when all the weekdays/weeks are included in the rule', 'textdomain' ),
127
  'monthly_weekdays' => null, // _x( '%s on the %s week of the month', 'Brief default description of a scheduling rule when some weekdays are included on only some weeks of the month. %s should be left alone and will be replaced by a comma-separated list of days and weeks in the following format: M, T, W on the first, second week of the month', 'textdomain' ),
128
  'monthly_weeks' => null, // _x( '%s week of the month', 'Brief default description of a scheduling rule when some weeks of the month are included but all or no weekdays are selected. %s should be left alone and will be replaced by a comma-separated list of weeks in the following format: First, second week of the month', 'textdomain' ),
129
  'all_day' => null, // _x( 'All day', 'Brief default description of a scheduling rule when no times are set', 'textdomain' ),
@@ -650,7 +650,7 @@ class sapAdminPageSettingScheduler_2_2_0 extends sapAdminPageSetting_2_2_0 {
650
  if ( !is_array( $values ) || !count( $values ) ) {
651
  return $output;
652
  }
653
-
654
  foreach ( $values as $i => $rule ) {
655
 
656
  if ( !empty( $rule['weekdays'] ) ) {
123
  'delete' => null, // _x( 'Delete rule', 'Delete a scheduling rule', 'textdomain' ),
124
  'delete_schedule' => null, // __( 'Delete scheduling rule', 'textdomain' ),
125
  'never' => null, // _x( 'Never', 'Brief default description of a scheduling rule when no weekdays or weeks are included in the rule', 'textdomain' ),
126
+ 'weekly_always' => null, // _x( 'Every day', 'Brief default description of a scheduling rule when all the weekdays/weeks are included in the rule', 'textdomain' ),
127
  'monthly_weekdays' => null, // _x( '%s on the %s week of the month', 'Brief default description of a scheduling rule when some weekdays are included on only some weeks of the month. %s should be left alone and will be replaced by a comma-separated list of days and weeks in the following format: M, T, W on the first, second week of the month', 'textdomain' ),
128
  'monthly_weeks' => null, // _x( '%s week of the month', 'Brief default description of a scheduling rule when some weeks of the month are included but all or no weekdays are selected. %s should be left alone and will be replaced by a comma-separated list of weeks in the following format: First, second week of the month', 'textdomain' ),
129
  'all_day' => null, // _x( 'All day', 'Brief default description of a scheduling rule when no times are set', 'textdomain' ),
650
  if ( !is_array( $values ) || !count( $values ) ) {
651
  return $output;
652
  }
653
+
654
  foreach ( $values as $i => $rule ) {
655
 
656
  if ( !empty( $rule['weekdays'] ) ) {
readme.txt CHANGED
@@ -184,6 +184,9 @@ Find answers to even more questions in the [FAQ](http://doc.fivestarplugins.com/
184
 
185
  == Changelog ==
186
 
 
 
 
187
  = 2.1.4 (2020-05-26) =
188
  - Correcting calculation error for "per guest" deposits in ultimate version.
189
 
184
 
185
  == Changelog ==
186
 
187
+ = 2.1.5 (2020-05-28) =
188
+ - New option to enable a maximum number of seats at one time in the premium section
189
+
190
  = 2.1.4 (2020-05-26) =
191
  - Correcting calculation error for "per guest" deposits in ultimate version.
192
 
restaurant-reservations.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Five Star Restaurant Reservations
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.4
7
  * Author: FiveStarPlugins
8
  * Author URI: https://profiles.wordpress.org/fivestarplugins/
9
  * Text Domain: restaurant-reservations
3
  * Plugin Name: Five Star Restaurant Reservations
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.5
7
  * Author: FiveStarPlugins
8
  * Author URI: https://profiles.wordpress.org/fivestarplugins/
9
  * Text Domain: restaurant-reservations