PluginProbe
Booking Calendar / 11.3
Booking Calendar v11.3
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-settings-themes / settings_themes__page.php

settings_themes__page.php in Booking Calendar 11.3, at includes/page-settings-themes/settings_themes__page.php

1,349 lines 45.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Appearance / Theme settings page.
4 *
5 * @package Booking Calendar
6 */
7
8 if ( ! defined( 'ABSPATH' ) ) {
9 exit;
10 }
11
12 /**
13 * Check whether the Appearance / Theme settings page is active.
14 *
15 * @return bool
16 */
17 function wpbc_settings_themes__is_page() {
18
19 if ( ! is_admin() ) {
20 return false;
21 }
22
23 if ( function_exists( 'wpbc_is_settings_themes_page' ) ) {
24 return wpbc_is_settings_themes_page();
25 }
26
27 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
28 $page = isset( $_REQUEST['page'] ) ? sanitize_key( wp_unslash( $_REQUEST['page'] ) ) : '';
29 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
30 $tab = isset( $_REQUEST['tab'] ) ? sanitize_key( wp_unslash( $_REQUEST['tab'] ) ) : '';
31
32 return ( 'wpbc-settings' === $page && 'themes' === $tab );
33 }
34
35 /**
36 * Redirect legacy Color Theme URLs to the new Appearance / Theme page.
37 *
38 * @return void
39 */
40 function wpbc_settings_themes__redirect_legacy_color_themes_url() {
41
42 if ( ! is_admin() ) {
43 return;
44 }
45
46 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
47 $page = isset( $_GET['page'] ) ? sanitize_key( wp_unslash( $_GET['page'] ) ) : '';
48 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
49 $tab = isset( $_GET['tab'] ) ? sanitize_key( wp_unslash( $_GET['tab'] ) ) : '';
50
51 if (
52 'wpbc-settings' !== $page
53 || 'color_themes' !== $tab
54 ) {
55 return;
56 }
57
58 $args = array();
59 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
60 foreach ( wp_unslash( $_GET ) as $key => $value ) {
61 $key = sanitize_key( $key );
62 if ( in_array( $key, array( 'page', 'tab' ), true ) || is_array( $value ) ) {
63 continue;
64 }
65 $args[ $key ] = sanitize_text_field( $value );
66 }
67
68 $url = function_exists( 'wpbc_get_settings_themes_url' )
69 ? wpbc_get_settings_themes_url()
70 : admin_url( 'admin.php?page=wpbc-settings&tab=themes' );
71
72 wp_safe_redirect( add_query_arg( $args, $url ) );
73 exit;
74 }
75 add_action( 'admin_init', 'wpbc_settings_themes__redirect_legacy_color_themes_url', 1 );
76
77 /**
78 * Enqueue CSS for Appearance / Theme.
79 *
80 * @param string $where_to_load Where assets are loaded.
81 *
82 * @return void
83 */
84 function wpbc_settings_themes_enqueue_css_files( $where_to_load ) {
85
86 if ( ( ! is_admin() ) || ( ! in_array( $where_to_load, array( 'admin', 'both' ), true ) ) ) {
87 return;
88 }
89
90 if ( ! wpbc_settings_themes__is_page() ) {
91 return;
92 }
93
94 wp_enqueue_style(
95 'wpbc-settings-themes-page',
96 trailingslashit( plugins_url( '', __FILE__ ) ) . '_out/settings_themes_page.css',
97 array( 'wpbc-calendar', 'wpbc-all-admin' ),
98 WP_BK_VERSION_NUM
99 );
100 }
101 add_action( 'wpbc_enqueue_css_files', 'wpbc_settings_themes_enqueue_css_files', 66 );
102
103 /**
104 * Enqueue JS for Appearance / Theme.
105 *
106 * @param string $where_to_load Where assets are loaded.
107 *
108 * @return void
109 */
110 function wpbc_settings_themes_enqueue_js_files( $where_to_load ) {
111
112 if ( ( ! is_admin() ) || ( ! in_array( $where_to_load, array( 'admin', 'both' ), true ) ) ) {
113 return;
114 }
115
116 if ( ! wpbc_settings_themes__is_page() ) {
117 return;
118 }
119
120 wp_enqueue_script(
121 'wpbc-settings-themes-page',
122 trailingslashit( plugins_url( '', __FILE__ ) ) . '_out/settings_themes_page.js',
123 array( 'jquery', 'wpbc_all' ),
124 WP_BK_VERSION_NUM,
125 array( 'in_footer' => WPBC_JS_IN_FOOTER )
126 );
127
128 wp_localize_script(
129 'wpbc-settings-themes-page',
130 'wpbc_settings_themes_page',
131 array(
132 'ajax_url' => admin_url( 'admin-ajax.php' ),
133 'plugin_url' => trailingslashit( WPBC_PLUGIN_URL ),
134 'nonce' => wp_create_nonce( 'wpbc_settings_themes_ajax_nonce' ),
135 'action' => 'WPBC_AJX_SETTINGS_THEMES_SAVE',
136 'preview_action' => 'WPBC_AJX_SETTINGS_THEMES_PREVIEW',
137 'settings' => wpbc_settings_themes__get_settings_response(),
138 'days_selection' => wpbc_settings_themes__get_days_selection_response(),
139 'i18n' => array(
140 'saving' => __( 'Saving', 'booking' ),
141 'saved' => __( 'Appearance settings updated.', 'booking' ),
142 'save_failed' => __( 'Unable to save appearance settings.', 'booking' ),
143 'preview_failed' => __( 'Unable to refresh calendar preview.', 'booking' ),
144 'security_error' => __( 'Security check failed.', 'booking' ),
145 'loading' => __( 'Loading', 'booking' ),
146 'calendar_only_theme_notice' => __( 'Preview is set to Calendar only. A matching calendar skin was selected automatically; switch Preview to Booking form to inspect the form theme.', 'booking' ),
147 'form_preview_option_notice' => __( 'This option is visible in the Booking form preview. Switch Preview to Booking form to inspect it.', 'booking' ),
148 ),
149 )
150 );
151 }
152 add_action( 'wpbc_enqueue_js_files', 'wpbc_settings_themes_enqueue_js_files', 66 );
153
154 /**
155 * Print tooltip initializer for Appearance / Theme.
156 *
157 * @return void
158 */
159 function wpbc_settings_themes_print_tooltip_js() {
160
161 if ( ! wpbc_settings_themes__is_page() ) {
162 return;
163 }
164
165 if ( function_exists( 'wpbc_bs_javascript_tooltips' ) ) {
166 wpbc_bs_javascript_tooltips();
167 }
168 }
169 add_action( 'admin_footer', 'wpbc_settings_themes_print_tooltip_js', 67 );
170
171 /**
172 * Get day-selection settings in the same normalized shape used by calendar boot code.
173 *
174 * @return array
175 */
176 function wpbc_settings_themes__get_days_selection_response() {
177
178 $days_selection = array(
179 'days_select_mode' => 'multiple',
180 'fixed__days_num' => 0,
181 'fixed__week_days__start' => '-1',
182 'dynamic__days_min' => 0,
183 'dynamic__days_max' => 0,
184 'dynamic__days_specific' => '',
185 'dynamic__week_days__start' => '-1',
186 );
187
188 if ( function_exists( 'wpbc__calendar__js_params__get_days_selection_arr' ) ) {
189 $days_selection = wp_parse_args( wpbc__calendar__js_params__get_days_selection_arr(), $days_selection );
190 }
191
192 return array(
193 'days_select_mode' => (string) $days_selection['days_select_mode'],
194 'fixed__days_num' => (int) $days_selection['fixed__days_num'],
195 'fixed__week_days__start' => (string) $days_selection['fixed__week_days__start'],
196 'dynamic__days_min' => (int) $days_selection['dynamic__days_min'],
197 'dynamic__days_max' => (int) $days_selection['dynamic__days_max'],
198 'dynamic__days_specific' => (string) $days_selection['dynamic__days_specific'],
199 'dynamic__week_days__start' => (string) $days_selection['dynamic__week_days__start'],
200 );
201 }
202
203 /**
204 * Get resource options.
205 *
206 * @return array
207 */
208 function wpbc_settings_themes__get_resources() {
209
210 if ( function_exists( 'wpbc_availability_general__get_resources' ) ) {
211 return wpbc_availability_general__get_resources();
212 }
213
214 $resources = array();
215
216 if ( function_exists( 'wpbc_ajx_get_sorted_booking_resources_arr' ) && function_exists( 'wpbc_ajx_get_all_booking_resources_arr' ) ) {
217 $resource_rows = wpbc_ajx_get_sorted_booking_resources_arr( wpbc_ajx_get_all_booking_resources_arr() );
218 foreach ( $resource_rows as $resource ) {
219 $resources[] = array(
220 'id' => isset( $resource['booking_type_id'] ) ? (int) $resource['booking_type_id'] : 1,
221 'title' => isset( $resource['title'] ) ? $resource['title'] : __( 'Booking resource', 'booking' ),
222 );
223 }
224 }
225
226 if ( empty( $resources ) ) {
227 $resources[] = array(
228 'id' => function_exists( 'wpbc_get_default_resource' ) ? (int) wpbc_get_default_resource() : 1,
229 'title' => __( 'Booking resource', 'booking' ),
230 );
231 }
232
233 return $resources;
234 }
235
236 /**
237 * Get capability required to manage Appearance / Theme.
238 *
239 * @return string
240 */
241 function wpbc_settings_themes__get_manage_cap() {
242
243 $min_user_role = get_bk_option( 'booking_user_role_settings' );
244 $capability = array(
245 'administrator' => 'activate_plugins',
246 'editor' => 'publish_pages',
247 'author' => 'publish_posts',
248 'contributor' => 'edit_posts',
249 'subscriber' => 'read',
250 );
251
252 return isset( $capability[ $min_user_role ] ) ? $capability[ $min_user_role ] : 'manage_options';
253 }
254
255 /**
256 * Check if a Theme Settings upsell row is visible for current user.
257 *
258 * @param string $dismiss_id Dismiss ID.
259 *
260 * @return bool
261 */
262 function wpbc_settings_themes__is_dismissed_visible( $dismiss_id ) {
263
264 if ( wpbc_is_this_demo() ) {
265 return true;
266 }
267
268 return ! function_exists( 'wpbc_is_dismissed_panel_visible' ) || wpbc_is_dismissed_panel_visible( $dismiss_id );
269 }
270
271 /**
272 * Get dismiss ID for Theme Settings premium option.
273 *
274 * @param string $option_name Option name.
275 *
276 * @return string
277 */
278 function wpbc_settings_themes__get_premium_option_dismiss_id( $option_name ) {
279
280 return 'wpbc_is_dismissed__theme_settings__' . sanitize_key( $option_name );
281 }
282
283 /**
284 * Render compact dismiss button for Theme Settings premium hints.
285 *
286 * @param string $dismiss_id Dismiss ID.
287 *
288 * @return void
289 */
290 function wpbc_settings_themes__render_dismiss_button( $dismiss_id ) {
291
292 if ( wpbc_is_this_demo() || ! function_exists( 'wpbc_is_dismissed' ) ) {
293 return;
294 }
295
296 ?>
297 <span class="wpbc_theme_premium_dismiss">
298 <?php
299 wpbc_is_dismissed(
300 $dismiss_id,
301 array(
302 'title' => '&times;',
303 'hint' => __( 'Hide this option', 'booking' ),
304 'css' => 'float:none;margin-left:4px;',
305 )
306 );
307 ?>
308 </span>
309 <?php
310 }
311
312 /**
313 * Sanitize preview resource ID.
314 *
315 * @param int $resource_id Resource ID.
316 *
317 * @return int
318 */
319 function wpbc_settings_themes__sanitize_preview_resource_id( $resource_id ) {
320
321 $resource_id = absint( $resource_id );
322 $resources = wpbc_settings_themes__get_resources();
323 $allowed = array();
324
325 foreach ( $resources as $resource ) {
326 $allowed[] = (int) $resource['id'];
327 }
328
329 if ( in_array( $resource_id, $allowed, true ) ) {
330 return $resource_id;
331 }
332
333 return ! empty( $allowed ) ? (int) $allowed[0] : 1;
334 }
335
336 /**
337 * Sanitize preview months count.
338 *
339 * @param int $months_count Months count.
340 *
341 * @return int
342 */
343 function wpbc_settings_themes__sanitize_preview_months_count( $months_count ) {
344
345 $months_count = absint( $months_count );
346 $allowed = array( 1, 2, 3, 4, 6, 12 );
347
348 return in_array( $months_count, $allowed, true ) ? $months_count : 1;
349 }
350
351 /**
352 * Get preview resource from request or default.
353 *
354 * @return int
355 */
356 function wpbc_settings_themes__get_preview_resource_id() {
357
358 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
359 $resource_id = isset( $_REQUEST['resource_id'] ) ? absint( wp_unslash( $_REQUEST['resource_id'] ) ) : ( function_exists( 'wpbc_get_default_resource' ) ? (int) wpbc_get_default_resource() : 1 );
360
361 return wpbc_settings_themes__sanitize_preview_resource_id( $resource_id );
362 }
363
364 /**
365 * Get preview months count from request or default.
366 *
367 * @return int
368 */
369 function wpbc_settings_themes__get_preview_months_count() {
370
371 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
372 $months_count = isset( $_REQUEST['months_count'] ) ? absint( wp_unslash( $_REQUEST['months_count'] ) ) : 1;
373
374 return wpbc_settings_themes__sanitize_preview_months_count( $months_count );
375 }
376
377 /**
378 * Get preview mode options.
379 *
380 * @return array
381 */
382 function wpbc_settings_themes__get_preview_mode_options() {
383
384 return array(
385 'calendar' => __( 'Calendar only', 'booking' ),
386 'form' => __( 'Booking form', 'booking' ),
387 );
388 }
389
390 /**
391 * Sanitize preview mode.
392 *
393 * @param string $preview_mode Preview mode.
394 *
395 * @return string
396 */
397 function wpbc_settings_themes__sanitize_preview_mode( $preview_mode ) {
398
399 $preview_mode = sanitize_key( (string) $preview_mode );
400
401 return array_key_exists( $preview_mode, wpbc_settings_themes__get_preview_mode_options() ) ? $preview_mode : 'calendar';
402 }
403
404 /**
405 * Get preview mode from request.
406 *
407 * @return string
408 */
409 function wpbc_settings_themes__get_preview_mode() {
410
411 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
412 $preview_mode = isset( $_REQUEST['preview_mode'] ) ? sanitize_key( wp_unslash( $_REQUEST['preview_mode'] ) ) : 'calendar';
413
414 return wpbc_settings_themes__sanitize_preview_mode( $preview_mode );
415 }
416
417 /**
418 * Get booking form options for preview.
419 *
420 * @return array
421 */
422 function wpbc_settings_themes__get_booking_form_options() {
423
424 $form_options = array(
425 'standard' => __( 'Standard booking form', 'booking' ),
426 );
427
428 if ( class_exists( 'WPBC_FE_Custom_Form_Helper' ) ) {
429 $owner_user_id = method_exists( 'WPBC_FE_Custom_Form_Helper', 'wpbc_mu__get_current__owner_user_id' ) ? WPBC_FE_Custom_Form_Helper::wpbc_mu__get_current__owner_user_id() : 0;
430 $forms_list = WPBC_FE_Custom_Form_Helper::get_custom_booking_forms_list(
431 array(
432 'include_standard' => true,
433 'owner_user_id' => $owner_user_id,
434 'statuses' => array( 'published' ),
435 'list_mode' => 'auto',
436 )
437 );
438
439 if ( is_array( $forms_list ) ) {
440 foreach ( $forms_list as $form_slug => $form_data ) {
441 $form_slug = sanitize_text_field( (string) $form_slug );
442 if ( '' === $form_slug ) {
443 continue;
444 }
445 $form_options[ $form_slug ] = isset( $form_data['title'] ) ? sanitize_text_field( (string) $form_data['title'] ) : $form_slug;
446 }
447 }
448 }
449
450 return $form_options;
451 }
452
453 /**
454 * Sanitize custom booking form.
455 *
456 * @param string $custom_booking_form Custom booking form slug.
457 *
458 * @return string
459 */
460 function wpbc_settings_themes__sanitize_custom_booking_form( $custom_booking_form ) {
461
462 $custom_booking_form = sanitize_text_field( (string) $custom_booking_form );
463 $form_options = wpbc_settings_themes__get_booking_form_options();
464
465 return array_key_exists( $custom_booking_form, $form_options ) ? $custom_booking_form : 'standard';
466 }
467
468 /**
469 * Get custom booking form from request.
470 *
471 * @return string
472 */
473 function wpbc_settings_themes__get_custom_booking_form() {
474
475 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
476 $custom_booking_form = isset( $_REQUEST['custom_booking_form'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['custom_booking_form'] ) ) : 'standard';
477
478 return wpbc_settings_themes__sanitize_custom_booking_form( $custom_booking_form );
479 }
480
481 /**
482 * Get form theme options.
483 *
484 * @return array
485 */
486 function wpbc_settings_themes__get_form_theme_options() {
487
488 return array(
489 '' => __( 'Light', 'booking' ),
490 'wpbc_theme_dark_1' => __( 'Dark', 'booking' ),
491 );
492 }
493
494 /**
495 * Get time picker skin options.
496 *
497 * @return array
498 */
499 function wpbc_settings_themes__get_time_picker_skin_options() {
500
501 $timeslot_picker_skins_options = array();
502 $upload_dir = wp_upload_dir();
503
504 if ( function_exists( 'wpbc_dir_list' ) ) {
505 $files_in_folder = wpbc_dir_list(
506 array(
507 WPBC_PLUGIN_DIR . '/css/time_picker_skins/',
508 $upload_dir['basedir'] . '/wpbc_time_picker_skins/',
509 )
510 );
511
512 foreach ( $files_in_folder as $skin_file ) {
513 $skin_file[1] = str_replace( array( WPBC_PLUGIN_DIR, WPBC_PLUGIN_URL, $upload_dir['basedir'] ), '', $skin_file[1] );
514 $timeslot_picker_skins_options[ $skin_file[1] ] = $skin_file[2];
515 }
516 }
517
518 if ( empty( $timeslot_picker_skins_options ) ) {
519 $default_options_values = wpbc_get_default_options();
520 $default_skin = isset( $default_options_values['booking_timeslot_picker_skin'] ) ? $default_options_values['booking_timeslot_picker_skin'] : '/css/time_picker_skins/grey.css';
521 $timeslot_picker_skins_options[ $default_skin ] = __( 'Default', 'booking' );
522 }
523
524 return $timeslot_picker_skins_options;
525 }
526
527 /**
528 * Normalize calendar skin option value to a relative path.
529 *
530 * @param string $skin_value Calendar skin value.
531 *
532 * @return string
533 */
534 function wpbc_settings_themes__normalize_calendar_skin_value( $skin_value ) {
535
536 $skin_value = (string) $skin_value;
537 $upload_dir = wp_upload_dir();
538 $upload_url = ( ! empty( $upload_dir['baseurl'] ) ) ? $upload_dir['baseurl'] : '';
539
540 return str_replace(
541 array(
542 WPBC_PLUGIN_URL,
543 $upload_url,
544 ),
545 '',
546 $skin_value
547 );
548 }
549
550 /**
551 * Get URL for a relative calendar skin path.
552 *
553 * @param string $relative_skin Relative skin path.
554 *
555 * @return string
556 */
557 function wpbc_settings_themes__get_calendar_skin_url( $relative_skin ) {
558
559 $relative_skin = wpbc_settings_themes__normalize_calendar_skin_value( $relative_skin );
560 $upload_dir = wp_upload_dir();
561 $upload_url = ( ! empty( $upload_dir['baseurl'] ) ) ? $upload_dir['baseurl'] : '';
562
563 if ( 0 === strpos( $relative_skin, '/wpbc_skins/' ) && ! empty( $upload_url ) ) {
564 return $upload_url . $relative_skin;
565 }
566
567 return WPBC_PLUGIN_URL . $relative_skin;
568 }
569
570 /**
571 * Build calendar skin options for selectbox with live-preview URL metadata.
572 *
573 * @return array
574 */
575 function wpbc_settings_themes__get_calendar_skin_options_for_select() {
576
577 $options = function_exists( 'wpbc_get_calendar_skin_options' ) ? wpbc_get_calendar_skin_options() : array();
578
579 foreach ( $options as $option_value => $option_label ) {
580 if ( is_array( $option_label ) && ! empty( $option_label['optgroup'] ) ) {
581 continue;
582 }
583
584 $relative_skin = wpbc_settings_themes__normalize_calendar_skin_value( $option_value );
585 $skin_url = wpbc_settings_themes__get_calendar_skin_url( $relative_skin );
586
587 if ( is_array( $option_label ) ) {
588 $option_label['attr'] = ( isset( $option_label['attr'] ) && is_array( $option_label['attr'] ) ) ? $option_label['attr'] : array();
589 $option_label['attr']['data-wpbc-calendar-skin-url'] = $skin_url;
590 $options[ $relative_skin ] = $option_label;
591 } else {
592 $options[ $relative_skin ] = array(
593 'title' => $option_label,
594 'attr' => array(
595 'data-wpbc-calendar-skin-url' => $skin_url,
596 ),
597 );
598 }
599
600 if ( $relative_skin !== $option_value ) {
601 unset( $options[ $option_value ] );
602 }
603 }
604
605 return $options;
606 }
607
608 /**
609 * Get current settings prepared for JavaScript and AJAX responses.
610 *
611 * @return array
612 */
613 function wpbc_settings_themes__get_settings_response() {
614
615 return array(
616 'booking_form_theme' => get_bk_option( 'booking_form_theme' ),
617 'booking_skin' => wpbc_settings_themes__normalize_calendar_skin_value( get_bk_option( 'booking_skin' ) ),
618 'booking_timeslot_picker_skin' => get_bk_option( 'booking_timeslot_picker_skin' ),
619 'booking_timeslot_picker' => get_bk_option( 'booking_timeslot_picker' ),
620 );
621 }
622
623 /**
624 * Override option values while rendering the live Appearance / Theme preview.
625 *
626 * @param mixed $value Current filter value.
627 * @param string $option Option name.
628 * @param mixed $default Default option value.
629 *
630 * @return mixed
631 */
632 function wpbc_settings_themes__preview_get_bk_option( $value, $option, $default ) {
633
634 global $wpbc_settings_themes__preview_options;
635
636 if (
637 is_array( $wpbc_settings_themes__preview_options )
638 && array_key_exists( $option, $wpbc_settings_themes__preview_options )
639 ) {
640 return $wpbc_settings_themes__preview_options[ $option ];
641 }
642
643 return $value;
644 }
645 add_bk_filter( 'wpdev_bk_get_option', 'wpbc_settings_themes__preview_get_bk_option' );
646
647 /**
648 * Prepare option overrides for the live preview renderer.
649 *
650 * @param array $current_settings Current preview settings.
651 *
652 * @return array
653 */
654 function wpbc_settings_themes__get_preview_option_overrides( $current_settings ) {
655
656 $option_names = array(
657 'booking_form_theme',
658 'booking_skin',
659 'booking_timeslot_picker_skin',
660 'booking_timeslot_picker',
661 );
662 $overrides = array();
663
664 foreach ( $option_names as $option_name ) {
665 if ( array_key_exists( $option_name, $current_settings ) ) {
666 $overrides[ $option_name ] = $current_settings[ $option_name ];
667 }
668 }
669
670 return $overrides;
671 }
672
673 /**
674 * Validate posted Appearance / Theme settings.
675 *
676 * @param array $post_data Raw post data.
677 *
678 * @return array
679 */
680 function wpbc_settings_themes__validate_data( $post_data ) {
681
682 $default_options_values = wpbc_get_default_options();
683 $form_theme_options = wpbc_settings_themes__get_form_theme_options();
684 $calendar_skin_options = wpbc_settings_themes__get_calendar_skin_options_for_select();
685 $time_skin_options = wpbc_settings_themes__get_time_picker_skin_options();
686
687 $cleaned = array(
688 'booking_form_theme' => isset( $default_options_values['booking_form_theme'] ) ? $default_options_values['booking_form_theme'] : '',
689 'booking_skin' => isset( $default_options_values['booking_skin'] ) ? $default_options_values['booking_skin'] : '',
690 'booking_timeslot_picker_skin' => isset( $default_options_values['booking_timeslot_picker_skin'] ) ? $default_options_values['booking_timeslot_picker_skin'] : '',
691 'booking_timeslot_picker' => isset( $default_options_values['booking_timeslot_picker'] ) ? $default_options_values['booking_timeslot_picker'] : 'Off',
692 );
693
694 if ( isset( $post_data['booking_form_theme'] ) ) {
695 $value = sanitize_text_field( wp_unslash( $post_data['booking_form_theme'] ) );
696 if ( array_key_exists( $value, $form_theme_options ) ) {
697 $cleaned['booking_form_theme'] = $value;
698 }
699 }
700
701 if ( isset( $post_data['booking_skin'] ) ) {
702 $value = wpbc_settings_themes__normalize_calendar_skin_value( sanitize_text_field( wp_unslash( $post_data['booking_skin'] ) ) );
703 if ( array_key_exists( $value, $calendar_skin_options ) ) {
704 $cleaned['booking_skin'] = $value;
705 }
706 }
707
708 if ( isset( $post_data['booking_timeslot_picker_skin'] ) ) {
709 $value = sanitize_text_field( wp_unslash( $post_data['booking_timeslot_picker_skin'] ) );
710 if ( array_key_exists( $value, $time_skin_options ) ) {
711 $cleaned['booking_timeslot_picker_skin'] = $value;
712 }
713 }
714
715 $timeslot_picker_value = isset( $post_data['booking_timeslot_picker'] ) ? sanitize_text_field( wp_unslash( $post_data['booking_timeslot_picker'] ) ) : '';
716
717 $cleaned['booking_timeslot_picker'] = ( 'On' === $timeslot_picker_value ) ? 'On' : 'Off';
718
719 return $cleaned;
720 }
721
722 /**
723 * Update Appearance / Theme settings.
724 *
725 * @param array $cleaned_data Cleaned settings.
726 *
727 * @return void
728 */
729 function wpbc_settings_themes__update_settings( $cleaned_data ) {
730
731 update_bk_option( 'booking_form_theme', $cleaned_data['booking_form_theme'] );
732 update_bk_option( 'booking_skin', $cleaned_data['booking_skin'] );
733 update_bk_option( 'booking_timeslot_picker_skin', $cleaned_data['booking_timeslot_picker_skin'] );
734 update_bk_option( 'booking_timeslot_picker', $cleaned_data['booking_timeslot_picker'] );
735 }
736
737 /**
738 * Render select field.
739 *
740 * @param string $name Field name.
741 * @param array $options Options.
742 * @param string $selected Selected value.
743 * @param array $args Extra args.
744 *
745 * @return void
746 */
747 function wpbc_settings_themes__render_select( $name, $options, $selected, $args = array() ) {
748
749 $args = wp_parse_args(
750 $args,
751 array(
752 'id' => $name,
753 'class' => '',
754 'data_attrs' => array(),
755 )
756 );
757
758 $data_attrs = '';
759 foreach ( $args['data_attrs'] as $attr_name => $attr_value ) {
760 $data_attrs .= ' ' . esc_attr( $attr_name ) . '="' . esc_attr( $attr_value ) . '"';
761 }
762 ?>
763 <select id="<?php echo esc_attr( $args['id'] ); ?>" name="<?php echo esc_attr( $name ); ?>" class="<?php echo esc_attr( $args['class'] ); ?>"<?php echo $data_attrs; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
764 <?php
765 foreach ( $options as $option_value => $option_data ) :
766 if ( ! is_array( $option_data ) ) {
767 $option_data = array( 'title' => $option_data );
768 }
769
770 $option_data = wp_parse_args(
771 $option_data,
772 array(
773 'title' => '',
774 'style' => '',
775 'class' => '',
776 'disabled' => false,
777 'selected' => false,
778 'attr' => array(),
779 'optgroup' => false,
780 'close' => false,
781 )
782 );
783
784 if ( ! empty( $option_data['optgroup'] ) ) :
785 if ( empty( $option_data['close'] ) ) :
786 ?>
787 <optgroup label="<?php echo esc_attr( $option_data['title'] ); ?>">
788 <?php
789 else :
790 ?>
791 </optgroup>
792 <?php
793 endif;
794 continue;
795 endif;
796
797 $option_attrs = '';
798 if ( ! empty( $option_data['attr'] ) && is_array( $option_data['attr'] ) ) {
799 foreach ( $option_data['attr'] as $attr_name => $attr_value ) {
800 $option_attrs .= ' ' . esc_attr( $attr_name ) . '="' . esc_attr( $attr_value ) . '"';
801 }
802 }
803 ?>
804 <option
805 value="<?php echo esc_attr( $option_value ); ?>"
806 <?php selected( (string) $selected, (string) $option_value ); ?>
807 <?php selected( ! empty( $option_data['selected'] ), true ); ?>
808 <?php disabled( ! empty( $option_data['disabled'] ), true ); ?>
809 <?php echo ( '' !== $option_data['class'] ) ? ' class="' . esc_attr( $option_data['class'] ) . '"' : ''; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
810 <?php echo ( '' !== $option_data['style'] ) ? ' style="' . esc_attr( $option_data['style'] ) . '"' : ''; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
811 <?php echo $option_attrs; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
812 ><?php echo wp_kses_post( html_entity_decode( (string) $option_data['title'], ENT_QUOTES, get_bloginfo( 'charset' ) ) ); ?></option>
813 <?php
814 endforeach;
815 ?>
816 </select>
817 <?php
818 }
819
820 /**
821 * Render booking resource calendar preview.
822 *
823 * @param int $resource_id Resource ID.
824 * @param int $months_count Number of months.
825 * @param array $preview_settings Optional settings.
826 *
827 * @return void
828 */
829 function wpbc_settings_themes__render_calendar_preview( $resource_id, $months_count, $preview_settings = array(), $preview_mode = 'calendar', $custom_booking_form = 'standard' ) {
830
831 global $wpbc_settings_themes__preview_options;
832
833 $resource_id = wpbc_settings_themes__sanitize_preview_resource_id( $resource_id );
834 $months_count = wpbc_settings_themes__sanitize_preview_months_count( $months_count );
835 $current_settings = wp_parse_args( $preview_settings, wpbc_settings_themes__get_settings_response() );
836 $form_theme = sanitize_html_class( $current_settings['booking_form_theme'] );
837 $preview_mode = wpbc_settings_themes__sanitize_preview_mode( $preview_mode );
838 $custom_booking_form = wpbc_settings_themes__sanitize_custom_booking_form( $custom_booking_form );
839 $previous_preview_options = isset( $wpbc_settings_themes__preview_options ) ? $wpbc_settings_themes__preview_options : null;
840 $wpbc_settings_themes__preview_options = wpbc_settings_themes__get_preview_option_overrides( $current_settings );
841 ?>
842 <div class="wpbc_theme_preview <?php echo esc_attr( $form_theme ); ?> wpbc_theme_preview_mode_<?php echo esc_attr( $preview_mode ); ?>" data-wpbc-admin-calendar-preview="1" data-wpbc-theme-preview="1" data-resource-id="<?php echo esc_attr( $resource_id ); ?>" data-months-count="<?php echo esc_attr( $months_count ); ?>" data-preview-mode="<?php echo esc_attr( $preview_mode ); ?>" data-custom-booking-form="<?php echo esc_attr( $custom_booking_form ); ?>">
843 <div class="wpbc_theme_real_preview" data-wpbc-theme-calendar-panel="1">
844 <?php
845 if ( class_exists( 'WPBC_FE_Render' ) ) {
846 if ( 'form' === $preview_mode ) {
847 WPBC_FE_Render::render_booking_form(
848 array(
849 'resource_id' => $resource_id,
850 'cal_count' => $months_count,
851 'is_echo' => 1,
852 'custom_booking_form' => $custom_booking_form,
853 )
854 );
855 } else {
856 WPBC_FE_Render::render_calendar_only(
857 array(
858 'resource_id' => $resource_id,
859 'cal_count' => $months_count,
860 'is_echo' => 1,
861 )
862 );
863 }
864 } elseif ( function_exists( 'wpbc__calendar__load' ) ) {
865 echo wpbc__calendar__load( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
866 array(
867 'resource_id' => $resource_id,
868 'aggregate_resource_id_arr' => array(),
869 'selected_dates_without_calendar' => '',
870 'calendar_number_of_months' => $months_count,
871 'start_month_calendar' => false,
872 'shortcode_options' => '',
873 'custom_form' => $custom_booking_form,
874 'skip_general_availability' => 1,
875 )
876 );
877 }
878 ?>
879 </div>
880 </div>
881 <?php
882
883 if ( null === $previous_preview_options ) {
884 unset( $wpbc_settings_themes__preview_options );
885 } else {
886 $wpbc_settings_themes__preview_options = $previous_preview_options;
887 }
888 }
889
890 /**
891 * Show Appearance / Theme save button in top toolbar.
892 *
893 * @param string $page_tag Current page tag.
894 * @param string $active_page_tab Current tab.
895 * @param string $active_page_subtab Current subtab.
896 *
897 * @return void
898 */
899 function wpbc_settings_themes__top_toolbar__show_save_button( $page_tag, $active_page_tab, $active_page_subtab ) {
900
901 if ( ( 'wpbc-settings' !== $page_tag ) || ( 'themes' !== $active_page_tab ) ) {
902 return;
903 }
904
905 if ( ! wpbc_is_mu_user_can_be_here( 'only_super_admin' ) || ! current_user_can( wpbc_settings_themes__get_manage_cap() ) ) {
906 return;
907 }
908 ?>
909 <div class="wpbc_ui_el__buttons_group wpbc_themes__top_toolbar_group">
910 <a href="javascript:void(0);"
911 class="button button-primary wpbc_themes__top_btn_save"
912 data-wpbc-theme-save="1"
913 data-wpbc-u-busy-text="<?php esc_attr_e( 'Saving', 'booking' ); ?>...">
914 <i class="menu_icon icon-1x wpbc-bi-check2-circle"></i>
915 <span class="in-button-text">&nbsp;&nbsp;<?php esc_html_e( 'Save Changes', 'booking' ); ?></span>
916 </a>
917 </div>
918 <?php
919 }
920 add_action( 'wpbc_ui_el__top_nav__content_end', 'wpbc_settings_themes__top_toolbar__show_save_button', 20, 3 );
921
922 /**
923 * Block direct access for regular users in MultiUser context.
924 *
925 * @param bool $is_show_this_page Whether to show page.
926 * @param string $page_tag Current page.
927 * @param string $active_page_tab Active tab.
928 * @param string $active_page_subtab Active subtab.
929 *
930 * @return bool
931 */
932 function wpbc_settings_themes__check_showing_page( $is_show_this_page, $page_tag, $active_page_tab, $active_page_subtab ) {
933
934 if ( ( 'wpbc-settings' === $page_tag ) && ( 'themes' === $active_page_tab ) && ( ! wpbc_is_mu_user_can_be_here( 'only_super_admin' ) || ! current_user_can( wpbc_settings_themes__get_manage_cap() ) ) ) {
935 return false;
936 }
937
938 return $is_show_this_page;
939 }
940 add_filter( 'wpbc_before_showing_settings_page_is_show_page', 'wpbc_settings_themes__check_showing_page', 20, 4 );
941
942 /**
943 * Appearance / Theme tab.
944 */
945 class WPBC_Page_Settings_Themes extends WPBC_Page_Structure {
946
947 /**
948 * Whether settings were saved during this request.
949 *
950 * @var bool
951 */
952 private $is_updated = false;
953
954 /**
955 * Menu slug.
956 *
957 * @return string
958 */
959 public function in_page() {
960
961 if ( ! wpbc_is_mu_user_can_be_here( 'only_super_admin' ) || ! current_user_can( wpbc_settings_themes__get_manage_cap() ) ) {
962 return (string) wp_rand( 100000, 1000000 );
963 }
964
965 return 'wpbc-settings';
966 }
967
968 /**
969 * Register tab.
970 *
971 * @return array
972 */
973 public function tabs() {
974
975 $tabs = array();
976
977 $tabs['themes'] = array(
978 'is_show_top_path' => true,
979 'right_vertical_sidebar__is_show' => true,
980 'right_vertical_sidebar__default_view_mode' => '',
981 'right_vertical_sidebar_compact__is_show' => true,
982 'left_navigation__default_view_mode' => 'compact',
983 'top_path_title' => __( 'Appearance', 'booking' ) . ' / ' . __( 'Theme', 'booking' ),
984 'title' => __( 'Appearance', 'booking' ) . ' / ' . __( 'Theme', 'booking' ) .
985 '<span class="wpbc_new_label" style="margin-left: auto;">' . esc_html__( 'New', 'booking' ) . '</span>',
986 'hint' => __( 'Preview and configure the booking form theme, calendar skin, and time slot appearance.', 'booking' ),
987 'page_title' => __( 'Appearance', 'booking' ) . ' / ' . __( 'Theme', 'booking' ),
988 'link' => '',
989 'position' => '',
990 'css_classes' => 'wpbc_top_tab__themes',
991 'icon' => '',
992 'font_icon' => 'wpbc-bi-palette-fill',
993 'font_icon_right' => '',
994 'default' => false,
995 'disabled' => false,
996 'hided' => false,
997 'subtabs' => array(),
998 'folder_style' => 'order:94;',
999 );
1000
1001 return $tabs;
1002 }
1003
1004 /**
1005 * Save settings.
1006 *
1007 * @return void
1008 */
1009 public function maybe_update() {
1010
1011 $form_name = 'wpbc_settings_themes_form';
1012
1013 // phpcs:ignore WordPress.Security.NonceVerification.Missing
1014 if ( ! isset( $_POST[ 'is_form_submitted_' . $form_name ] ) ) {
1015 return;
1016 }
1017
1018 check_admin_referer( 'wpbc_settings_page_' . $form_name );
1019
1020 if ( ! wpbc_is_mu_user_can_be_here( 'only_super_admin' ) || ! current_user_can( wpbc_settings_themes__get_manage_cap() ) ) {
1021 return;
1022 }
1023
1024 $cleaned_data = wpbc_settings_themes__validate_data( $_POST ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1025 wpbc_settings_themes__update_settings( $cleaned_data );
1026
1027 $this->is_updated = true;
1028 }
1029
1030 /**
1031 * Right compact sidebar tabs.
1032 *
1033 * @return void
1034 */
1035 public function right_sidebar_compact_content() {
1036
1037 WPBC_UI_Sidebar_Panels::render_rightbar_tabs(
1038 array(
1039 array(
1040 'id' => 'wpbc_tab_theme_settings',
1041 'panel_id' => 'wpbc_theme__inspector_settings',
1042 'title' => __( 'Settings', 'booking' ),
1043 'icon' => 'wpbc_icn_tune',
1044 'selected' => true,
1045 ),
1046 array(
1047 'id' => 'wpbc_tab_theme_notes',
1048 'panel_id' => 'wpbc_theme__inspector_notes',
1049 'title' => __( 'Notes', 'booking' ),
1050 'icon' => 'wpbc-bi-info-circle',
1051 ),
1052 ),
1053 array(
1054 'aria_label' => __( 'Appearance Panels', 'booking' ),
1055 'context' => 'settings_themes',
1056 'class' => 'wpbc_theme_rightbar_tabs',
1057 )
1058 );
1059 }
1060
1061 /**
1062 * Right sidebar panels.
1063 *
1064 * @return void
1065 */
1066 public function right_sidebar_content() {
1067 ?>
1068 <div class="wpbc_bfb__panel--library wpbc_rightbar_palette wpbc_theme_rightbar_panels">
1069 <?php
1070 WPBC_UI_Sidebar_Panels::render_panel(
1071 array(
1072 'id' => 'wpbc_theme__inspector_settings',
1073 'labelledby' => 'wpbc_tab_theme_settings',
1074 'class' => 'wpbc_theme__inspector_settings',
1075 ),
1076 array( $this, 'right_panel_settings_content' )
1077 );
1078
1079 WPBC_UI_Sidebar_Panels::render_panel(
1080 array(
1081 'id' => 'wpbc_theme__inspector_notes',
1082 'labelledby' => 'wpbc_tab_theme_notes',
1083 'class' => 'wpbc_theme__inspector_notes',
1084 'hidden' => true,
1085 ),
1086 array( $this, 'right_panel_notes_content' )
1087 );
1088 ?>
1089 </div>
1090 <?php
1091 }
1092
1093 /**
1094 * Settings panel content.
1095 *
1096 * @return void
1097 */
1098 public function right_panel_settings_content() {
1099
1100 $form_name = 'wpbc_settings_themes_form';
1101 $current_settings = wpbc_settings_themes__get_settings_response();
1102 $form_theme_options = wpbc_settings_themes__get_form_theme_options();
1103 $calendar_skin_options = wpbc_settings_themes__get_calendar_skin_options_for_select();
1104 $time_skin_options = wpbc_settings_themes__get_time_picker_skin_options();
1105
1106 WPBC_UI_Sidebar_Panels::render_inspector_header( __( 'Appearance', 'booking' ) . ' / ' . __( 'Theme', 'booking' ), __( 'Visual settings for the booking form and calendar preview.', 'booking' ) );
1107 ?>
1108 <form method="post" id="<?php echo esc_attr( $form_name ); ?>" class="wpbc_theme_settings_form" data-wpbc-theme-settings-form="1">
1109 <?php wp_nonce_field( 'wpbc_settings_page_' . $form_name ); ?>
1110 <input type="hidden" name="is_form_submitted_<?php echo esc_attr( $form_name ); ?>" value="1" />
1111 <div class="wpbc_bfb__inspector__body wpbc_theme_inspector_body">
1112 <?php
1113 WPBC_UI_Sidebar_Panels::render_collapsible_group(
1114 array(
1115 'id' => 'wpbc_theme_form_group',
1116 'group' => 'settings-theme-form',
1117 'title' => __( 'Form Theme', 'booking' ),
1118 'open' => true,
1119 ),
1120 function () use ( $form_theme_options, $current_settings ) {
1121 ?>
1122 <div class="wpbc_theme_choice_grid">
1123 <?php foreach ( $form_theme_options as $theme_value => $theme_title ) : ?>
1124 <label class="wpbc_theme_choice <?php echo ( (string) $current_settings['booking_form_theme'] === (string) $theme_value ) ? 'is-selected' : ''; ?>">
1125 <input type="radio" name="booking_form_theme" value="<?php echo esc_attr( $theme_value ); ?>" <?php checked( (string) $current_settings['booking_form_theme'], (string) $theme_value ); ?> />
1126 <span class="wpbc_theme_choice_swatch <?php echo esc_attr( sanitize_html_class( $theme_value ) ); ?>"></span>
1127 <span class="wpbc_theme_choice_label"><?php echo esc_html( $theme_title ); ?></span>
1128 </label>
1129 <?php endforeach; ?>
1130 </div>
1131 <p class="wpbc_theme_description"><?php esc_html_e( 'The form theme changes the booking form surface and can also guide matching calendar and time slot skins.', 'booking' ); ?></p>
1132 <?php
1133 }
1134 );
1135
1136 WPBC_UI_Sidebar_Panels::render_collapsible_group(
1137 array(
1138 'id' => 'wpbc_theme_calendar_group',
1139 'group' => 'settings-theme-calendar',
1140 'title' => __( 'Calendar Skin', 'booking' ),
1141 'open' => true,
1142 ),
1143 function () use ( $calendar_skin_options, $current_settings ) {
1144 ?>
1145 <div class="wpbc_theme_field_row">
1146 <label class="wpbc_theme_field_label" for="booking_skin"><?php esc_html_e( 'Calendar Skin', 'booking' ); ?></label>
1147 <div class="wpbc_ajx_toolbar wpbc_no_borders wpbc_theme_skin_toolbar">
1148 <div class="ui_container">
1149 <div class="ui_group">
1150 <div class="ui_element ui_nowrap">
1151 <?php
1152 if ( function_exists( 'wpbc_flex_select' ) ) {
1153 wpbc_flex_select(
1154 array(
1155 'id' => 'booking_skin',
1156 'name' => 'booking_skin',
1157 'label' => '',
1158 'class' => 'js-wpbc-bfb-calendar-skin wpbc_radio__set_days_customize_plugin',
1159 'value' => $current_settings['booking_skin'],
1160 'attr' => array( 'data-wpbc-theme-calendar-skin' => '1' ),
1161 'options' => $calendar_skin_options,
1162 )
1163 );
1164 } else {
1165 wpbc_settings_themes__render_select(
1166 'booking_skin',
1167 $calendar_skin_options,
1168 $current_settings['booking_skin'],
1169 array(
1170 'id' => 'booking_skin',
1171 'class' => 'js-wpbc-bfb-calendar-skin wpbc_radio__set_days_customize_plugin',
1172 'data_attrs' => array( 'data-wpbc-theme-calendar-skin' => '1' ),
1173 )
1174 );
1175 }
1176 $is_apply_rotating_icon = false;
1177 if ( function_exists( 'wpbc_smpl_form__ui__selectbox_prior_btn' ) ) {
1178 wpbc_smpl_form__ui__selectbox_prior_btn( 'booking_skin', $is_apply_rotating_icon );
1179 }
1180 if ( function_exists( 'wpbc_smpl_form__ui__selectbox_next_btn' ) ) {
1181 wpbc_smpl_form__ui__selectbox_next_btn( 'booking_skin', $is_apply_rotating_icon );
1182 }
1183 ?>
1184 </div>
1185 </div>
1186 </div>
1187 </div>
1188 </div>
1189 <?php
1190 }
1191 );
1192
1193 WPBC_UI_Sidebar_Panels::render_collapsible_group(
1194 array(
1195 'id' => 'wpbc_theme_time_slots_group',
1196 'group' => 'settings-theme-time-slots',
1197 'title' => __( 'Time Slot Appearance', 'booking' ),
1198 'open' => false,
1199 ),
1200 function () use ( $time_skin_options, $current_settings ) {
1201 ?>
1202 <div class="wpbc_theme_field_row">
1203 <label class="wpbc_theme_field_label" for="booking_timeslot_picker_skin"><?php esc_html_e( 'Time Picker Skin', 'booking' ); ?></label>
1204 <?php
1205 wpbc_settings_themes__render_select(
1206 'booking_timeslot_picker_skin',
1207 $time_skin_options,
1208 $current_settings['booking_timeslot_picker_skin'],
1209 array(
1210 'id' => 'booking_timeslot_picker_skin',
1211 'data_attrs' => array(
1212 'data-wpbc-theme-time-skin' => '1',
1213 'data-wpbc-theme-preview-notice' => 'form',
1214 ),
1215 )
1216 );
1217 ?>
1218 </div>
1219 <label class="wpbc_theme_switch wpbc_theme_switch_card">
1220 <input type="checkbox" name="booking_timeslot_picker" value="On" data-wpbc-theme-preview-notice="form" <?php checked( $current_settings['booking_timeslot_picker'], 'On' ); ?> />
1221 <span class="wpbc_theme_switch_control" aria-hidden="true"><span class="wpbc_theme_switch_knob"></span></span>
1222 <span class="wpbc_theme_switch_label"><?php esc_html_e( 'Show time slots as a time picker instead of a select box.', 'booking' ); ?></span>
1223 </label>
1224 <?php
1225 }
1226 );
1227 ?>
1228 </div>
1229 </form>
1230 <?php
1231 }
1232
1233 /**
1234 * Notes panel content.
1235 *
1236 * @return void
1237 */
1238 public function right_panel_notes_content() {
1239
1240 WPBC_UI_Sidebar_Panels::render_inspector_header( __( 'Notes', 'booking' ), __( 'How these appearance settings are applied.', 'booking' ) );
1241 ?>
1242 <div class="wpbc_bfb__inspector__body wpbc_theme_inspector_body">
1243 <div class="wpbc_theme_notice">
1244 <strong><?php esc_html_e( 'Note', 'booking' ); ?>!</strong>
1245 <?php esc_html_e( 'These options apply to front-end booking calendars and forms. The preview uses the selected booking resource from the toolbar.', 'booking' ); ?>
1246 </div>
1247 </div>
1248 <?php
1249 }
1250
1251 /**
1252 * Show page content.
1253 *
1254 * @return void|false
1255 */
1256 public function content() {
1257
1258 do_action( 'wpbc_hook_settings_page_header', 'page_settings_themes' );
1259
1260 if ( ! wpbc_is_mu_user_can_be_here( 'only_super_admin' ) || ! current_user_can( wpbc_settings_themes__get_manage_cap() ) ) {
1261 return false;
1262 }
1263
1264 if ( function_exists( 'wpbc_js_for_bookings_page' ) ) {
1265 wpbc_js_for_bookings_page();
1266 }
1267
1268 if ( $this->is_updated ) {
1269 wpbc_show_changes_saved_message();
1270 }
1271
1272 $resource_id = wpbc_settings_themes__get_preview_resource_id();
1273 $months_count = wpbc_settings_themes__get_preview_months_count();
1274 $preview_mode = wpbc_settings_themes__get_preview_mode();
1275 $custom_booking_form = wpbc_settings_themes__get_custom_booking_form();
1276 $resources = wpbc_settings_themes__get_resources();
1277 $form_options = wpbc_settings_themes__get_booking_form_options();
1278 $is_free_version = ! class_exists( 'wpdev_bk_personal' );
1279 ?>
1280 <div class="wpbc_theme_page wpdevelop" data-wpbc-theme-page="1" data-wpbc-theme-resource-id="<?php echo esc_attr( $resource_id ); ?>">
1281 <form method="get" class="wpbc_theme_toolbar wpbc_ts_toolbar wpbc_theme_preview_controls" data-wpbc-theme-preview-toolbar="1">
1282 <input type="hidden" name="page" value="wpbc-settings" />
1283 <input type="hidden" name="tab" value="themes" />
1284 <div class="wpbc_ts_control wpbc_theme_control_resource">
1285 <label for="wpbc_theme_resource_id"><?php esc_html_e( 'Booking resource', 'booking' ); ?></label>
1286 <?php if ( $is_free_version ) : ?>
1287 <input type="hidden" id="wpbc_theme_resource_id" name="resource_id" value="<?php echo esc_attr( $resource_id ); ?>" />
1288 <div class="wpbc_theme_toolbar_value">
1289 <i class="menu_icon icon-1x wpbc-bi-calendar2-day"></i>
1290 <span><?php echo esc_html( ! empty( $resources[0]['title'] ) ? $resources[0]['title'] : __( 'Default booking resource', 'booking' ) ); ?></span>
1291 </div>
1292 <?php
1293 $resource_dismiss_id = wpbc_settings_themes__get_premium_option_dismiss_id( 'booking_resources' );
1294 if ( wpbc_settings_themes__is_dismissed_visible( $resource_dismiss_id ) ) :
1295 ?>
1296 <div id="<?php echo esc_attr( $resource_dismiss_id ); ?>" class="wpbc_theme_upgrade_hint">
1297 <a class="wpbc_pro_label" href="<?php echo esc_url( 'https://wpbookingcalendar.com/features/' ); ?>" target="_blank">Pro</a>
1298 <?php wpbc_settings_themes__render_dismiss_button( $resource_dismiss_id ); ?>
1299 <span><?php esc_html_e( 'The Free version has one default booking resource. To have multiple resources, please upgrade to a premium version.', 'booking' ); ?></span>
1300 </div>
1301 <?php endif; ?>
1302 <?php else : ?>
1303 <select id="wpbc_theme_resource_id" name="resource_id">
1304 <?php foreach ( $resources as $resource ) : ?>
1305 <option value="<?php echo esc_attr( $resource['id'] ); ?>" <?php selected( $resource_id, (int) $resource['id'] ); ?>><?php echo esc_html( $resource['title'] ); ?></option>
1306 <?php endforeach; ?>
1307 </select>
1308 <?php endif; ?>
1309 </div>
1310 <div class="wpbc_ts_control wpbc_theme_control_months">
1311 <label for="wpbc_theme_months_count"><?php esc_html_e( 'Months', 'booking' ); ?></label>
1312 <select id="wpbc_theme_months_count" name="months_count">
1313 <?php foreach ( array( 1, 2, 3, 4, 6, 12 ) as $month_option ) : ?>
1314 <option value="<?php echo esc_attr( $month_option ); ?>" <?php selected( $months_count, $month_option ); ?>><?php echo esc_html( $month_option ); ?></option>
1315 <?php endforeach; ?>
1316 </select>
1317 </div>
1318 <div class="wpbc_ts_control wpbc_theme_control_preview_mode">
1319 <label for="wpbc_theme_preview_mode"><?php esc_html_e( 'Preview', 'booking' ); ?></label>
1320 <select id="wpbc_theme_preview_mode" name="preview_mode">
1321 <?php foreach ( wpbc_settings_themes__get_preview_mode_options() as $mode_value => $mode_title ) : ?>
1322 <option value="<?php echo esc_attr( $mode_value ); ?>" <?php selected( $preview_mode, $mode_value ); ?>><?php echo esc_html( $mode_title ); ?></option>
1323 <?php endforeach; ?>
1324 </select>
1325 </div>
1326 <div class="wpbc_ts_control wpbc_theme_control_form <?php echo ( 'form' === $preview_mode ) ? 'is-visible' : ''; ?>" data-wpbc-theme-form-control="1">
1327 <label for="wpbc_theme_custom_form"><?php esc_html_e( 'Booking Form', 'booking' ); ?></label>
1328 <select id="wpbc_theme_custom_form" name="custom_booking_form">
1329 <?php foreach ( $form_options as $form_value => $form_title ) : ?>
1330 <option value="<?php echo esc_attr( $form_value ); ?>" <?php selected( $custom_booking_form, $form_value ); ?>><?php echo esc_html( $form_title ); ?></option>
1331 <?php endforeach; ?>
1332 </select>
1333 </div>
1334 </form>
1335 <?php wpbc_settings_themes__render_calendar_preview( $resource_id, $months_count, array(), $preview_mode, $custom_booking_form ); ?>
1336 <div class="wpbc_theme_calendar_notes" data-wpbc-theme-calendar-notes="1">
1337 <div class="wpbc_ts_hint wpbc_theme_hint_bar">
1338 <span class="wpbc_icn_info_outline"></span>
1339 <?php esc_html_e( 'Preview the selected appearance settings before saving them for front-end booking forms.', 'booking' ); ?>
1340 </div>
1341 </div>
1342 </div>
1343 <?php
1344
1345 do_action( 'wpbc_hook_settings_page_footer', 'page_settings_themes' );
1346 }
1347 }
1348 add_action( 'wpbc_menu_created', array( new WPBC_Page_Settings_Themes(), '__construct' ) );
1349