| @@ -1,95 +1,133 @@ | ||
| 1 | 1 | <?php |
| 2 | +/** | |
| 3 | + * @file: wp-content/plugins/booking/includes/_capacity/calendar_load.php | |
| 4 | + */ | |
| 2 | 5 | |
| 3 | 6 | if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly // FixIn: 9.8.0.4. |
| 4 | 7 | |
| 5 | 8 | /** |
| 6 | - * Define parameters for calendar -- which is required for JS calendar show | |
| 9 | + * Define parameters for calendar -- required for JS calendar show | |
| 7 | 10 | * |
| 8 | - * @param $params | |
| 11 | + * @param array $params | |
| 9 | 12 | * |
| 10 | - * @return string | |
| 13 | + * @return string JS code body (no <script> wrapper) | |
| 11 | 14 | */ |
| 12 | 15 | function wpbc__calendar__set_js_params__before_show( $params ) { |
| 13 | 16 | |
| 14 | 17 | $start_script_code = ''; |
| 15 | 18 | |
| 16 | - // Server Balancer ------------------------------------------------------------------------------------------- //FixIn: // FixIn: 9.8.6.2. | |
| 19 | + // Server Balancer. | |
| 17 | 20 | $balancer_max_threads = intval( get_bk_option( 'booking_load_balancer_max_threads' ) ); |
| 18 | 21 | $balancer_max_threads = ( empty( $balancer_max_threads ) ) ? 1 : $balancer_max_threads; |
| 19 | 22 | $start_script_code .= " _wpbc.balancer__set_max_threads( " . $balancer_max_threads . " ); "; |
| 20 | 23 | |
| 21 | - $resource_id = isset( $params['resource_id'] ) ? intval( $params['resource_id'] ) : 1; | |
| 24 | + $resource_id = isset( $params['resource_id'] ) ? absint( $params['resource_id'] ) : 1; | |
| 22 | 25 | |
| 23 | - // Start Month ---------------------------------------------------------------------------------------------------- | |
| 24 | - $calendar_scroll_to = ( ( isset( $params['start_month_calendar'] ) ) && ( is_array( $params['start_month_calendar'] ) ) && ( count( $params['start_month_calendar'] ) > 0 ) ) | |
| 25 | - ? "[ " . strval( intval( $params['start_month_calendar'][0] ) ) . "," . strval( intval( $params['start_month_calendar'][1] ) ) . " ]" | |
| 26 | - : 'false'; | |
| 26 | + if ( function_exists( 'wpbc_is_booking_used_check_in_out_time' ) ) { | |
| 27 | + $is_enabled_change_over = wpbc_is_booking_used_check_in_out_time( false, $resource_id ); | |
| 28 | + $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . " , 'is_enabled_change_over' , " . ( $is_enabled_change_over ? 'true' : 'false' ) . " ); "; | |
| 29 | + $start_script_code .= " _wpbc.set_other_param( 'is_enabled_change_over', " . ( $is_enabled_change_over ? 'true' : 'false' ) . " ); "; | |
| 30 | + } | |
| 31 | + | |
| 32 | + // Start Month (require [year,month]). | |
| 33 | + $calendar_scroll_to = 'false'; | |
| 34 | + if ( | |
| 35 | + isset( $params['start_month_calendar'] ) | |
| 36 | + && is_array( $params['start_month_calendar'] ) | |
| 37 | + && ( count( $params['start_month_calendar'] ) > 1 ) | |
| 38 | + ) { | |
| 39 | + $y = intval( $params['start_month_calendar'][0] ); | |
| 40 | + $m = intval( $params['start_month_calendar'][1] ); | |
| 41 | + if ( ( $y > 0 ) && ( $m > 0 ) ) { | |
| 42 | + $calendar_scroll_to = "[ " . (string) $y . "," . (string) $m . " ]"; | |
| 43 | + } | |
| 44 | + } | |
| 27 | 45 | $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . " , 'calendar_scroll_to' , " . $calendar_scroll_to . " ); "; |
| 28 | 46 | |
| 29 | - // Max months to scroll ------------------------------------------------------------------------------------------- | |
| 30 | - $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . " , 'booking_max_monthes_in_calendar' , '" . esc_js( get_bk_option( 'booking_max_monthes_in_calendar' ) ) . "' ); "; // FixIn: 10.6.1.3. | |
| 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']; | |
| 50 | + $params['classic_booking_context_token'] = empty( $params['classic_booking_context_token'] ) ? '' : (string) $params['classic_booking_context_token']; | |
| 31 | 51 | |
| 32 | - // Start of WeekDay ----------------------------------------------------------------------------------------------- | |
| 33 | - $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . " , 'booking_start_day_weeek' , '" . esc_js( get_bk_option( 'booking_start_day_weeek' ) ) . "' ); "; // FixIn: 10.6.1.3. | |
| 52 | + $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . " , 'calendar_dates_start' , " . wp_json_encode( $params['calendar_dates_start'] ) . " ); "; | |
| 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'] ) . " ); "; | |
| 34 | 55 | |
| 35 | - // Number of visible months ----------------------------------------------------------------------------------------------- | |
| 36 | - $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . " , 'calendar_number_of_months' , '" . $params['calendar_number_of_months'] . "' ); "; | |
| 56 | + if ( ( '' !== $params['calendar_dates_start'] ) || ( '' !== $params['calendar_dates_end'] ) ) { | |
| 57 | + $start_script_code .= wpbc_get_localized_js__time_local( $params['calendar_dates_start'] ); | |
| 58 | + } | |
| 37 | 59 | |
| 38 | - // ----------------------------------------------------------------------------------------------------------------- | |
| 39 | - // Days Selection | |
| 40 | - // ----------------------------------------------------------------------------------------------------------------- | |
| 41 | - $days_selection_arr = wpbc__calendar__js_params__get_days_selection_arr(); | |
| 42 | - $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'days_select_mode', '" . $days_selection_arr['days_select_mode'] . "' ); "; | |
| 43 | - $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'fixed__days_num', " . $days_selection_arr['fixed__days_num'] . " ); "; | |
| 44 | - $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'fixed__week_days__start', [" .$days_selection_arr['fixed__week_days__start'] . "] ); "; | |
| 45 | - $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'dynamic__days_min', " . $days_selection_arr['dynamic__days_min'] . " ); "; | |
| 46 | - $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'dynamic__days_max', " . $days_selection_arr['dynamic__days_max'] . " ); "; | |
| 47 | - $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'dynamic__days_specific', [" .$days_selection_arr['dynamic__days_specific'] . "] ); "; | |
| 48 | - $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'dynamic__week_days__start', [" .$days_selection_arr['dynamic__week_days__start'] . "] ); "; | |
| 60 | + // Max months to scroll. | |
| 61 | + $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . " , 'booking_max_monthes_in_calendar' , " . wp_json_encode( (string) get_bk_option( 'booking_max_monthes_in_calendar' ) ) . " ); "; | |
| 49 | 62 | |
| 50 | - /** | |
| 51 | - * For Debug :: | |
| 52 | - // $start_script_code .= " _wpbc.calendar__set_parameters( " . $resource_id . ", { | |
| 53 | - // 'days_select_mode' : 'dynamic', | |
| 54 | - // 'dynamic__days_min' : 7, | |
| 55 | - // 'dynamic__days_max' : 14, | |
| 56 | - // 'dynamic__days_specific' : [7,10,14], | |
| 57 | - // 'dynamic__week_days__start' : [-1] | |
| 58 | - // } ); "; | |
| 59 | - // Calendar - Set calendar parameter and value | |
| 60 | - // $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'days_select_mode' , 'multiple' ); "; | |
| 61 | - // $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'days_select_mode' , 'fixed' ); "; | |
| 62 | - // $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'fixed__days_num' , 7 ); "; | |
| 63 | - // $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'fixed__week_days__start' , [-1] ); "; | |
| 64 | - */ | |
| 63 | + // Start of week day. | |
| 64 | + $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . " , 'booking_start_day_weeek' , " . wp_json_encode( (string) get_bk_option( 'booking_start_day_weeek' ) ) . " ); "; | |
| 65 | 65 | |
| 66 | - // Date / Time formats: | |
| 67 | - $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'booking_date_format', '" . esc_js( get_bk_option( 'booking_date_format' ) ) . "' ); "; | |
| 68 | - $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'booking_time_format', '" . esc_js( get_bk_option( 'booking_time_format' ) ) . "' ); "; | |
| 66 | + // Number of visible months. | |
| 67 | + $months_num = isset( $params['calendar_number_of_months'] ) ? (int) $params['calendar_number_of_months'] : 1; | |
| 68 | + $months_num = max( 1, min( 36, $months_num ) ); | |
| 69 | + $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . " , 'calendar_number_of_months' , " . wp_json_encode( (string) $months_num ) . " ); "; | |
| 69 | 70 | |
| 70 | - // Capacity | availability ---------------------------------------------------------------------------------------- | |
| 71 | + // Days Selection. | |
| 72 | + $days_selection_arr = wpbc__calendar__js_params__get_days_selection_arr(); | |
| 73 | + | |
| 74 | + $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'days_select_mode', " . wp_json_encode( (string) $days_selection_arr['days_select_mode'] ) . " ); "; | |
| 75 | + $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'fixed__days_num', " . intval( $days_selection_arr['fixed__days_num'] ) . " ); "; | |
| 76 | + | |
| 77 | + // Keep legacy: these are stored as comma lists like "-1" or "0,1". | |
| 78 | + $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'fixed__week_days__start', [" . $days_selection_arr['fixed__week_days__start'] . "] ); "; | |
| 79 | + $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'dynamic__days_min', " . intval( $days_selection_arr['dynamic__days_min'] ) . " ); "; | |
| 80 | + $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'dynamic__days_max', " . intval( $days_selection_arr['dynamic__days_max'] ) . " ); "; | |
| 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. | |
| 105 | + $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'booking_date_format', " . wp_json_encode( (string) get_bk_option( 'booking_date_format' ) ) . " ); "; | |
| 106 | + $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'booking_time_format', " . wp_json_encode( (string) get_bk_option( 'booking_time_format' ) ) . " ); "; | |
| 107 | + | |
| 108 | + // Capacity | availability. | |
| 71 | 109 | if ( class_exists( 'wpdev_bk_biz_l' ) ) { |
| 72 | 110 | $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . " , 'is_parent_resource' , " . ( wpbc_get_child_resources_number( $resource_id ) ? 1 : 0 ) . " ); "; |
| 73 | - $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . " , 'booking_capacity_field' , '" . wpbc_get__booking_capacity_field__name() . "' ); "; | |
| 74 | - $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . " , 'booking_is_dissbale_booking_for_different_sub_resources' , '" . get_bk_option( 'booking_is_dissbale_booking_for_different_sub_resources' ) . "' ); "; | |
| 111 | + $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . " , 'booking_capacity_field' , " . wp_json_encode( (string) wpbc_get__booking_capacity_field__name() ) . " ); "; | |
| 112 | + $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . " , 'booking_is_dissbale_booking_for_different_sub_resources' , " . wp_json_encode( (string) get_bk_option( 'booking_is_dissbale_booking_for_different_sub_resources' ) ) . " ); "; | |
| 75 | 113 | } |
| 76 | 114 | if ( class_exists( 'wpdev_bk_biz_s' ) ) { |
| 77 | - $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . " , 'booking_recurrent_time' , '" . esc_js( get_bk_option( 'booking_recurrent_time' ) ) . "' ); "; // FixIn: 10.6.1.3. | |
| 115 | + $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . " , 'booking_recurrent_time' , " . wp_json_encode( (string) get_bk_option( 'booking_recurrent_time' ) ) . " ); "; | |
| 78 | 116 | } |
| 79 | 117 | |
| 80 | - // ----------------------------------------------------------------------------------------------------------------- | |
| 81 | - // Save initial values of days selection for later use in conditional day logic | |
| 82 | - $start_script_code .= " if ( 'function' === typeof ( wpbc__conditions__SAVE_INITIAL__days_selection_params__bm ) ){ wpbc__conditions__SAVE_INITIAL__days_selection_params__bm( " . $resource_id . " ); } "; | |
| 118 | + // Save initial values of days selection for later use in conditional day logic. | |
| 119 | + $start_script_code .= " if ( 'function' === typeof ( wpbc__conditions__SAVE_INITIAL__days_selection_params__bm ) ) { wpbc__conditions__SAVE_INITIAL__days_selection_params__bm( " . $resource_id . " ); } "; | |
| 83 | 120 | |
| 84 | 121 | if ( |
| 85 | - ( ! empty( $params['shortcode_options'] ) ) | |
| 86 | - && ( function_exists( 'wpbc_parse_shortcode_option__set_days_selection_conditions' ) ) | |
| 87 | - ){ | |
| 122 | + ( ! empty( $params['shortcode_options'] ) ) | |
| 123 | + && ( function_exists( 'wpbc_parse_shortcode_option__set_days_selection_conditions' ) ) | |
| 124 | + ) { | |
| 88 | 125 | $days_selection_conditions = wpbc_parse_shortcode_option__set_days_selection_conditions( $resource_id, $params['shortcode_options'] ); |
| 126 | + | |
| 89 | 127 | if ( ! empty( $days_selection_conditions ) ) { |
| 90 | - $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'conditions', " . wp_json_encode( $days_selection_conditions['conditions'] ). " ); "; | |
| 91 | - $start_script_code .= " _wpbc.seasons__set( " . $resource_id . ", " . wp_json_encode( $days_selection_conditions['seasons'] ) . " ); "; | |
| 128 | + $start_script_code .= " _wpbc.calendar__set_param_value( " . $resource_id . ", 'conditions', " . wp_json_encode( $days_selection_conditions['conditions'] ) . " ); "; | |
| 129 | + $start_script_code .= " _wpbc.seasons__set( " . $resource_id . ", " . wp_json_encode( $days_selection_conditions['seasons'] ) . " ); "; | |
| 92 | 130 | } |
| 93 | 131 | } |
| 94 | 132 | |
| 95 | 133 | return $start_script_code; |
| @@ -94,24 +132,32 @@ | ||
| 94 | 132 | |
| 95 | 133 | return $start_script_code; |
| 96 | 134 | } |
| 97 | 135 | |
| 136 | + | |
| 98 | 137 | /** |
| 99 | 138 | * Get days selection parameters, which saved in database |
| 100 | 139 | * |
| 101 | - * @return array | |
| 102 | - */ | |
| 103 | - function wpbc__calendar__js_params__get_days_selection_arr(){ | |
| 140 | + * @return array | |
| 141 | + */ | |
| 142 | + function wpbc__calendar__js_params__get_days_selection_arr(){ | |
| 104 | 143 | |
| 105 | 144 | $specific_days_selection = ( function_exists( 'wpbc_get_specific_range_dates__as_comma_list' ) ) |
| 106 | 145 | ? wpbc_get_specific_range_dates__as_comma_list( get_bk_option( 'booking_range_selection_days_specific_num_dynamic' ) ) |
| 107 | 146 | : ''; |
| 108 | - $data_arr = array(); | |
| 109 | - // Modes :: Selection of Days | |
| 110 | - $data_arr['days_select_mode'] = ( 'range' === get_bk_option('booking_type_of_day_selections') ) | |
| 111 | - ? get_bk_option('booking_range_selection_type') | |
| 112 | - : get_bk_option( 'booking_type_of_day_selections'); | |
| 113 | - $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 */ | |
| 114 | 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 } */ |
| 115 | 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 */ |
| 116 | 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 */ |
| 117 | 163 | $data_arr['dynamic__days_specific'] = $specific_days_selection; /* Example: '5,7' */ |
| @@ -116,12 +162,15 @@ | ||
| 116 | 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 */ |
| 117 | 163 | $data_arr['dynamic__days_specific'] = $specific_days_selection; /* Example: '5,7' */ |
| 118 | 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 } */ |
| 119 | 165 | |
| 120 | - // 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. | |
| 121 | - if ( ( ! class_exists( 'wpdev_bk_biz_s' ) ) && ( in_array( $data_arr['days_select_mode'], array( 'dynamic', 'fixed' ) ) ) ) { | |
| 122 | - $data_arr['days_select_mode'] = 'multiple'; | |
| 123 | - } | |
| 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 | + } | |
| 124 | 173 | |
| 125 | 174 | return $data_arr; |
| 126 | 175 | } |
| 127 | 176 | |
| @@ -127,101 +176,166 @@ | ||
| 127 | 176 | |
| 128 | 177 | |
| 129 | 178 | |
| 130 | 179 | /** |
| 131 | - * Get JavaScript for Calendar Loading: 1.Show Calendar 2. Send Ajax to Load bookings / availability / data for calendar | |
| 180 | + * Get JavaScript for Calendar Loading: | |
| 181 | + * 1) Show Calendar | |
| 182 | + * 2) Send Ajax to load bookings / availability / data for calendar | |
| 132 | 183 | * |
| 133 | - * @param $params | |
| 184 | + * @param array $params | |
| 134 | 185 | * |
| 135 | - * @return string | |
| 186 | + * @return string Either '' (when collected to footer) OR legacy <script>...</script> fallback. | |
| 136 | 187 | */ |
| 137 | -function wpbc__calendar__load( $params = array() ){ | |
| 188 | +function wpbc__calendar__load( $params = array() ) { | |
| 138 | 189 | |
| 139 | 190 | $defaults = array( |
| 140 | - 'resource_id' => '1', // $resource_id | |
| 141 | - 'aggregate_resource_id_arr' => array(), // It is array of booking resources from aggregate parameter() | |
| 142 | - 'selected_dates_without_calendar' => '', // $my_selected_dates_without_calendar | |
| 143 | - 'calendar_number_of_months' => 1, // $my_boook_count | |
| 144 | - 'start_month_calendar' => false, // $start_month_calendar | |
| 145 | - 'shortcode_options' => '', // options from the Booking Calendar shortcode. Usually it's conditional dates selection parameters | |
| 146 | - 'custom_form' => 'standard' | |
| 147 | - ); | |
| 148 | - $params = wp_parse_args( $params, $defaults ); | |
| 191 | + 'resource_id' => '1', | |
| 192 | + 'aggregate_resource_id_arr' => array(), | |
| 193 | + 'selected_dates_without_calendar' => '', | |
| 194 | + 'calendar_number_of_months' => 1, | |
| 195 | + 'start_month_calendar' => false, | |
| 196 | + 'shortcode_options' => '', | |
| 197 | + 'custom_form' => 'standard', | |
| 198 | + 'calendar_dates_start' => '', | |
| 199 | + 'calendar_dates_end' => '', | |
| 200 | + 'classic_booking_context_token' => '', | |
| 201 | + 'skip_general_availability' => 0, | |
| 202 | + 'calendar_request_overrides' => array(), | |
| 203 | + ); | |
| 204 | + $params = wp_parse_args( $params, $defaults ); | |
| 149 | 205 | |
| 150 | - // Resource ID | |
| 151 | - $params['resource_id'] = (int) $params['resource_id']; | |
| 206 | + // Resource ID. | |
| 207 | + $params['resource_id'] = absint( $params['resource_id'] ); | |
| 152 | 208 | |
| 153 | - $start_script_code = '<script type="text/javascript"> ' . wpbc_jq_ready_start(); // FixIn: 10.1.3.7. | |
| 209 | + // Build JS BODY (no <script>, no ready wrapper). | |
| 210 | + $js_body = ''; | |
| 154 | 211 | |
| 155 | - //$start_script_code .= " wpbc_calendar__loading__start( {$params['resource_id']} ); "; | |
| 212 | + $js_body .= wpbc__calendar__set_js_params__before_show( $params ); | |
| 156 | 213 | |
| 157 | - $start_script_code .= wpbc__calendar__set_js_params__before_show( $params ); | |
| 214 | + // Show calendar. | |
| 215 | + $js_body .= " wpbc_calendar_show(" . wp_json_encode( (string) $params['resource_id'] ) . "); "; | |
| 158 | 216 | |
| 159 | - // ----------------------------------------------------------------------------------------------------------------- | |
| 160 | - // Show calendar | |
| 161 | - $start_script_code .= " wpbc_calendar_show( '" . $params['resource_id'] . "' ); "; | |
| 217 | + // Security params. | |
| 218 | + $js_body .= " _wpbc.set_secure_param('nonce', " . wp_json_encode( wp_create_nonce( 'wpbc_calendar_load_ajx' . '_wpbcnonce' ) ) . "); "; | |
| 219 | + $js_body .= " _wpbc.set_secure_param('user_id', " . wp_json_encode( (string) wpbc_get_current_user_id() ) . "); "; | |
| 220 | + $js_body .= " _wpbc.set_secure_param('locale', " . wp_json_encode( (string) get_user_locale() ) . "); "; | |
| 162 | 221 | |
| 163 | - // ----------------------------------------------------------------------------------------------------------------- | |
| 164 | - // Set Security - Nonce for Ajax - Listing | |
| 165 | - $start_script_code .= " _wpbc.set_secure_param( 'nonce', '" . wp_create_nonce( 'wpbc_calendar_load_ajx' . '_wpbcnonce' ) . "' ); "; | |
| 166 | - $start_script_code .= " _wpbc.set_secure_param( 'user_id', '" . wpbc_get_current_user_id() . "' ); "; | |
| 167 | - $start_script_code .= " _wpbc.set_secure_param( 'locale', '" . get_user_locale() . "' ); "; | |
| 222 | + // booking_hash (keep legacy GET behavior, sanitized). | |
| 223 | + $get_booking_hash = ''; | |
| 224 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing | |
| 225 | + if ( isset( $_GET['booking_hash'] ) ) { | |
| 226 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized | |
| 227 | + $raw_hash = wp_unslash( $_GET['booking_hash'] ); | |
| 228 | + if ( ! is_array( $raw_hash ) ) { | |
| 229 | + $get_booking_hash = sanitize_text_field( (string) $raw_hash ); | |
| 230 | + } | |
| 231 | + } | |
| 168 | 232 | |
| 169 | - // ----------------------------------------------------------------------------------------------------------------- | |
| 170 | - // Get parameters for Ajax request | |
| 171 | - $get_booking_hash = ( ( isset( $_GET['booking_hash'] ) ) ? sanitize_text_field( wp_unslash( $_GET['booking_hash'] ) ) : '' ); /* phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing */ /* FixIn: sanitize_unslash */ | |
| 172 | - $booking_hash = $get_booking_hash; | |
| 173 | - | |
| 174 | - // FixIn: 9.8.15.10. | |
| 233 | + // Aggregate type. | |
| 175 | 234 | $aggregate_type = 'all'; |
| 176 | 235 | if ( |
| 177 | - ( ! empty( $params['shortcode_options'] ) ) | |
| 178 | - && ( function_exists( 'wpbc_parse_calendar_options__aggregate_param' ) ) | |
| 236 | + ( ! empty( $params['shortcode_options'] ) ) | |
| 237 | + && function_exists( 'wpbc_parse_calendar_options__aggregate_param' ) | |
| 179 | 238 | ) { |
| 180 | - $aggregate_type = wpbc_parse_calendar_options__aggregate_param( $params['shortcode_options'] ); | |
| 181 | - if ( ( ! empty( $aggregate_type ) ) && ( ! empty( $aggregate_type['type'] ) ) ) { | |
| 182 | - $aggregate_type = $aggregate_type['type']; | |
| 183 | - } else { | |
| 184 | - $aggregate_type = 'all'; | |
| 239 | + $aggregate_type_res = wpbc_parse_calendar_options__aggregate_param( $params['shortcode_options'] ); | |
| 240 | + if ( ( ! empty( $aggregate_type_res ) ) && ( ! empty( $aggregate_type_res['type'] ) ) ) { | |
| 241 | + $aggregate_type = (string) $aggregate_type_res['type']; | |
| 185 | 242 | } |
| 186 | 243 | } |
| 187 | 244 | |
| 245 | + // request_uri captured on front-end (legacy rationale). | |
| 246 | + $server_request_uri = ''; | |
| 247 | + // phpcs:ignore WordPress.Security.NonceVerification.Missing | |
| 248 | + if ( isset( $_SERVER['REQUEST_URI'] ) ) { | |
| 249 | + // phpcs:ignore WordPress.Security.NonceVerification.Missing | |
| 250 | + $server_request_uri = sanitize_text_field( wp_unslash( (string) $_SERVER['REQUEST_URI'] ) ); | |
| 251 | + } | |
| 188 | 252 | |
| 189 | - /** | |
| 190 | - * About ['request_uri']: | |
| 191 | - * At ( front-end ) side the $_SERVER['REQUEST_URI'] = '/resource-id2/' which is good | |
| 192 | - * but in Ajax Response (admin side ) we will have: | |
| 193 | - * $_SERVER['REQUEST_URI'] = '/wp-admin/admin-ajax.php' | |
| 194 | - * $_SERVER['HTTP_REFERER'] = 'http://beta/resource-id2/' | |
| 195 | - * that is why we define 'request_uri' here at front-end side. | |
| 196 | - */ | |
| 197 | - $server_request_uri = ( ( isset( $_SERVER['REQUEST_URI'] ) ) ? sanitize_text_field( $_SERVER['REQUEST_URI'] ) : '' ); /* phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.MissingUnslash */ /* FixIn: sanitize_unslash */ | |
| 198 | 253 | $params_for_request = array( |
| 199 | - 'resource_id' => $params['resource_id'], | |
| 200 | - 'booking_hash' => $booking_hash, | |
| 201 | - 'request_uri' => $server_request_uri, // Is it the same as window.location.href or | |
| 202 | - 'custom_form' => $params['custom_form'], // Optional. | |
| 203 | - 'aggregate_resource_id_str' => implode( ',', $params['aggregate_resource_id_arr'] ), // Optional. Resource ID from aggregate parameter in shortcode. | |
| 204 | - 'aggregate_type' => $aggregate_type // Optional. 'all' | 'bookings_only' <- it is depends on shortcode parameter: options="{aggregate type=bookings_only}" | |
| 205 | - ); | |
| 206 | - $params_for_request = wp_json_encode( $params_for_request ); | |
| 254 | + 'resource_id' => $params['resource_id'], | |
| 255 | + 'booking_hash' => $get_booking_hash, | |
| 256 | + 'request_uri' => $server_request_uri, | |
| 257 | + 'custom_form' => (string) $params['custom_form'], | |
| 258 | + 'aggregate_resource_id_str' => implode( ',', (array) $params['aggregate_resource_id_arr'] ), | |
| 259 | + 'aggregate_type' => (string) $aggregate_type, | |
| 260 | + 'skip_general_availability' => (int) $params['skip_general_availability'], | |
| 261 | + 'classic_booking_context_token' => (string) $params['classic_booking_context_token'], | |
| 262 | + ); | |
| 207 | 263 | |
| 208 | - // ----------------------------------------------------------------------------------------------------------------- | |
| 209 | - // Send Ajax request to load bookings | |
| 210 | - $start_script_code .= " wpbc_calendar__load_data__ajx( {$params_for_request} ); "; | |
| 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 | + } | |
| 271 | + } | |
| 272 | + } | |
| 211 | 273 | |
| 212 | - $start_script_code .= wpbc_jq_ready_end() . '</script>'; // FixIn: 10.1.3.7. | |
| 274 | + // Send Ajax request to load bookings. | |
| 275 | + $js_body .= " wpbc_calendar__load_data__ajx(" . wp_json_encode( $params_for_request ) . "); "; | |
| 213 | 276 | |
| 277 | + // --------------------------------------------------------------------- | |
| 278 | + // Elementor-safe path: add inline via WP scripts (footer-safe, not in content). // FixIn: 10.14.13.2. | |
| 279 | + // --------------------------------------------------------------------- | |
| 280 | + $can_use_wp_inline = ( ! wp_doing_ajax() ); | |
| 281 | + | |
| 282 | + if ( $can_use_wp_inline && class_exists( 'WPBC_FE_Assets' ) ) { | |
| 283 | + | |
| 284 | + $assets_key = 'wpbc:cal-load:' . intval( $params['resource_id'] ) . ':' . md5( wp_json_encode( $params_for_request ) ); | |
| 285 | + | |
| 286 | + // Try after main client script first (best), fallback to wpbc_all if needed. | |
| 287 | + $added = WPBC_FE_Assets::add_jq_ready_js_to_wp_script( 'wpbc-main-client', $js_body, $assets_key ); | |
| 288 | + if ( ! $added ) { | |
| 289 | + $added = WPBC_FE_Assets::add_jq_ready_js_to_wp_script( 'wpbc_all', $js_body, $assets_key ); | |
| 290 | + } | |
| 291 | + | |
| 292 | + if ( $added ) { | |
| 293 | + return ''; // Important: nothing inline in the content. | |
| 294 | + } | |
| 295 | + } | |
| 296 | + | |
| 297 | + // --------------------------------------------------------------------- | |
| 298 | + // Legacy fallback: return inline <script>...</script> (Works in rare contexts without wp_footer / without assets manager). | |
| 299 | + // --------------------------------------------------------------------- | |
| 300 | + $start_script_code = '<script type="text/javascript"> ' . wpbc_jq_ready_start() . $js_body . wpbc_jq_ready_end() . '</script>'; | |
| 301 | + | |
| 214 | 302 | return $start_script_code; |
| 215 | 303 | } |
| 216 | 304 | |
| 217 | 305 | |
| 218 | 306 | /** |
| 307 | + * Get Booking Calendar option names that belong to General Availability rules. | |
| 308 | + * | |
| 309 | + * @return array | |
| 310 | + */ | |
| 311 | +function wpbc__calendar__get_general_availability_option_names() { | |
| 312 | + | |
| 313 | + $option_names = array( | |
| 314 | + 'booking_unavailable_days_num_from_today', | |
| 315 | + 'booking_available_days_num_from_today', | |
| 316 | + 'booking_unavailable_extra_in_out', | |
| 317 | + 'booking_unavailable_extra_minutes_in', | |
| 318 | + 'booking_unavailable_extra_minutes_out', | |
| 319 | + 'booking_unavailable_extra_days_in', | |
| 320 | + 'booking_unavailable_extra_days_out', | |
| 321 | + ); | |
| 322 | + | |
| 323 | + foreach ( range( 0, 6 ) as $week_day_num ) { | |
| 324 | + $option_names[] = 'booking_unavailable_day' . $week_day_num; | |
| 325 | + } | |
| 326 | + | |
| 327 | + return $option_names; | |
| 328 | +} | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | +/** | |
| 219 | 333 | * Response to Ajax request, about loading calendar data |
| 220 | 334 | * |
| 221 | 335 | * @return void |
| 222 | 336 | */ |
| 223 | -function ajax_WPBC_AJX_CALENDAR_LOAD() { | |
| 337 | +function ajax_WPBC_AJX_CALENDAR_LOAD() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound | |
| 224 | 338 | |
| 225 | 339 | // Security ------------------------------------------------------------------------------------------------------ // in Ajax Post: 'nonce': _wpbc.get_secure_param( 'nonce' ), |
| 226 | 340 | $action_name = 'wpbc_calendar_load_ajx' . '_wpbcnonce'; |
| 227 | 341 | $nonce_post_key = 'nonce'; |
| @@ -247,19 +361,91 @@ | ||
| 247 | 361 | 'user_id' => $user_id, |
| 248 | 362 | 'request_rules_structure' => array( |
| 249 | 363 | 'resource_id' => array( 'validate' => 'd', 'default' => 1 ), // 'digit_or_csd' |
| 250 | 364 | 'booking_hash' => array( 'validate' => 's', 'default' => '' ), |
| 251 | - 'request_uri' => array( 'validate' => 's', 'default' => '' ), | |
| 252 | - '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' => '' ), | |
| 253 | 369 | 'aggregate_resource_id_str' => array( 'validate' => 'digit_or_csd', 'default' => '' ), // Comma separated string of resource ID, which was used in 'aggregate' parameter. |
| 254 | - 'aggregate_type' => array( 'validate' => 's', 'default' => 'all' ) // 'all' | 'bookings_only' // FixIn: 9.8.15.10. | |
| 370 | + 'aggregate_type' => array( 'validate' => 's', 'default' => 'all' ), // 'all' | 'bookings_only' // FixIn: 9.8.15.10. | |
| 371 | + 'dates_to_check' => array( 'validate' => 'array', 'default' => '' ), // 'all' | 'bookings_only' // FixIn: 9.8.15.10. | |
| 372 | + 'skip_general_availability' => array( 'validate' => 'd', 'default' => 0 ), | |
| 373 | + 'wpbc_settings_calendar_preview' => array( 'validate' => 'd', 'default' => 0 ), | |
| 374 | + 'wpbc_settings_calendar_preview_changeover' => array( 'validate' => array( 'On', 'Off' ), 'default' => 'Off' ), | |
| 375 | + 'wpbc_settings_calendar_preview_triangles' => array( 'validate' => array( 'On', 'Off' ), 'default' => 'On' ), | |
| 376 | + 'wpbc_settings_calendar_preview_recurrent_time' => array( 'validate' => array( 'On', 'Off' ), 'default' => 'Off' ), | |
| 377 | + 'wpbc_settings_calendar_preview_last_checkout' => array( 'validate' => array( 'On', 'Off' ), 'default' => 'Off' ), | |
| 378 | + 'wpbc_settings_calendar_preview_excerpt_on_pages' => array( 'validate' => array( 'On', 'Off' ), 'default' => 'Off' ), | |
| 379 | + 'wpbc_settings_calendar_preview_excerpt_pages' => array( 'validate' => 's', 'default' => '' ), | |
| 380 | + 'wpbc_settings_calendar_preview_excerpt_resources' => array( 'validate' => 's', 'default' => '' ), | |
| 381 | + 'wpbc_settings_calendar_preview_show_legend' => array( 'validate' => array( 'On', 'Off' ), 'default' => 'Off' ), | |
| 382 | + 'wpbc_settings_calendar_preview_legend_show_numbers' => array( 'validate' => array( 'On', 'Off' ), 'default' => 'Off' ), | |
| 383 | + 'wpbc_settings_calendar_preview_legend_vertical' => array( 'validate' => array( 'On', 'Off' ), 'default' => 'Off' ), | |
| 384 | + 'wpbc_settings_calendar_preview_legend_show_available' => array( 'validate' => array( 'On', 'Off' ), 'default' => 'Off' ), | |
| 385 | + 'wpbc_settings_calendar_preview_legend_text_available' => array( 'validate' => 's', 'default' => '' ), | |
| 386 | + 'wpbc_settings_calendar_preview_legend_show_pending' => array( 'validate' => array( 'On', 'Off' ), 'default' => 'Off' ), | |
| 387 | + 'wpbc_settings_calendar_preview_legend_text_pending' => array( 'validate' => 's', 'default' => '' ), | |
| 388 | + 'wpbc_settings_calendar_preview_legend_show_approved' => array( 'validate' => array( 'On', 'Off' ), 'default' => 'Off' ), | |
| 389 | + 'wpbc_settings_calendar_preview_legend_text_approved' => array( 'validate' => 's', 'default' => '' ), | |
| 390 | + 'wpbc_settings_calendar_preview_legend_show_partially' => array( 'validate' => array( 'On', 'Off' ), 'default' => 'Off' ), | |
| 391 | + 'wpbc_settings_calendar_preview_legend_text_partially' => array( 'validate' => 's', 'default' => '' ), | |
| 392 | + 'wpbc_settings_calendar_preview_legend_show_unavailable' => array( 'validate' => array( 'On', 'Off' ), 'default' => 'Off' ), | |
| 393 | + 'wpbc_settings_calendar_preview_legend_text_unavailable' => array( 'validate' => 's', 'default' => '' ), | |
| 394 | + 'wpbc_settings_calendar_preview_disable_timeslots_tooltip' => array( 'validate' => array( 'On', 'Off' ), 'default' => 'Off' ), | |
| 395 | + 'wpbc_settings_calendar_preview_timeslot_word' => array( 'validate' => 's', 'default' => '' ), | |
| 396 | + 'wpbc_settings_calendar_preview_show_availability_tooltip' => array( 'validate' => array( 'On', 'Off' ), 'default' => 'Off' ), | |
| 397 | + 'wpbc_settings_calendar_preview_availability_word' => array( 'validate' => 's', 'default' => '' ), | |
| 398 | + 'wpbc_settings_calendar_preview_show_availability_cell' => array( 'validate' => array( 'On', 'Off' ), 'default' => 'Off' ), | |
| 399 | + 'wpbc_settings_calendar_preview_availability_cell_word' => array( 'validate' => 's', 'default' => '' ), | |
| 400 | + 'wpbc_settings_calendar_preview_show_cost_tooltip' => array( 'validate' => array( 'On', 'Off' ), 'default' => 'Off' ), | |
| 401 | + 'wpbc_settings_calendar_preview_cost_word' => array( 'validate' => 's', 'default' => '' ), | |
| 402 | + 'wpbc_settings_calendar_preview_show_cost_cell' => array( 'validate' => array( 'On', 'Off' ), 'default' => 'Off' ), | |
| 403 | + 'wpbc_settings_calendar_preview_cost_currency' => array( 'validate' => 's', 'default' => '' ), | |
| 404 | + 'wpbc_settings_calendar_preview_show_booked_details' => array( 'validate' => array( 'On', 'Off' ), 'default' => 'Off' ), | |
| 405 | + 'wpbc_settings_calendar_preview_booked_details' => array( 'validate' => 's', 'default' => '' ), | |
| 255 | 406 | ) |
| 256 | 407 | ) |
| 257 | 408 | ); |
| 258 | - $request_prefix = 'calendar_request_params'; | |
| 259 | - $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; | |
| 260 | 433 | |
| 434 | + if ( ! empty( $request_params['skip_general_availability'] ) ) { | |
| 435 | + $can_skip_general_availability = ( | |
| 436 | + function_exists( 'wpbc_availability_general__get_manage_cap' ) | |
| 437 | + && function_exists( 'wpbc_is_mu_user_can_be_here' ) | |
| 438 | + && wpbc_is_mu_user_can_be_here( 'only_super_admin' ) | |
| 439 | + && current_user_can( wpbc_availability_general__get_manage_cap() ) | |
| 440 | + ); | |
| 261 | 441 | |
| 442 | + if ( ! $can_skip_general_availability ) { | |
| 443 | + $request_params['skip_general_availability'] = 0; | |
| 444 | + } | |
| 445 | + } | |
| 446 | + | |
| 447 | + | |
| 262 | 448 | // Do Job here !! ------------------------------------------------------------------------------------------------- |
| 263 | 449 | |
| 264 | 450 | make_bk_action( 'check_pending_unpaid_bookings__do_auto_cancel', $request_params['resource_id'] ); |
| 265 | 451 | |
| @@ -273,22 +459,28 @@ | ||
| 273 | 459 | unset( $aggregate_resource_id_arr[ $resource_id_key ] ); // Remove source booking resource from aggregate ARR. // FixIn: 9.8.15.10. |
| 274 | 460 | } |
| 275 | 461 | $aggregate_resource_id_arr = array_values($aggregate_resource_id_arr); // Reset keys |
| 276 | 462 | |
| 277 | - $availability_per_days__params = array( | |
| 278 | - 'resource_id' => $request_params['resource_id'], | |
| 279 | - 'max_days_count' => $max_days_count, | |
| 280 | - 'skip_booking_id' => $skip_booking_id, | |
| 281 | - '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 | |
| 282 | - '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'] ) | |
| 283 | 470 | , 'additional_bk_types' => $aggregate_resource_id_arr // It is array of booking resources from aggregate parameter() // arrays | CSD | int // OPTIONAL |
| 284 | 471 | , 'aggregate_type' => $request_params['aggregate_type'] // It is string: 'all' | 'bookings_only' // OPTIONAL |
| 472 | + , 'skip_general_availability' => $request_params['skip_general_availability'] | |
| 285 | 473 | // , 'as_single_resource' => true // get dates as for 'single resource' or 'parent' resource including bookings in all 'child booking resources' |
| 286 | 474 | // , 'max_days_count' => wpbc_get_max_visible_days_in_calendar() // 365 |
| 287 | 475 | // , 'timeslots_to_check_intersect' => $timeslots_to_check_intersect //TODO 2023-10-25: delete it, because we get it in wpbc_get_availability_per_days_arr() //array( '12:20 - 12:55', '13:00 - 14:00' ) |
| 288 | 476 | ); |
| 289 | 477 | |
| 290 | - // If in Booking > Add booking page we use in URL .../wp-admin/admin.php?page=wpbc-new&booking_type=2&as_single_resource=1 then get availability only for single resource. | |
| 478 | + if ( ! empty( $request_params['dates_to_check'] ) ) { | |
| 479 | + $availability_per_days__params['dates_to_check'] = $request_params['dates_to_check']; // Usually if defined it is: [ '2025-01-01', '2025-12-31' ], because of shortcode [booking resource_id=4 calendar_dates_start='2025-01-01' calendar_dates_end='2025-12-31' ...] | |
| 480 | + } | |
| 481 | + | |
| 482 | + // If in Booking > Add booking page we use in URL .../wp-admin/admin.php?page=wpbc&tab=add-booking&booking_type=2&as_single_resource=1 then get availability only for single resource. | |
| 291 | 483 | if ( |
| 292 | 484 | ( ! empty( $request_params['request_uri'] ) ) |
| 293 | 485 | && ( strpos( $request_params['request_uri'], 'as_single_resource=1' ) !== false ) |
| 294 | 486 | ){ |
| @@ -296,9 +488,9 @@ | ||
| 296 | 488 | } |
| 297 | 489 | |
| 298 | 490 | /** |
| 299 | 491 | * Tricks: |
| 300 | - * if ( strpos( $request_params['request_uri'],'page=wpbc-new' ) !== false ) { $availability_per_days__params['is_days_always_available'] = true; } | |
| 492 | + * if ( wpbc_is_new_booking_page_url( $request_params['request_uri'] ) ) { $availability_per_days__params['is_days_always_available'] = true; } | |
| 301 | 493 | * |
| 302 | 494 | * // Set dates in calendar always available only for specific resources with specific ID |
| 303 | 495 | * if ( in_array( $request_params['resource_id'], array( 12, 15, 17 ) ) ) { $availability_per_days__params['is_days_always_available'] = true; } |
| 304 | 496 | */ |
| @@ -303,28 +495,62 @@ | ||
| 303 | 495 | * if ( in_array( $request_params['resource_id'], array( 12, 15, 17 ) ) ) { $availability_per_days__params['is_days_always_available'] = true; } |
| 304 | 496 | */ |
| 305 | 497 | |
| 306 | 498 | // Get unavailable dates for calendar |
| 499 | + // $availability_per_days__params['dates_to_check'] = array( '2025-01-01', '2025-12-31' ); // FixIn: 10.13.1.4. | |
| 500 | + global $wpbc__skip_get_bk_options; | |
| 501 | + | |
| 502 | + $previous_skip_get_bk_options = $wpbc__skip_get_bk_options; | |
| 503 | + $previous_settings_calendar_preview_options = null; | |
| 504 | + $is_settings_calendar_preview = ( | |
| 505 | + function_exists( 'wpbc_settings_calendar__is_calendar_load_preview_request_allowed' ) | |
| 506 | + && wpbc_settings_calendar__is_calendar_load_preview_request_allowed( $request_params ) | |
| 507 | + ); | |
| 508 | + if ( ! empty( $availability_per_days__params['skip_general_availability'] ) ) { | |
| 509 | + $wpbc__skip_get_bk_options = array_unique( | |
| 510 | + array_merge( | |
| 511 | + (array) $wpbc__skip_get_bk_options, | |
| 512 | + wpbc__calendar__get_general_availability_option_names() | |
| 513 | + ) | |
| 514 | + ); | |
| 515 | + } | |
| 516 | + if ( $is_settings_calendar_preview ) { | |
| 517 | + $previous_settings_calendar_preview_options = wpbc_settings_calendar__preview_options_push( | |
| 518 | + wpbc_settings_calendar__get_calendar_load_preview_options( $request_params ) | |
| 519 | + ); | |
| 520 | + } | |
| 521 | + | |
| 307 | 522 | $availability_per_days_arr = wpbc_get_availability_per_days_arr( $availability_per_days__params ); |
| 523 | + $wpbc__skip_get_bk_options = $previous_skip_get_bk_options; | |
| 524 | + if ( $is_settings_calendar_preview ) { | |
| 525 | + wpbc_settings_calendar__preview_options_pop( $previous_settings_calendar_preview_options ); | |
| 526 | + } | |
| 308 | 527 | |
| 309 | 528 | |
| 529 | + $ajx_data_arr = array( /** | |
| 530 | + * Send JSON. It will make "wp_json_encode" - so pass only array, and This function call wp_die( '', '', array( 'response' => null, ) ) . | |
| 531 | + * Pass JS OBJ: response_data in "jQuery.post( " function on success. | |
| 532 | + */ | |
| 533 | + 'ajx_data' => $availability_per_days_arr, | |
| 534 | + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized | |
| 535 | + 'ajx_search_params' => $_REQUEST[ $request_prefix ], | |
| 536 | + 'ajx_cleaned_params' => $request_params, | |
| 537 | + 'resource_id' => $request_params['resource_id'], | |
| 538 | + ); | |
| 539 | + | |
| 540 | + // FixIn: 10.12.4.6. | |
| 541 | + if ( ! in_array( $request_params['resource_id'], $availability_per_days_arr['resources_id_arr__in_dates'] ) ) { | |
| 542 | + $ajx_data_arr['ajx_data']['ajx_after_action_message'] = 'Wrong ID of booking resource. Probably calendar (booking resource) with ID = ' . intval( $request_params['resource_id'] ) . ' not exists. Please check resource_id parameter in the Booking Calendar shortcode.'; | |
| 543 | + } | |
| 544 | + | |
| 545 | + | |
| 546 | + | |
| 310 | 547 | // Show message under calendar, if needed. |
| 311 | 548 | //$availability_per_days_arr['ajx_after_action_message'] = 'Ta Da :))'; |
| 312 | 549 | //$availability_per_days_arr['ajx_after_action_message_status'] = 'warning'; |
| 313 | 550 | |
| 314 | 551 | // Ajax ------------------------------------------------------------------------------------------------------------ |
| 315 | - wp_send_json( array( | |
| 316 | - /** | |
| 317 | - * Send JSON. It will make "wp_json_encode" - so pass only array, and This function call wp_die( '', '', array( 'response' => null, ) ) . | |
| 318 | - * Pass JS OBJ: response_data in "jQuery.post( " function on success. | |
| 319 | - */ | |
| 320 | - 'ajx_data' => $availability_per_days_arr, | |
| 321 | - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized | |
| 322 | - 'ajx_search_params' => $_REQUEST[ $request_prefix ], | |
| 323 | - 'ajx_cleaned_params' => $request_params, | |
| 324 | - | |
| 325 | - 'resource_id' => $request_params['resource_id'] | |
| 326 | - ) ); | |
| 552 | + wp_send_json( $ajx_data_arr ); | |
| 327 | 553 | |
| 328 | 554 | } |
| 329 | 555 | |
| 330 | 556 | if ( is_admin() && ( defined( 'DOING_AJAX' ) ) && ( DOING_AJAX ) ) { |