PluginProbe
Booking Calendar / 11.8.3
Booking Calendar v11.8.3
11.8.3 11.8.2 11.8.1 11.8 11.7 11.6.1 11.6 11.5 11.4.3 11.4.2 11.4.1 11.4 11.3 11.2.1 11.2 11.1 11.0 10.15.7 10.15.6 10.1.3 10.10 10.10.1 10.10.2 10.11 10.11.2 All 203 releases
← All changes | includes/_capacity/calendar_load.php +101 -40 11.311.8.3 View file →
@@ -1,4 +1,4 @@
1 1 <?php
2 2 /**
3 3 * @file: wp-content/plugins/booking/includes/_capacity/calendar_load.php
4 4 */
@@ -44,13 +44,15 @@
44 44 }
45 45 $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . " , 'calendar_scroll_to' , " . $calendar_scroll_to . " ); ";
46 46
47 47 // Set Start / End Date in Calendar (JSON encode => safe quotes).
48 - $params['calendar_dates_start'] = ( empty( $params['calendar_dates_start'] ) ) ? '' : (string) $params['calendar_dates_start'];
49 - $params['calendar_dates_end'] = ( empty( $params['calendar_dates_end'] ) ) ? '' : (string) $params['calendar_dates_end'];
48 + $params['calendar_dates_start'] = ( empty( $params['calendar_dates_start'] ) ) ? '' : (string) $params['calendar_dates_start'];
49 + $params['calendar_dates_end'] = ( empty( $params['calendar_dates_end'] ) ) ? '' : (string) $params['calendar_dates_end'];
50 + $params['classic_booking_context_token'] = empty( $params['classic_booking_context_token'] ) ? '' : (string) $params['classic_booking_context_token'];
50 51
51 52 $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . " , 'calendar_dates_start' , " . wp_json_encode( $params['calendar_dates_start'] ) . " ); ";
52 - $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . " , 'calendar_dates_end' , " . wp_json_encode( $params['calendar_dates_end'] ) . " ); ";
53 + $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . " , 'calendar_dates_end' , " . wp_json_encode( $params['calendar_dates_end'] ) . " ); ";
54 + $start_script_code .= " _wpbc.booking__set_param_value( " . $resource_id . " , 'classic_booking_context_token' , " . wp_json_encode( $params['classic_booking_context_token'] ) . " ); ";
53 55
54 56 if ( ( '' !== $params['calendar_dates_start'] ) || ( '' !== $params['calendar_dates_end'] ) ) {
55 57 $start_script_code .= wpbc_get_localized_js__time_local( $params['calendar_dates_start'] );
56 58 }
@@ -66,9 +68,9 @@
66 68 $months_num = max( 1, min( 36, $months_num ) );
67 69 $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . " , 'calendar_number_of_months' , " . wp_json_encode( (string) $months_num ) . " ); ";
68 70
69 71 // Days Selection.
70 - $days_selection_arr = wpbc__calendar__js_params__get_days_selection_arr();
72 + $days_selection_arr = wpbc__calendar__js_params__get_days_selection_arr();
71 73
72 74 $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'days_select_mode', " . wp_json_encode( (string) $days_selection_arr['days_select_mode'] ) . " ); ";
73 75 $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'fixed__days_num', " . intval( $days_selection_arr['fixed__days_num'] ) . " ); ";
74 76
@@ -75,12 +77,32 @@
75 77 // Keep legacy: these are stored as comma lists like "-1" or "0,1".
76 78 $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'fixed__week_days__start', [" . $days_selection_arr['fixed__week_days__start'] . "] ); ";
77 79 $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'dynamic__days_min', " . intval( $days_selection_arr['dynamic__days_min'] ) . " ); ";
78 80 $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'dynamic__days_max', " . intval( $days_selection_arr['dynamic__days_max'] ) . " ); ";
79 - $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'dynamic__days_specific', [" . $days_selection_arr['dynamic__days_specific'] . "] ); ";
80 - $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'dynamic__week_days__start', [" . $days_selection_arr['dynamic__week_days__start'] . "] ); ";
81 -
82 - // Date / Time formats.
81 + $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'dynamic__days_specific', [" . $days_selection_arr['dynamic__days_specific'] . "] ); ";
82 + $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'dynamic__week_days__start', [" . $days_selection_arr['dynamic__week_days__start'] . "] ); ";
83 +
84 + // Informational help shown between the first and second clicks in range mode.
85 + // Integrations can disable it per calendar/resource without changing the selection engine.
86 + /**
87 + * Filters whether the two-click range-selection guidance is shown for a calendar.
88 + *
89 + * @param bool $is_enabled Whether guidance is enabled.
90 + * @param int $resource_id Booking resource ID.
91 + * @param array $params Calendar shortcode/render parameters.
92 + */
93 + $range_selection_guidance_default = function_exists( 'wpbc_frontend_messages__is_enabled' )
94 + ? wpbc_frontend_messages__is_enabled( 'message_range_selection_click_last_date' )
95 + : true;
96 + $range_selection_guidance_is_enabled = (bool) apply_filters(
97 + 'wpbc_calendar_range_selection_guidance_is_enabled',
98 + $range_selection_guidance_default,
99 + $resource_id,
100 + $params
101 + );
102 + $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'range_selection_guidance_is_enabled', " . ( $range_selection_guidance_is_enabled ? 'true' : 'false' ) . " ); ";
103 +
104 + // Date / Time formats.
83 105 $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'booking_date_format', " . wp_json_encode( (string) get_bk_option( 'booking_date_format' ) ) . " ); ";
84 106 $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'booking_time_format', " . wp_json_encode( (string) get_bk_option( 'booking_time_format' ) ) . " ); ";
85 107
86 108 // Capacity | availability.
@@ -114,21 +136,28 @@
114 136
115 137 /**
116 138 * Get days selection parameters, which saved in database
117 139 *
118 - * @return array
119 - */
120 - function wpbc__calendar__js_params__get_days_selection_arr(){
140 + * @return array
141 + */
142 + function wpbc__calendar__js_params__get_days_selection_arr(){
121 143
122 144 $specific_days_selection = ( function_exists( 'wpbc_get_specific_range_dates__as_comma_list' ) )
123 145 ? wpbc_get_specific_range_dates__as_comma_list( get_bk_option( 'booking_range_selection_days_specific_num_dynamic' ) )
124 146 : '';
125 - $data_arr = array();
126 - // Modes :: Selection of Days
127 - $data_arr['days_select_mode'] = ( 'range' === get_bk_option('booking_type_of_day_selections') )
128 - ? get_bk_option('booking_range_selection_type')
129 - : get_bk_option( 'booking_type_of_day_selections');
130 - $data_arr['fixed__days_num'] = intval( get_bk_option( 'booking_range_selection_days_count' ) ); /* Number of days selection with 1 mouse click */
147 + $data_arr = array();
148 + // Modes :: Selection of Days.
149 + $day_selection_type = get_bk_option( 'booking_type_of_day_selections' );
150 + if ( 'range' === $day_selection_type ) {
151 + // Free/Personal use the unrestricted two-click range. Business Small+ can apply its saved range subtype/rules.
152 + $data_arr['days_select_mode'] = class_exists( 'wpdev_bk_biz_s' )
153 + ? get_bk_option( 'booking_range_selection_type' )
154 + : 'dynamic';
155 + } else {
156 + $data_arr['days_select_mode'] = $day_selection_type;
157 + }
158 + $fixed_days_num = absint( get_bk_option( 'booking_range_selection_days_count' ) );
159 + $data_arr['fixed__days_num'] = ( 0 < $fixed_days_num ) ? min( 180, $fixed_days_num ) : 3; /* Number of days selection with 1 mouse click */
131 160 $data_arr['fixed__week_days__start'] = get_bk_option( 'booking_range_start_day' ); /* { -1 - Any | 0 - Su, 1 - Mo, 2 - Tu, 3 - We, 4 - Th, 5 - Fr, 6 - Sat } */
132 161 $data_arr['dynamic__days_min'] = intval( get_bk_option( 'booking_range_selection_days_count_dynamic' ) ); /* Min. Number of days selection with 2 mouse clicks */
133 162 $data_arr['dynamic__days_max'] = intval( get_bk_option( 'booking_range_selection_days_max_count_dynamic' ) ); /* Max. Number of days selection with 2 mouse clicks */
134 163 $data_arr['dynamic__days_specific'] = $specific_days_selection; /* Example: '5,7' */
@@ -133,12 +162,15 @@
133 162 $data_arr['dynamic__days_max'] = intval( get_bk_option( 'booking_range_selection_days_max_count_dynamic' ) ); /* Max. Number of days selection with 2 mouse clicks */
134 163 $data_arr['dynamic__days_specific'] = $specific_days_selection; /* Example: '5,7' */
135 164 $data_arr['dynamic__week_days__start'] = get_bk_option( 'booking_range_start_day_dynamic' ); /* { -1 - Any | 0 - Su, 1 - Mo, 2 - Tu, 3 - We, 4 - Th, 5 - Fr, 6 - Sat } */
136 165
137 - // Fix about possible issue of downgrade from Paid to free version and try to use 'Range days' selection, which is not supports in that version. // FixIn: 10.4.0.4.
138 - if ( ( ! class_exists( 'wpdev_bk_biz_s' ) ) && ( in_array( $data_arr['days_select_mode'], array( 'dynamic', 'fixed' ) ) ) ) {
139 - $data_arr['days_select_mode'] = 'multiple';
140 - }
166 + // A fixed one-click range remains Business Small+. On downgrade, preserve the Range choice but use Free's unrestricted two-click mode.
167 + if ( ( ! class_exists( 'wpdev_bk_biz_s' ) ) && ( in_array( $data_arr['days_select_mode'], array( 'dynamic', 'fixed' ), true ) ) ) {
168 + $data_arr['days_select_mode'] = 'dynamic';
169 + $data_arr['dynamic__days_min'] = 1;
170 + $data_arr['dynamic__days_specific'] = '';
171 + $data_arr['dynamic__week_days__start'] = '-1';
172 + }
141 173
142 174 return $data_arr;
143 175 }
144 176
@@ -163,12 +195,13 @@
163 195 'start_month_calendar' => false,
164 196 'shortcode_options' => '',
165 197 'custom_form' => 'standard',
166 198 'calendar_dates_start' => '',
167 - 'calendar_dates_end' => '',
199 + 'calendar_dates_end' => '',
200 + 'classic_booking_context_token' => '',
168 201 'skip_general_availability' => 0,
169 - 'calendar_request_overrides' => array(),
170 - );
202 + 'calendar_request_overrides' => array(),
203 + );
171 204 $params = wp_parse_args( $params, $defaults );
172 205
173 206 // Resource ID.
174 207 $params['resource_id'] = absint( $params['resource_id'] );
@@ -223,16 +256,19 @@
223 256 'request_uri' => $server_request_uri,
224 257 'custom_form' => (string) $params['custom_form'],
225 258 'aggregate_resource_id_str' => implode( ',', (array) $params['aggregate_resource_id_arr'] ),
226 259 'aggregate_type' => (string) $aggregate_type,
227 - 'skip_general_availability' => (int) $params['skip_general_availability'],
260 + 'skip_general_availability' => (int) $params['skip_general_availability'],
261 + 'classic_booking_context_token' => (string) $params['classic_booking_context_token'],
228 262 );
229 263
230 - if ( ! empty( $params['calendar_request_overrides'] ) && is_array( $params['calendar_request_overrides'] ) ) {
231 - foreach ( $params['calendar_request_overrides'] as $override_key => $override_value ) {
232 - if ( 0 === strpos( (string) $override_key, 'wpbc_settings_calendar_preview' ) ) {
233 - $params_for_request[ $override_key ] = $override_value;
234 - }
264 + if ( ! empty( $params['calendar_request_overrides'] ) && is_array( $params['calendar_request_overrides'] ) ) {
265 + foreach ( $params['calendar_request_overrides'] as $override_key => $override_value ) {
266 + if ( 'allow_past' === $override_key ) {
267 + $params_for_request['allow_past'] = ! empty( $override_value ) ? 1 : 0;
268 + } elseif ( 0 === strpos( (string) $override_key, 'wpbc_settings_calendar_preview' ) ) {
269 + $params_for_request[ $override_key ] = $override_value;
270 + }
235 271 }
236 272 }
237 273
238 274 // Send Ajax request to load bookings.
@@ -325,10 +361,12 @@
325 361 'user_id' => $user_id,
326 362 'request_rules_structure' => array(
327 363 'resource_id' => array( 'validate' => 'd', 'default' => 1 ), // 'digit_or_csd'
328 364 'booking_hash' => array( 'validate' => 's', 'default' => '' ),
329 - 'request_uri' => array( 'validate' => 's', 'default' => '' ),
330 - 'custom_form' => array( 'validate' => 's', 'default' => 'standard' ),
365 + 'request_uri' => array( 'validate' => 's', 'default' => '' ),
366 + 'custom_form' => array( 'validate' => 's', 'default' => 'standard' ),
367 + 'allow_past' => array( 'validate' => 'd', 'default' => 0 ),
368 + 'classic_booking_context_token' => array( 'validate' => 'strong', 'default' => '' ),
331 369 'aggregate_resource_id_str' => array( 'validate' => 'digit_or_csd', 'default' => '' ), // Comma separated string of resource ID, which was used in 'aggregate' parameter.
332 370 'aggregate_type' => array( 'validate' => 's', 'default' => 'all' ), // 'all' | 'bookings_only' // FixIn: 9.8.15.10.
333 371 'dates_to_check' => array( 'validate' => 'array', 'default' => '' ), // 'all' | 'bookings_only' // FixIn: 9.8.15.10.
334 372 'skip_general_availability' => array( 'validate' => 'd', 'default' => 0 ),
@@ -367,10 +405,32 @@
367 405 'wpbc_settings_calendar_preview_booked_details' => array( 'validate' => 's', 'default' => '' ),
368 406 )
369 407 )
370 408 );
371 - $request_prefix = 'calendar_request_params';
372 - $request_params = $user_request->get_sanitized__in_request__value_or_default( $request_prefix ); // NOT Direct: $_REQUEST['search_params']['resource_id']
409 + $request_prefix = 'calendar_request_params';
410 + $request_params = $user_request->get_sanitized__in_request__value_or_default( $request_prefix ); // NOT Direct: $_REQUEST['search_params']['resource_id']
411 + if ( ! empty( $request_params['classic_booking_context_token'] ) && function_exists( 'wpbc_classic_booking_context_validate_submission' ) ) {
412 + $classic_context = wpbc_classic_booking_context_validate_submission(
413 + $request_params['classic_booking_context_token'],
414 + $request_params['resource_id'],
415 + $request_params['dates_to_check'],
416 + $request_params['custom_form'],
417 + $request_params['aggregate_resource_id_str']
418 + );
419 + if ( ! is_wp_error( $classic_context ) ) {
420 + $request_params['allow_past'] = ! empty( $classic_context['allow_past'] ) ? 1 : 0;
421 + // Use the signed canonical set so equivalent wire shapes cannot change availability input.
422 + $request_params['aggregate_resource_id_str'] = implode( ',', $classic_context['aggregate_resource_ids'] );
423 + $request_params['dates_to_check'] = array(
424 + $classic_context['calendar_dates_start'],
425 + $classic_context['calendar_dates_end'],
426 + );
427 + } else {
428 + $request_params['allow_past'] = 0;
429 + }
430 + }
431 + $can_allow_past = ! empty( $request_params['allow_past'] );
432 + $request_params['allow_past'] = $can_allow_past ? 1 : 0;
373 433
374 434 if ( ! empty( $request_params['skip_general_availability'] ) ) {
375 435 $can_skip_general_availability = (
376 436 function_exists( 'wpbc_availability_general__get_manage_cap' )
@@ -399,14 +459,15 @@
399 459 unset( $aggregate_resource_id_arr[ $resource_id_key ] ); // Remove source booking resource from aggregate ARR. // FixIn: 9.8.15.10.
400 460 }
401 461 $aggregate_resource_id_arr = array_values($aggregate_resource_id_arr); // Reset keys
402 462
403 - $availability_per_days__params = array(
404 - 'resource_id' => $request_params['resource_id'],
405 - 'max_days_count' => $max_days_count,
406 - 'skip_booking_id' => $skip_booking_id,
407 - 'request_uri' => $request_params['request_uri'], // It different in Ajax requests than $server_request_uri . It's used for change-over days to detect for exception at specific pages
408 - 'custom_form' => $request_params['custom_form']
463 + $availability_per_days__params = array(
464 + 'resource_id' => $request_params['resource_id'],
465 + 'max_days_count' => $max_days_count,
466 + 'skip_booking_id' => $skip_booking_id,
467 + 'request_uri' => $request_params['request_uri'], // It different in Ajax requests than $server_request_uri . It's used for change-over days to detect for exception at specific pages
468 + 'custom_form' => $request_params['custom_form'],
469 + 'allow_past' => ! empty( $request_params['allow_past'] )
409 470 , 'additional_bk_types' => $aggregate_resource_id_arr // It is array of booking resources from aggregate parameter() // arrays | CSD | int // OPTIONAL
410 471 , 'aggregate_type' => $request_params['aggregate_type'] // It is string: 'all' | 'bookings_only' // OPTIONAL
411 472 , 'skip_general_availability' => $request_params['skip_general_availability']
412 473 // , 'as_single_resource' => true // get dates as for 'single resource' or 'parent' resource including bookings in all 'child booking resources'