PluginProbe
Booking Calendar / 11.1
Booking Calendar v11.1
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
booking / includes / page-add-booking / add_booking__component.php

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

407 lines 15.6 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_date' => '',
139 'selected_time' => '',
140 'time_override_enabled' => 0,
141 'time_override_source' => '',
142 'time_override_start' => '',
143 'time_override_end' => '',
144 'is_toolbar_visible' => true,
145 'is_booking_page_js' => true,
146 'is_booking_page_popover' => true,
147 'is_show_before_content_spacer' => true,
148 'is_show_footer_email_toggle' => true,
149 'content_css_class' => 'add_booking_page_content',
150 'content_style' => 'width:100%;margin-bottom:100px;',
151 'is_echo' => 1,
152 );
153 $args = wp_parse_args( $args, $defaults );
154
155 $args['_is_explicit_resource_id'] = ( ( null !== $args['resource_id'] ) && ( absint( $args['resource_id'] ) > 0 ) )
156 || ( ( null !== $args['booking_type'] ) && ( absint( $args['booking_type'] ) > 0 ) );
157 $args['_is_explicit_booking_form'] = ( ( null !== $args['custom_booking_form'] ) && ( '' !== (string) $args['custom_booking_form'] ) )
158 || ( ( null !== $args['booking_form'] ) && ( '' !== (string) $args['booking_form'] ) );
159
160 $resource_id = self::get_explicit_or_get_resource_id( $args );
161 $form_name = self::get_explicit_or_get_booking_form( $args );
162
163 $calendar_params = self::get_calendar_params( $args );
164
165 $args['resource_id'] = $resource_id;
166 $args['custom_booking_form'] = $form_name;
167 $args['cal_count'] = $calendar_params['months_number'];
168 $args['shortcode_param__options'] = $calendar_params['shortcode_param__options'];
169
170 $args['selected_dates_without_calendar'] = ( null !== $args['selected_dates_without_calendar'] ) ? (string) $args['selected_dates_without_calendar'] : '';
171 $args['calendar_dates_start'] = (string) $args['calendar_dates_start'];
172 $args['calendar_dates_end'] = (string) $args['calendar_dates_end'];
173 $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
174 $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
175 $args['selected_date'] = sanitize_text_field( wp_unslash( (string) $args['selected_date'] ) );
176 $args['selected_time'] = sanitize_text_field( wp_unslash( (string) $args['selected_time'] ) );
177 $args['time_override_enabled'] = ! empty( $args['time_override_enabled'] ) ? 1 : 0;
178 $args['time_override_source'] = sanitize_key( wp_unslash( (string) $args['time_override_source'] ) );
179 $args['time_override_start'] = sanitize_text_field( wp_unslash( (string) $args['time_override_start'] ) );
180 $args['time_override_end'] = sanitize_text_field( wp_unslash( (string) $args['time_override_end'] ) );
181
182 return $args;
183 }
184
185
186 /**
187 * Print per-render context that legacy front-end JavaScript reads from the global _wpbc object.
188 *
189 * @param array $args Component options.
190 *
191 * @return void
192 */
193 private static function print_context_js( $args ) {
194
195 $booking_hash = isset( $args['booking_hash'] ) ? (string) $args['booking_hash'] : '';
196 $allow_past_date_arr = self::get_allow_past_min_date_arr( $args );
197 $context = array(
198 'resource_id' => absint( $args['resource_id'] ),
199 'selected_dates_without_calendar' => (string) $args['selected_dates_without_calendar'],
200 'selected_date' => (string) $args['selected_date'],
201 'selected_time' => (string) $args['selected_time'],
202 'time_override_enabled' => absint( $args['time_override_enabled'] ),
203 'time_override_source' => (string) $args['time_override_source'],
204 'time_override_start' => (string) $args['time_override_start'],
205 'time_override_end' => (string) $args['time_override_end'],
206 'allow_past' => ! empty( $args['allow_past'] ) ? 1 : 0,
207 );
208 ?>
209 <script type="text/javascript">
210 window.wpbc_add_booking_component_context = <?php echo wp_json_encode( $context ); ?>;
211 if ( 'undefined' !== typeof _wpbc ) {
212 _wpbc.set_other_param( 'this_page_booking_hash', <?php echo wp_json_encode( $booking_hash ); ?> );
213 _wpbc.set_other_param( 'this_page_allow_past', <?php echo wp_json_encode( ! empty( $args['allow_past'] ) ? 1 : 0 ); ?> );
214 _wpbc.set_other_param( 'this_page_allow_past_arr', <?php echo wp_json_encode( $allow_past_date_arr ); ?> );
215 }
216 </script>
217 <?php
218 }
219
220
221 /**
222 * Get minimum date array for modal/admin contexts that allow selecting past days.
223 *
224 * @param array $args Component options.
225 *
226 * @return array
227 */
228 private static function get_allow_past_min_date_arr( $args ) {
229
230 if ( empty( $args['allow_past'] ) && empty( $args['booking_hash'] ) ) {
231 return array();
232 }
233
234 if (
235 ! function_exists( 'wpbc_get_max_visible_days_in_calendar' )
236 || ! function_exists( 'wpbc_datetime_localized__use_wp_timezone' )
237 || ! function_exists( 'wpbc_csv_numbers_to_int_array' )
238 ) {
239 return array();
240 }
241
242 $gmt_time = gmdate( 'Y-m-d H:i:s', strtotime( '-' . intval( wpbc_get_max_visible_days_in_calendar() ) . ' days' ) );
243 $local_csv = wpbc_datetime_localized__use_wp_timezone( $gmt_time, 'Y,m,d,H,i' );
244
245 return wpbc_csv_numbers_to_int_array( $local_csv );
246 }
247
248
249 /**
250 * Resolve booking resource id: explicit component args first, then legacy $_GET.
251 *
252 * @param array $args Component options.
253 *
254 * @return int
255 */
256 private static function get_explicit_or_get_resource_id( $args ) {
257
258 if ( ( null !== $args['resource_id'] ) && ( absint( $args['resource_id'] ) > 0 ) ) {
259 return absint( $args['resource_id'] );
260 }
261
262 if ( ( null !== $args['booking_type'] ) && ( absint( $args['booking_type'] ) > 0 ) ) {
263 return absint( $args['booking_type'] );
264 }
265
266 if ( isset( $_GET['booking_type'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
267 return intval( $_GET['booking_type'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
268 }
269
270 return 1;
271 }
272
273
274 /**
275 * Resolve booking form: explicit component args first, then legacy $_GET.
276 *
277 * @param array $args Component options.
278 *
279 * @return string
280 */
281 private static function get_explicit_or_get_booking_form( $args ) {
282
283 if ( ( null !== $args['custom_booking_form'] ) && ( '' !== (string) $args['custom_booking_form'] ) ) {
284 return sanitize_text_field( wp_unslash( (string) $args['custom_booking_form'] ) );
285 }
286
287 if ( ( null !== $args['booking_form'] ) && ( '' !== (string) $args['booking_form'] ) ) {
288 return sanitize_text_field( wp_unslash( (string) $args['booking_form'] ) );
289 }
290
291 return WPBC_GET_Request::has_non_empty_get( 'booking_form' ) ? WPBC_GET_Request::get_sanitized( 'booking_form' ) : 'standard';
292 }
293
294
295 /**
296 * Resolve calendar settings for the component.
297 *
298 * @param array $args Component options.
299 *
300 * @return array
301 */
302 private static function get_calendar_params( $args ) {
303
304 if ( null !== $args['calendar_options'] && is_array( $args['calendar_options'] ) ) {
305 $calendar_options = self::format_calendar_options( $args['calendar_options'] );
306 } else {
307 $calendar_options = self::get_saved_user_calendar_options();
308 }
309
310 if ( null !== $args['calendar_months_count'] ) {
311 $calendar_options['months_number'] = absint( $args['calendar_months_count'] );
312 }
313
314 if ( null !== $args['cal_count'] ) {
315 $calendar_options['months_number'] = absint( $args['cal_count'] );
316 }
317
318 if ( empty( $calendar_options['months_number'] ) ) {
319 $calendar_options['months_number'] = 1;
320 }
321
322 if ( null !== $args['shortcode_param__options'] ) {
323 $shortcode_param__options = (string) $args['shortcode_param__options'];
324 } else {
325 $shortcode_param__options = '{calendar' . $calendar_options['options_param'] . '}';
326 }
327
328 return array(
329 'months_number' => absint( $calendar_options['months_number'] ),
330 'shortcode_param__options' => $shortcode_param__options,
331 );
332 }
333
334
335 /**
336 * Get Calendar Options of specific User.
337 *
338 * @return array Number of months and calendar options parameter.
339 */
340 public static function get_saved_user_calendar_options() {
341
342 $user_calendar_options = get_user_option( 'booking_custom_' . 'add_booking_calendar_options', wpbc_get_current_user_id() );
343
344 if ( false === $user_calendar_options ) {
345 $user_calendar_options = array();
346 } else {
347 $user_calendar_options = maybe_unserialize( $user_calendar_options );
348 }
349
350 return self::format_calendar_options( $user_calendar_options );
351 }
352
353
354 /**
355 * Convert calendar option values to the shortcode option string used by the renderer.
356 *
357 * @param array $user_calendar_options Raw calendar options.
358 *
359 * @return array
360 */
361 private static function format_calendar_options( $user_calendar_options ) {
362
363 $defaults = array(
364 'calendar_months_count' => 1,
365 'calendar_months_num_in_1_row' => 0,
366 'calendar_width' => '',
367 'calendar_widthunits' => 'px',
368 'calendar_cell_height' => '',
369 'calendar_cell_heightunits' => 'px',
370 );
371
372 $user_calendar_options = wp_parse_args( (array) $user_calendar_options, $defaults );
373
374 if ( ! empty( $user_calendar_options['calendar_months_count'] ) ) {
375 $selected_calendar_months_count = intval( $user_calendar_options['calendar_months_count'] );
376 } else {
377 $selected_calendar_months_count = 1;
378 }
379
380 if ( ! empty( $user_calendar_options['calendar_months_num_in_1_row'] ) ) {
381 $option_months_num_in_row = ' months_num_in_row=' . intval( $user_calendar_options['calendar_months_num_in_1_row'] );
382 } else {
383 $option_months_num_in_row = '';
384 }
385
386 if ( ! empty( $user_calendar_options['calendar_width'] ) ) {
387 $unit_value = ( esc_attr( $user_calendar_options['calendar_widthunits'] ) == 'percent' ) ? '%' : esc_attr( $user_calendar_options['calendar_widthunits'] );
388 $option_width = ' width=' . intval( $user_calendar_options['calendar_width'] ) . $unit_value;
389 $option_width .= ' strong_width=' . intval( $user_calendar_options['calendar_width'] ) . $unit_value; // FixIn: 9.3.1.6.
390 } else {
391 $option_width = '';
392 }
393
394 if ( ! empty( $user_calendar_options['calendar_cell_height'] ) ) {
395 $unit_value = ( esc_attr( $user_calendar_options['calendar_cell_heightunits'] ) == 'percent' ) ? '%' : esc_attr( $user_calendar_options['calendar_cell_heightunits'] );
396 $option_cell_height = ' cell_height=' . intval( $user_calendar_options['calendar_cell_height'] ) . $unit_value;
397 } else {
398 $option_cell_height = '';
399 }
400
401 return array(
402 'months_number' => $selected_calendar_months_count,
403 'options_param' => $option_months_num_in_row . $option_width . $option_cell_height,
404 );
405 }
406 }
407