PluginProbe
Booking Calendar / 11.2
Booking Calendar v11.2
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 / page-add-booking / add_booking__component.php

add_booking__component.php in Booking Calendar 11.2, at includes/page-add-booking/add_booking__component.php

451 lines 17.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php /**
2 * @version 1.0
3 * @package Booking Calendar
4 * @category Reusable Add Booking component
5 */
6
7 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly.
8
9 /**
10 * Reusable renderer for the Booking > Add Booking experience.
11 *
12 * The admin page calls this without args, so legacy $_GET driven behavior stays intact.
13 * Future embedded contexts can pass explicit args, which are always preferred over $_GET.
14 */
15 class WPBC_Add_Booking_Component {
16
17 /**
18 * Check if current user can access the Add Booking workflow.
19 *
20 * @return bool
21 */
22 public static function current_user_can_add_booking() {
23
24 $user_role = get_bk_option( 'booking_user_role_addbooking' );
25 $cap = 'read';
26
27 if ( class_exists( 'WPBC_Admin_Menus' ) && isset( WPBC_Admin_Menus::$capability[ $user_role ] ) ) {
28 $cap = WPBC_Admin_Menus::$capability[ $user_role ];
29 } elseif ( class_exists( 'WPBC_Admin_Menus' ) && isset( WPBC_Admin_Menus::$capability['subscriber'] ) ) {
30 $cap = WPBC_Admin_Menus::$capability['subscriber'];
31 }
32
33 return current_user_can( $cap );
34 }
35
36 /**
37 * Render the component and echo by default.
38 *
39 * @param array $args Component options.
40 *
41 * @return string|void
42 */
43 public static function render( $args = array() ) {
44
45 $args = self::normalize_args( $args );
46 $is_echo = ( ! empty( $args['is_echo'] ) );
47
48 ob_start();
49
50 ?><span class="wpdevelop"><?php // BS UI CSS Class.
51
52 if ( ! empty( $args['is_booking_page_js'] ) ) {
53 wpbc_js_for_bookings_page(); // JavaScript functions.
54 }
55
56 if ( ! empty( $args['is_toolbar_visible'] ) ) {
57 wpbc_add_new_booking_toolbar(
58 array(
59 'resource_id' => $args['_is_explicit_resource_id'] ? $args['resource_id'] : null,
60 'booking_form' => $args['_is_explicit_booking_form'] ? $args['custom_booking_form'] : null,
61 )
62 );
63 }
64
65 ?></span><!-- wpdevelop class --><?php
66
67 if ( ! empty( $args['is_show_before_content_spacer'] ) ) {
68 ?><div class="clear" style="height:40px;"></div><?php
69 }
70
71 ?><div class="<?php echo esc_attr( $args['content_css_class'] ); ?>" style="<?php echo esc_attr( $args['content_style'] ); ?>"><?php
72
73 self::print_context_js( $args );
74
75 WPBC_FE_Render::render_booking_form(
76 array(
77 'resource_id' => $args['resource_id'],
78 'cal_count' => $args['cal_count'],
79 'is_echo' => 1,
80 'custom_booking_form' => $args['custom_booking_form'],
81 'selected_dates_without_calendar' => $args['selected_dates_without_calendar'],
82 'start_month_calendar' => $args['start_month_calendar'],
83 'shortcode_param__options' => $args['shortcode_param__options'],
84 'calendar_dates_start' => $args['calendar_dates_start'],
85 'calendar_dates_end' => $args['calendar_dates_end'],
86 'booking_hash' => $args['booking_hash'],
87 )
88 );
89
90 ?></div><?php
91
92 if ( ! empty( $args['is_show_footer_email_toggle'] ) ) {
93 ?><hr /><?php
94 wpbc_toolbar_is_send_emails_btn_duplicated();
95 }
96
97 if ( ! empty( $args['is_booking_page_popover'] ) ) {
98 wpbc_bs_javascript_popover(); // JS Popover.
99 }
100
101 $html = ob_get_clean();
102
103 if ( $is_echo ) {
104 echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
105 return;
106 }
107
108 return $html;
109 }
110
111
112 /**
113 * Normalize component args.
114 *
115 * Explicit args are preferred first. Empty/non-provided args fall back to legacy $_GET behavior.
116 *
117 * @param array $args Component options.
118 *
119 * @return array
120 */
121 private static function normalize_args( $args ) {
122
123 $defaults = array(
124 'resource_id' => null,
125 'booking_type' => null,
126 'booking_form' => null,
127 'custom_booking_form' => null,
128 'calendar_options' => null,
129 'cal_count' => null,
130 'calendar_months_count' => null,
131 'shortcode_param__options' => null,
132 'selected_dates_without_calendar' => null,
133 'start_month_calendar' => false,
134 'calendar_dates_start' => '',
135 'calendar_dates_end' => '',
136 'booking_hash' => '',
137 'allow_past' => null,
138 'selected_dates' => '',
139 'selected_date' => '',
140 'selected_time' => '',
141 'time_override_enabled' => 0,
142 'time_override_source' => '',
143 'time_override_start' => '',
144 'time_override_end' => '',
145 'is_toolbar_visible' => true,
146 'is_booking_page_js' => true,
147 'is_booking_page_popover' => true,
148 'is_show_before_content_spacer' => true,
149 'is_show_footer_email_toggle' => true,
150 'content_css_class' => 'add_booking_page_content',
151 'content_style' => 'width:100%;margin-bottom:100px;',
152 'is_echo' => 1,
153 );
154 $args = wp_parse_args( $args, $defaults );
155
156 $args['_is_explicit_resource_id'] = ( ( null !== $args['resource_id'] ) && ( absint( $args['resource_id'] ) > 0 ) )
157 || ( ( null !== $args['booking_type'] ) && ( absint( $args['booking_type'] ) > 0 ) );
158 $args['_is_explicit_booking_form'] = ( ( null !== $args['custom_booking_form'] ) && ( '' !== (string) $args['custom_booking_form'] ) )
159 || ( ( null !== $args['booking_form'] ) && ( '' !== (string) $args['booking_form'] ) );
160
161 $resource_id = self::get_explicit_or_get_resource_id( $args );
162 $form_name = self::get_explicit_or_get_booking_form( $args, $resource_id );
163
164 $calendar_params = self::get_calendar_params( $args );
165
166 $args['resource_id'] = $resource_id;
167 $args['custom_booking_form'] = $form_name;
168 $args['cal_count'] = $calendar_params['months_number'];
169 $args['shortcode_param__options'] = $calendar_params['shortcode_param__options'];
170
171 $args['selected_dates_without_calendar'] = ( null !== $args['selected_dates_without_calendar'] ) ? (string) $args['selected_dates_without_calendar'] : '';
172 $args['calendar_dates_start'] = (string) $args['calendar_dates_start'];
173 $args['calendar_dates_end'] = (string) $args['calendar_dates_end'];
174 $args['booking_hash'] = ( '' !== (string) $args['booking_hash'] ) ? sanitize_text_field( wp_unslash( (string) $args['booking_hash'] ) ) : ( isset( $_GET['booking_hash'] ) ? sanitize_text_field( wp_unslash( $_GET['booking_hash'] ) ) : '' ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
175 $args['allow_past'] = ( null !== $args['allow_past'] ) ? ( ! empty( $args['allow_past'] ) ? 1 : 0 ) : ( isset( $_GET['allow_past'] ) ? 1 : 0 ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
176 $args['selected_dates'] = sanitize_text_field( wp_unslash( (string) $args['selected_dates'] ) );
177 $args['selected_date'] = sanitize_text_field( wp_unslash( (string) $args['selected_date'] ) );
178 $args['selected_time'] = sanitize_text_field( wp_unslash( (string) $args['selected_time'] ) );
179 $args['time_override_enabled'] = ! empty( $args['time_override_enabled'] ) ? 1 : 0;
180 $args['time_override_source'] = sanitize_key( wp_unslash( (string) $args['time_override_source'] ) );
181 $args['time_override_start'] = sanitize_text_field( wp_unslash( (string) $args['time_override_start'] ) );
182 $args['time_override_end'] = sanitize_text_field( wp_unslash( (string) $args['time_override_end'] ) );
183
184 return $args;
185 }
186
187
188 /**
189 * Print per-render context that legacy front-end JavaScript reads from the global _wpbc object.
190 *
191 * @param array $args Component options.
192 *
193 * @return void
194 */
195 private static function print_context_js( $args ) {
196
197 $booking_hash = isset( $args['booking_hash'] ) ? (string) $args['booking_hash'] : '';
198 $allow_past_date_arr = self::get_allow_past_min_date_arr( $args );
199 $context = array(
200 'resource_id' => absint( $args['resource_id'] ),
201 'selected_dates_without_calendar' => (string) $args['selected_dates_without_calendar'],
202 'selected_dates' => (string) $args['selected_dates'],
203 'selected_date' => (string) $args['selected_date'],
204 'selected_time' => (string) $args['selected_time'],
205 'time_override_enabled' => absint( $args['time_override_enabled'] ),
206 'time_override_source' => (string) $args['time_override_source'],
207 'time_override_start' => (string) $args['time_override_start'],
208 'time_override_end' => (string) $args['time_override_end'],
209 'allow_past' => ! empty( $args['allow_past'] ) ? 1 : 0,
210 );
211 ?>
212 <script type="text/javascript">
213 window.wpbc_add_booking_component_context = <?php echo wp_json_encode( $context ); ?>;
214 if ( 'undefined' !== typeof _wpbc ) {
215 _wpbc.set_other_param( 'this_page_booking_hash', <?php echo wp_json_encode( $booking_hash ); ?> );
216 _wpbc.set_other_param( 'this_page_allow_past', <?php echo wp_json_encode( ! empty( $args['allow_past'] ) ? 1 : 0 ); ?> );
217 _wpbc.set_other_param( 'this_page_allow_past_arr', <?php echo wp_json_encode( $allow_past_date_arr ); ?> );
218 }
219 </script>
220 <?php
221 }
222
223
224 /**
225 * Get minimum date array for modal/admin contexts that allow selecting past days.
226 *
227 * @param array $args Component options.
228 *
229 * @return array
230 */
231 private static function get_allow_past_min_date_arr( $args ) {
232
233 if ( empty( $args['allow_past'] ) && empty( $args['booking_hash'] ) ) {
234 return array();
235 }
236
237 if (
238 ! function_exists( 'wpbc_get_max_visible_days_in_calendar' )
239 || ! function_exists( 'wpbc_datetime_localized__use_wp_timezone' )
240 || ! function_exists( 'wpbc_csv_numbers_to_int_array' )
241 ) {
242 return array();
243 }
244
245 $gmt_time = gmdate( 'Y-m-d H:i:s', strtotime( '-' . intval( wpbc_get_max_visible_days_in_calendar() ) . ' days' ) );
246 $local_csv = wpbc_datetime_localized__use_wp_timezone( $gmt_time, 'Y,m,d,H,i' );
247
248 return wpbc_csv_numbers_to_int_array( $local_csv );
249 }
250
251
252 /**
253 * Resolve booking resource id: explicit component args first, then legacy $_GET.
254 *
255 * @param array $args Component options.
256 *
257 * @return int
258 */
259 private static function get_explicit_or_get_resource_id( $args ) {
260
261 if ( ( null !== $args['resource_id'] ) && ( absint( $args['resource_id'] ) > 0 ) ) {
262 return absint( $args['resource_id'] );
263 }
264
265 if ( ( null !== $args['booking_type'] ) && ( absint( $args['booking_type'] ) > 0 ) ) {
266 return absint( $args['booking_type'] );
267 }
268
269 if ( isset( $_GET['booking_type'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
270 return intval( $_GET['booking_type'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
271 }
272
273 return 1;
274 }
275
276
277 /**
278 * Resolve default booking form for specific booking resource.
279 *
280 * @param int $resource_id Booking resource ID.
281 * @param string $default_form Fallback form name.
282 *
283 * @return string
284 */
285 public static function get_default_booking_form_for_resource( $resource_id, $default_form = 'standard' ) {
286
287 $resource_id = absint( $resource_id );
288 $default_form = ( '' !== (string) $default_form ) ? (string) $default_form : 'standard';
289
290 if ( $resource_id <= 0 ) {
291 return sanitize_text_field( wp_unslash( $default_form ) );
292 }
293
294 $default_custom_form_name = '';
295 if ( function_exists( 'apply_bk_filter' ) ) {
296 $default_custom_form_name = apply_bk_filter( 'wpbc_get_default_custom_form', '', $resource_id );
297 }
298
299 if (
300 ( '' === (string) $default_custom_form_name )
301 && class_exists( 'WPBC_FE_Custom_Form_Helper' )
302 && method_exists( 'WPBC_FE_Custom_Form_Helper', 'get_default_custom_form__for__booking_resource' )
303 ) {
304 $default_custom_form_name = WPBC_FE_Custom_Form_Helper::get_default_custom_form__for__booking_resource( $resource_id );
305 }
306
307 $default_custom_form_name = sanitize_text_field( wp_unslash( (string) $default_custom_form_name ) );
308
309 return ( '' !== $default_custom_form_name ) ? $default_custom_form_name : sanitize_text_field( wp_unslash( $default_form ) );
310 }
311
312
313 /**
314 * Resolve booking form: explicit component args first, then legacy $_GET, then resource default.
315 *
316 * @param array $args Component options.
317 * @param int $resource_id Booking resource ID.
318 *
319 * @return string
320 */
321 private static function get_explicit_or_get_booking_form( $args, $resource_id = 0 ) {
322
323 if ( ( null !== $args['custom_booking_form'] ) && ( '' !== (string) $args['custom_booking_form'] ) ) {
324 return sanitize_text_field( wp_unslash( (string) $args['custom_booking_form'] ) );
325 }
326
327 if ( ( null !== $args['booking_form'] ) && ( '' !== (string) $args['booking_form'] ) ) {
328 return sanitize_text_field( wp_unslash( (string) $args['booking_form'] ) );
329 }
330
331 if ( WPBC_GET_Request::has_non_empty_get( 'booking_form' ) ) {
332 return WPBC_GET_Request::get_sanitized( 'booking_form' );
333 }
334
335 return self::get_default_booking_form_for_resource( $resource_id, 'standard' );
336 }
337
338
339 /**
340 * Resolve calendar settings for the component.
341 *
342 * @param array $args Component options.
343 *
344 * @return array
345 */
346 private static function get_calendar_params( $args ) {
347
348 if ( null !== $args['calendar_options'] && is_array( $args['calendar_options'] ) ) {
349 $calendar_options = self::format_calendar_options( $args['calendar_options'] );
350 } else {
351 $calendar_options = self::get_saved_user_calendar_options();
352 }
353
354 if ( null !== $args['calendar_months_count'] ) {
355 $calendar_options['months_number'] = absint( $args['calendar_months_count'] );
356 }
357
358 if ( null !== $args['cal_count'] ) {
359 $calendar_options['months_number'] = absint( $args['cal_count'] );
360 }
361
362 if ( empty( $calendar_options['months_number'] ) ) {
363 $calendar_options['months_number'] = 1;
364 }
365
366 if ( null !== $args['shortcode_param__options'] ) {
367 $shortcode_param__options = (string) $args['shortcode_param__options'];
368 } else {
369 $shortcode_param__options = '{calendar' . $calendar_options['options_param'] . '}';
370 }
371
372 return array(
373 'months_number' => absint( $calendar_options['months_number'] ),
374 'shortcode_param__options' => $shortcode_param__options,
375 );
376 }
377
378
379 /**
380 * Get Calendar Options of specific User.
381 *
382 * @return array Number of months and calendar options parameter.
383 */
384 public static function get_saved_user_calendar_options() {
385
386 $user_calendar_options = get_user_option( 'booking_custom_' . 'add_booking_calendar_options', wpbc_get_current_user_id() );
387
388 if ( false === $user_calendar_options ) {
389 $user_calendar_options = array();
390 } else {
391 $user_calendar_options = maybe_unserialize( $user_calendar_options );
392 }
393
394 return self::format_calendar_options( $user_calendar_options );
395 }
396
397
398 /**
399 * Convert calendar option values to the shortcode option string used by the renderer.
400 *
401 * @param array $user_calendar_options Raw calendar options.
402 *
403 * @return array
404 */
405 private static function format_calendar_options( $user_calendar_options ) {
406
407 $defaults = array(
408 'calendar_months_count' => 1,
409 'calendar_months_num_in_1_row' => 0,
410 'calendar_width' => '',
411 'calendar_widthunits' => 'px',
412 'calendar_cell_height' => '',
413 'calendar_cell_heightunits' => 'px',
414 );
415
416 $user_calendar_options = wp_parse_args( (array) $user_calendar_options, $defaults );
417
418 if ( ! empty( $user_calendar_options['calendar_months_count'] ) ) {
419 $selected_calendar_months_count = intval( $user_calendar_options['calendar_months_count'] );
420 } else {
421 $selected_calendar_months_count = 1;
422 }
423
424 if ( ! empty( $user_calendar_options['calendar_months_num_in_1_row'] ) ) {
425 $option_months_num_in_row = ' months_num_in_row=' . intval( $user_calendar_options['calendar_months_num_in_1_row'] );
426 } else {
427 $option_months_num_in_row = '';
428 }
429
430 if ( ! empty( $user_calendar_options['calendar_width'] ) ) {
431 $unit_value = ( esc_attr( $user_calendar_options['calendar_widthunits'] ) == 'percent' ) ? '%' : esc_attr( $user_calendar_options['calendar_widthunits'] );
432 $option_width = ' width=' . intval( $user_calendar_options['calendar_width'] ) . $unit_value;
433 $option_width .= ' strong_width=' . intval( $user_calendar_options['calendar_width'] ) . $unit_value; // FixIn: 9.3.1.6.
434 } else {
435 $option_width = '';
436 }
437
438 if ( ! empty( $user_calendar_options['calendar_cell_height'] ) ) {
439 $unit_value = ( esc_attr( $user_calendar_options['calendar_cell_heightunits'] ) == 'percent' ) ? '%' : esc_attr( $user_calendar_options['calendar_cell_heightunits'] );
440 $option_cell_height = ' cell_height=' . intval( $user_calendar_options['calendar_cell_height'] ) . $unit_value;
441 } else {
442 $option_cell_height = '';
443 }
444
445 return array(
446 'months_number' => $selected_calendar_months_count,
447 'options_param' => $option_months_num_in_row . $option_width . $option_cell_height,
448 );
449 }
450 }
451