PluginProbe
Booking Calendar / 11.6
Booking Calendar v11.6
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
booking / includes / _front_end / class-fe-render.php

class-fe-render.php in Booking Calendar 11.6, at includes/_front_end/class-fe-render.php

397 lines 17.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Front-End Render (Booking form, Calendar)
4 *
5 * File: /wp-content/plugins/booking/includes/_front_end/class-fe-render.php
6 */
7
8 if ( ! defined( 'ABSPATH' ) ) {
9 exit;
10 }
11
12 class WPBC_FE_Render {
13
14 /**
15 * Echo or return helper (to preserve legacy API behavior).
16 *
17 * @param string $html - already escaped/sanitizing HTML content.
18 * @param bool $is_echo - do we need to echo it?.
19 *
20 * @return string|void
21 */
22 private static function echo_or_return( $html, $is_echo ) {
23
24 if ( $is_echo ) {
25
26 echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
27
28 return;
29 }
30
31 return $html;
32 }
33
34 // -----------------------------------------------------------------------------------------------------------------
35
36 /**
37 * Render Booking Form (Calendar + Form).
38 *
39 * @param array $params_arr
40 *
41 * @return string|void
42 */
43 public static function render_booking_form( $params_arr = array() ) {
44
45 // Default parameters (keep identical to legacy).
46 $default_params = array(
47 'resource_id' => 1,
48 'cal_count' => 1,
49 'is_echo' => 1,
50 'custom_booking_form' => 'standard',
51 'selected_dates_without_calendar' => '',
52 'start_month_calendar' => false,
53 'shortcode_param__options' => '',
54 'calendar_dates_start' => '',
55 'calendar_dates_end' => '',
56 'booking_hash' => '',
57 'form_status' => 'published',
58 'calendar_request_overrides' => array(),
59 );
60 $params_arr = wp_parse_args( $params_arr, $default_params );
61 $is_echo = ( ! empty( $params_arr['is_echo'] ) );
62
63 // ---------------------------------------------------------------------
64 // Hash resolution, e.g. $_GET['booking_hash'] for Booking Form rendering.
65 // ---------------------------------------------------------------------
66 $hash_res = WPBC_FE_Attr_Postprocessor::resolve_booking_hash_and_maybe_get_parent_resource_id( $params_arr, 'form' );
67 if ( ! $hash_res['ok'] ) {
68 return self::echo_or_return( $hash_res['error_html'], $is_echo );
69 }
70 $params_arr = $hash_res['params_arr'];
71
72 // ---------------------------------------------------------------------
73 // Normalize aggregate resource IDs. - "5;3;9" -> [ 'resource_id' => 5, 'aggregate_resource_id_arr' => [5,3,9] ].
74 // ---------------------------------------------------------------------
75 $aggregate_resource_id_arr = array();
76 $split = WPBC_FE_Attr_Postprocessor::split_aggregate_resource_id( $params_arr['resource_id'] );
77 $params_arr['resource_id'] = $split['resource_id'];
78 $aggregate_resource_id_arr = $split['aggregate_resource_id_arr'];
79
80 // ---------------------------------------------------------------------
81 // Validate resource_id parameter and check if booking resource exists.
82 // ---------------------------------------------------------------------
83 $resource_validation = WPBC_FE_Attr_Postprocessor::validate_resource_id( $params_arr['resource_id'] );
84 if ( true !== $resource_validation ) {
85 return self::echo_or_return( $resource_validation, $is_echo );
86 }
87
88 // ---------------------------------------------------------------------
89 // == MU ==
90 // ---------------------------------------------------------------------
91 make_bk_action( 'check_multiuser_params_for_client_side', $params_arr['resource_id'] );
92
93 // Render a focused cancellation confirmation instead of loading the complete booking form and calendar.
94 if ( WPBC_GET_Request::has_get( 'booking_cancel' ) && function_exists( 'wpbc_customer_access_render_cancellation_confirmation' ) ) {
95 $booking_hash = sanitize_text_field( wp_unslash( (string) $params_arr['booking_hash'] ) );
96 if ( '' === $booking_hash ) {
97 $booking_hash = WPBC_GET_Request::get_sanitized( 'booking_hash' );
98 }
99
100 $cancellation_html = wpbc_customer_access_render_cancellation_confirmation( $booking_hash, $params_arr['resource_id'] );
101
102 /**
103 * Filters the complete visitor cancellation confirmation markup.
104 *
105 * @param string $cancellation_html Rendered confirmation markup.
106 * @param int $resource_id Resource ID used by the front-end form container.
107 * @param string $booking_hash Sanitized booking credential from the cancellation URL.
108 */
109 $cancellation_html = apply_filters(
110 'wpbc_customer_booking_cancellation_confirmation_html',
111 $cancellation_html,
112 absint( $params_arr['resource_id'] ),
113 $booking_hash
114 );
115
116 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
117 $my_result = apply_filters( 'wpdev_booking_form', ' ' . $cancellation_html . ' ', $params_arr['resource_id'] );
118
119 make_bk_action( 'finish_check_multiuser_params_for_client_side', $params_arr['resource_id'] );
120
121 return self::echo_or_return( $my_result, $is_echo );
122 }
123
124 // ---------------------------------------------------------------------
125 // Normalize calendar_dates_start/end.
126 // ---------------------------------------------------------------------
127 $calendar_dates_range = WPBC_FE_Attr_Postprocessor::normalize_calendar_dates_range( $params_arr['calendar_dates_start'], $params_arr['calendar_dates_end'] );
128 $classic_booking_context_token = '';
129 if (
130 function_exists( 'wpbc_classic_booking_context_encode' )
131 && '' !== $calendar_dates_range['start']
132 && '' !== $calendar_dates_range['end']
133 ) {
134 $classic_booking_context_token = wpbc_classic_booking_context_encode(
135 array(
136 'resource_id' => $params_arr['resource_id'],
137 'calendar_dates_start' => $calendar_dates_range['start'],
138 'calendar_dates_end' => $calendar_dates_range['end'],
139 'custom_form' => $params_arr['custom_booking_form'],
140 'aggregate_resource_ids' => $aggregate_resource_id_arr,
141 )
142 );
143 }
144
145 // ---------------------------------------------------------------------
146 // Calendar load params (keep identical keys).
147 // ---------------------------------------------------------------------
148 $calendar_load_params = array(
149 'resource_id' => $params_arr['resource_id'],
150 'aggregate_resource_id_arr' => $aggregate_resource_id_arr,
151 'selected_dates_without_calendar' => $params_arr['selected_dates_without_calendar'],
152 'calendar_number_of_months' => $params_arr['cal_count'],
153 'start_month_calendar' => $params_arr['start_month_calendar'],
154 'shortcode_options' => $params_arr['shortcode_param__options'],
155 'custom_form' => $params_arr['custom_booking_form'],
156 'calendar_dates_start' => $calendar_dates_range['start'],
157 'calendar_dates_end' => $calendar_dates_range['end'],
158 'classic_booking_context_token' => $classic_booking_context_token,
159 'calendar_request_overrides' => $params_arr['calendar_request_overrides'],
160 );
161
162 $start_script_code = wpbc__calendar__load( $calendar_load_params );
163
164 // Disable booked time slots when selected date is predefined (legacy behavior).
165 if ( '' !== $params_arr['selected_dates_without_calendar'] ) {
166 $assets_key = 'wpbc:disable_time_fields_in_booking_form:' . intval( $params_arr['resource_id'] );
167
168 // Fire on all booking dates loaded. // FixIn: 10.14.17.2.
169 $local_js_code = " jQuery( 'body' ).on( 'wpbc_calendar_ajx__loaded_data', function ( event, loaded_resource_id ){ ";
170 $local_js_code .= ' if ( loaded_resource_id == ' . intval( $params_arr['resource_id'] ) . ' ){ ';
171 $local_js_code .= ' wpbc_disable_time_fields_in_booking_form(' . intval( $params_arr['resource_id'] ) . ')';
172 $local_js_code .= ' }';
173 $local_js_code .= '} );';
174
175 $added = WPBC_FE_Assets::add_jq_ready_js_to_wp_script( 'wpbc_all', $local_js_code, $assets_key );
176 if ( ! $added ) {
177 $start_script_code .= WPBC_FE_Assets::add_inline_js( $local_js_code, $assets_key ); // Fallback to direct inline JS, if previosly not edded script.
178 }
179 }
180
181 // ---------------------------------------------------------------------
182 // For Phase #1 we still use legacy HTML builder for the form body. (Later phases will move it fully.)
183 // ---------------------------------------------------------------------
184 $legacy = wpbc_get_legacy_booking_instance();
185 if ( ! $legacy ) {
186 $err = '<div class="wpbc_after_booking_thank_you_section"><div class="wpbc_ty__container"><div class="wpbc_ty__header"><strong>' . esc_html__( 'Oops!', 'booking' ) . '</strong> ' . esc_html__( 'Booking Calendar front-end renderer is not available. Please contact support.', 'booking' ) . '</div></div></div>';
187 return self::echo_or_return( $err, $is_echo );
188 }
189
190 $form_html = WPBC_FE_Form_Body_Renderer::render(
191 array(
192 'resource_id' => $params_arr['resource_id'],
193 'custom_booking_form' => $params_arr['custom_booking_form'],
194 'form_status' => $params_arr['form_status'],
195 'selected_dates_without_calendar' => $params_arr['selected_dates_without_calendar'],
196 'cal_count' => $params_arr['cal_count'],
197 'shortcode_param__options' => $params_arr['shortcode_param__options'],
198 'booking_hash' => $params_arr['booking_hash'],
199 'legacy_instance' => $legacy,
200 )
201 );
202
203 $my_result = ' ' . $form_html . ' ' . $start_script_code;
204
205
206 // Add DIV structure, where to show payment form.
207 $my_result = apply_filters( 'wpdev_booking_form', $my_result, $params_arr['resource_id'] ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
208
209 // == MU ==
210 make_bk_action( 'finish_check_multiuser_params_for_client_side', $params_arr['resource_id'] );
211
212 return self::echo_or_return( $my_result, $is_echo );
213 }
214
215
216 /**
217 * Render Availability Calendar Only.
218 *
219 * @param array $params_arr
220 *
221 * @return string|void
222 */
223 public static function render_calendar_only( $params_arr = array() ) {
224
225 $default_params = array(
226 'resource_id' => 1,
227 'cal_count' => 1,
228 'is_echo' => 1,
229 'start_month_calendar' => false,
230 'shortcode_param__options' => '',
231 'calendar_dates_start' => '',
232 'calendar_dates_end' => '',
233 'booking_hash' => '',
234 'calendar_request_overrides' => array(),
235 );
236 $params_arr = wp_parse_args( $params_arr, $default_params );
237 $is_echo = ( ! empty( $params_arr['is_echo'] ) );
238
239 // ---------------------------------------------------------------------
240 // Hash resolution, e.g. $_GET['booking_hash'] for Booking Form rendering.
241 // ---------------------------------------------------------------------
242 $hash_res = WPBC_FE_Attr_Postprocessor::resolve_booking_hash_and_maybe_get_parent_resource_id( $params_arr, 'calendar' );
243 if ( ! $hash_res['ok'] ) {
244 return self::echo_or_return( $hash_res['error_html'], $is_echo );
245 }
246 $params_arr = $hash_res['params_arr'];
247
248 // ---------------------------------------------------------------------
249 // Normalize aggregate resource IDs. - "5;3;9" -> [ 'resource_id' => 5, 'aggregate_resource_id_arr' => [5,3,9] ].
250 // ---------------------------------------------------------------------
251 $aggregate_resource_id_arr = array();
252 $split = WPBC_FE_Attr_Postprocessor::split_aggregate_resource_id( $params_arr['resource_id'] );
253 $params_arr['resource_id'] = $split['resource_id'];
254 $aggregate_resource_id_arr = $split['aggregate_resource_id_arr'];
255
256
257 // ---------------------------------------------------------------------
258 // Validate resource_id parameter and check if booking resource exists.
259 // ---------------------------------------------------------------------
260 $resource_validation = WPBC_FE_Attr_Postprocessor::validate_resource_id( $params_arr['resource_id'] );
261 if ( true !== $resource_validation ) {
262 return self::echo_or_return( $resource_validation, $is_echo );
263 }
264
265 // ---------------------------------------------------------------------
266 // == MU ==
267 // ---------------------------------------------------------------------
268 make_bk_action( 'check_multiuser_params_for_client_side', $params_arr['resource_id'] );
269
270 // ---------------------------------------------------------------------
271 // Normalize calendar_dates_start/end.
272 // ---------------------------------------------------------------------
273 $calendar_dates_range = WPBC_FE_Attr_Postprocessor::normalize_calendar_dates_range( $params_arr['calendar_dates_start'], $params_arr['calendar_dates_end'] );
274
275 $calendar_load_params = array(
276 'resource_id' => $params_arr['resource_id'],
277 'aggregate_resource_id_arr' => $aggregate_resource_id_arr,
278 'selected_dates_without_calendar' => '',
279 'calendar_number_of_months' => $params_arr['cal_count'],
280 'start_month_calendar' => $params_arr['start_month_calendar'],
281 'shortcode_options' => $params_arr['shortcode_param__options'],
282 'custom_form' => 'standard', // Because we show only 'AVAILABILITY CALENDAR' without the form, at all.
283 'calendar_dates_start' => $calendar_dates_range['start'],
284 'calendar_dates_end' => $calendar_dates_range['end'],
285 'calendar_request_overrides' => $params_arr['calendar_request_overrides'],
286 );
287 $start_script_code = wpbc__calendar__load( $calendar_load_params );
288
289
290 $my_result = '<div style="clear:both;height:10px;"></div>';
291 $my_result .= wpbc_pre_get_calendar_html( $params_arr['resource_id'], $params_arr['cal_count'], $params_arr['shortcode_param__options'] );
292 $my_result .= ' ' . $start_script_code;
293
294 // Keep legacy filter.
295 $my_result = apply_filters( 'wpdev_booking_calendar', $my_result, $params_arr['resource_id'] ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
296
297 $booking_form_is_using_bs_css = get_bk_option( 'booking_form_is_using_bs_css' );
298 $my_result = '<span ' . ( ( 'On' === $booking_form_is_using_bs_css ) ? 'class="wpdevelop"' : '' ) . '>' . $my_result . '</span>';
299
300 // == MU ==
301 make_bk_action( 'finish_check_multiuser_params_for_client_side', $params_arr['resource_id'] );
302
303 return self::echo_or_return( $my_result, $is_echo );
304 }
305
306 }
307
308
309 /**
310 * Try to get legacy wpdev_booking instance (for Phase #1 fallback calls).
311 *
312 * @return wpdev_booking|null
313 */
314 function wpbc_get_legacy_booking_instance() {
315
316 if ( ! function_exists( 'WPBC' ) ) {
317 return null;
318 }
319
320 $wpbc_instance = WPBC();
321 if ( ! $wpbc_instance ) {
322 return null;
323 }
324
325 if ( empty( $wpbc_instance->booking_obj ) && class_exists( 'wpdev_booking' ) ) {
326 // Lazy boot as a last resort (avoid doing this if you don’t want any boot during true WPBC ajax).
327 $wpbc_instance->booking_obj = new wpdev_booking();
328 }
329
330 return ( $wpbc_instance->booking_obj instanceof wpdev_booking ) ? $wpbc_instance->booking_obj : null;
331 }
332
333
334
335 //TODO: replace evrywhere wpbc_get_rendered_booking_form_html() to some simpler call.
336
337 /**
338 * Get HTML of Rendered Booking From - Legacy type of calling render.
339 *
340 * @param $resource_id
341 * @param $cal_count
342 * @param $is_echo
343 * @param $my_booking_form
344 * @param $my_selected_dates_without_calendar
345 * @param $start_month_calendar
346 * @param $shortcode_param__options
347 *
348 * @return string|null
349 */
350 function wpbc_get_rendered_booking_form_html( $resource_id = 1, $cal_count = 1, $is_echo = 1, $my_booking_form = 'standard', $my_selected_dates_without_calendar = '', $start_month_calendar = false, $shortcode_param__options = array() ) {
351
352 return WPBC_FE_Render::render_booking_form(
353 array(
354 'resource_id' => $resource_id,
355 'cal_count' => $cal_count,
356 'is_echo' => $is_echo,
357 'custom_booking_form' => $my_booking_form,
358 'selected_dates_without_calendar' => $my_selected_dates_without_calendar,
359 'start_month_calendar' => $start_month_calendar,
360 'shortcode_param__options' => $shortcode_param__options,
361 )
362 );
363 }
364
365 /**
366 * Get booking form rendered HTML content without echo.
367 *
368 * @param $resource_id
369 * @param $cal_count
370 * @param $my_booking_form
371 * @param $my_selected_dates_without_calendar
372 * @param $start_month_calendar
373 * @param $shortcode_param__options
374 *
375 * @return string|null
376 */
377 function wpbc_get_rendered_booking_form_html__noecho( $resource_id = 1, $cal_count = 1, $my_booking_form = 'standard', $my_selected_dates_without_calendar = '', $start_month_calendar = false, $shortcode_param__options = array() ) {
378
379 $my_result = WPBC_FE_Render::render_booking_form(
380 array(
381 'resource_id' => $resource_id,
382 'cal_count' => $cal_count,
383 'is_echo' => 0,
384 'custom_booking_form' => $my_booking_form,
385 'selected_dates_without_calendar' => $my_selected_dates_without_calendar,
386 'start_month_calendar' => $start_month_calendar,
387 'shortcode_param__options' => $shortcode_param__options,
388 )
389 );
390 return $my_result;
391 }
392
393 /**
394 * This hook exists in personal.php file for the [bookingselect ..]
395 */
396 add_bk_filter( 'wpdevbk_get_booking_form', 'wpbc_get_rendered_booking_form_html__noecho' );
397