PluginProbe
Booking Calendar / 11.9
Booking Calendar v11.9
11.9 11.8.4 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 All 205 releases
← All changes | includes/_capacity/calendar_load.php +115 -42 11.3 → 11.9 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,29 @@
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 (
269 + 0 === strpos( (string) $override_key, 'wpbc_settings_calendar_preview' )
270 + || in_array(
271 + (string) $override_key,
272 + array(
273 + 'wpbc_setup_wizard_date_selection_preview',
274 + 'wpbc_setup_wizard_date_selection_preview_nonce',
275 + ),
276 + true
277 + )
278 + ) {
279 + $params_for_request[ $override_key ] = $override_value;
280 + }
235 281 }
236 282 }
237 283
238 284 // Send Ajax request to load bookings.
@@ -325,10 +371,12 @@
325 371 'user_id' => $user_id,
326 372 'request_rules_structure' => array(
327 373 'resource_id' => array( 'validate' => 'd', 'default' => 1 ), // 'digit_or_csd'
328 374 'booking_hash' => array( 'validate' => 's', 'default' => '' ),
329 - 'request_uri' => array( 'validate' => 's', 'default' => '' ),
330 - 'custom_form' => array( 'validate' => 's', 'default' => 'standard' ),
375 + 'request_uri' => array( 'validate' => 's', 'default' => '' ),
376 + 'custom_form' => array( 'validate' => 's', 'default' => 'standard' ),
377 + 'allow_past' => array( 'validate' => 'd', 'default' => 0 ),
378 + 'classic_booking_context_token' => array( 'validate' => 'strong', 'default' => '' ),
331 379 'aggregate_resource_id_str' => array( 'validate' => 'digit_or_csd', 'default' => '' ), // Comma separated string of resource ID, which was used in 'aggregate' parameter.
332 380 'aggregate_type' => array( 'validate' => 's', 'default' => 'all' ), // 'all' | 'bookings_only' // FixIn: 9.8.15.10.
333 381 'dates_to_check' => array( 'validate' => 'array', 'default' => '' ), // 'all' | 'bookings_only' // FixIn: 9.8.15.10.
334 382 'skip_general_availability' => array( 'validate' => 'd', 'default' => 0 ),
@@ -363,14 +411,38 @@
363 411 'wpbc_settings_calendar_preview_cost_word' => array( 'validate' => 's', 'default' => '' ),
364 412 'wpbc_settings_calendar_preview_show_cost_cell' => array( 'validate' => array( 'On', 'Off' ), 'default' => 'Off' ),
365 413 'wpbc_settings_calendar_preview_cost_currency' => array( 'validate' => 's', 'default' => '' ),
366 414 'wpbc_settings_calendar_preview_show_booked_details' => array( 'validate' => array( 'On', 'Off' ), 'default' => 'Off' ),
367 - 'wpbc_settings_calendar_preview_booked_details' => array( 'validate' => 's', 'default' => '' ),
368 - )
415 + 'wpbc_settings_calendar_preview_booked_details' => array( 'validate' => 's', 'default' => '' ),
416 + 'wpbc_setup_wizard_date_selection_preview' => array( 'validate' => 'd', 'default' => 0 ),
417 + 'wpbc_setup_wizard_date_selection_preview_nonce' => array( 'validate' => 'strong', 'default' => '' ),
418 + )
369 419 )
370 420 );
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']
421 + $request_prefix = 'calendar_request_params';
422 + $request_params = $user_request->get_sanitized__in_request__value_or_default( $request_prefix ); // NOT Direct: $_REQUEST['search_params']['resource_id']
423 + if ( ! empty( $request_params['classic_booking_context_token'] ) && function_exists( 'wpbc_classic_booking_context_validate_submission' ) ) {
424 + $classic_context = wpbc_classic_booking_context_validate_submission(
425 + $request_params['classic_booking_context_token'],
426 + $request_params['resource_id'],
427 + $request_params['dates_to_check'],
428 + $request_params['custom_form'],
429 + $request_params['aggregate_resource_id_str']
430 + );
431 + if ( ! is_wp_error( $classic_context ) ) {
432 + $request_params['allow_past'] = ! empty( $classic_context['allow_past'] ) ? 1 : 0;
433 + // Use the signed canonical set so equivalent wire shapes cannot change availability input.
434 + $request_params['aggregate_resource_id_str'] = implode( ',', $classic_context['aggregate_resource_ids'] );
435 + $request_params['dates_to_check'] = array(
436 + $classic_context['calendar_dates_start'],
437 + $classic_context['calendar_dates_end'],
438 + );
439 + } else {
440 + $request_params['allow_past'] = 0;
441 + }
442 + }
443 + $can_allow_past = ! empty( $request_params['allow_past'] );
444 + $request_params['allow_past'] = $can_allow_past ? 1 : 0;
373 445
374 446 if ( ! empty( $request_params['skip_general_availability'] ) ) {
375 447 $can_skip_general_availability = (
376 448 function_exists( 'wpbc_availability_general__get_manage_cap' )
@@ -399,14 +471,15 @@
399 471 unset( $aggregate_resource_id_arr[ $resource_id_key ] ); // Remove source booking resource from aggregate ARR. // FixIn: 9.8.15.10.
400 472 }
401 473 $aggregate_resource_id_arr = array_values($aggregate_resource_id_arr); // Reset keys
402 474
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']
475 + $availability_per_days__params = array(
476 + 'resource_id' => $request_params['resource_id'],
477 + 'max_days_count' => $max_days_count,
478 + 'skip_booking_id' => $skip_booking_id,
479 + '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
480 + 'custom_form' => $request_params['custom_form'],
481 + 'allow_past' => ! empty( $request_params['allow_past'] )
409 482 , 'additional_bk_types' => $aggregate_resource_id_arr // It is array of booking resources from aggregate parameter() // arrays | CSD | int // OPTIONAL
410 483 , 'aggregate_type' => $request_params['aggregate_type'] // It is string: 'all' | 'bookings_only' // OPTIONAL
411 484 , 'skip_general_availability' => $request_params['skip_general_availability']
412 485 // , 'as_single_resource' => true // get dates as for 'single resource' or 'parent' resource including bookings in all 'child booking resources'