$value ) { $key = sanitize_key( $key ); if ( in_array( $key, array( 'page', 'tab' ), true ) || is_array( $value ) ) { continue; } $args[ $key ] = sanitize_text_field( $value ); } $url = function_exists( 'wpbc_get_settings_themes_url' ) ? wpbc_get_settings_themes_url() : admin_url( 'admin.php?page=wpbc-settings&tab=themes' ); wp_safe_redirect( add_query_arg( $args, $url ) ); exit; } add_action( 'admin_init', 'wpbc_settings_themes__redirect_legacy_color_themes_url', 1 ); /** * Enqueue CSS for Appearance / Theme. * * @param string $where_to_load Where assets are loaded. * * @return void */ function wpbc_settings_themes_enqueue_css_files( $where_to_load ) { if ( ( ! is_admin() ) || ( ! in_array( $where_to_load, array( 'admin', 'both' ), true ) ) ) { return; } if ( ! wpbc_settings_themes__is_page() ) { return; } wp_enqueue_style( 'wpbc-settings-themes-page', trailingslashit( plugins_url( '', __FILE__ ) ) . '_out/settings_themes_page.css', array( 'wpbc-calendar', 'wpbc-all-admin' ), WP_BK_VERSION_NUM ); wp_enqueue_style( 'coloris', wpbc_plugin_url( '/vendors/coloris/dist/coloris.min.css' ), array(), WP_BK_VERSION_NUM ); } add_action( 'wpbc_enqueue_css_files', 'wpbc_settings_themes_enqueue_css_files', 66 ); /** * Enqueue JS for Appearance / Theme. * * @param string $where_to_load Where assets are loaded. * * @return void */ function wpbc_settings_themes_enqueue_js_files( $where_to_load ) { if ( ( ! is_admin() ) || ( ! in_array( $where_to_load, array( 'admin', 'both' ), true ) ) ) { return; } if ( ! wpbc_settings_themes__is_page() ) { return; } wp_enqueue_script( 'coloris', wpbc_plugin_url( '/vendors/coloris/dist/coloris.min.js' ), array(), WP_BK_VERSION_NUM, array( 'in_footer' => WPBC_JS_IN_FOOTER ) ); wp_enqueue_script( 'wpbc-settings-themes-page', trailingslashit( plugins_url( '', __FILE__ ) ) . '_out/settings_themes_page.js', array( 'jquery', 'wpbc_all', 'coloris' ), WP_BK_VERSION_NUM, array( 'in_footer' => WPBC_JS_IN_FOOTER ) ); wp_localize_script( 'wpbc-settings-themes-page', 'wpbc_settings_themes_page', array( 'ajax_url' => admin_url( 'admin-ajax.php' ), 'plugin_url' => trailingslashit( WPBC_PLUGIN_URL ), 'nonce' => wp_create_nonce( 'wpbc_settings_themes_ajax_nonce' ), 'action' => 'WPBC_AJX_SETTINGS_THEMES_SAVE', 'preview_action' => 'WPBC_AJX_SETTINGS_THEMES_PREVIEW', 'settings' => wpbc_settings_themes__get_settings_response(), 'form_style_presets' => wpbc_bfb_settings__get_form_style_presets(), 'form_style_css_var_names' => wpbc_bfb_settings__get_form_style_css_var_names(), 'custom_form_style_defaults' => wpbc_bfb_settings__get_default_custom_form_style_options(), 'form_accent_defaults' => wpbc_bfb_settings__get_default_form_accent_options(), 'days_selection' => wpbc_settings_themes__get_days_selection_response(), 'i18n' => array( 'saving' => __( 'Saving', 'booking' ), 'saved' => __( 'Appearance settings updated.', 'booking' ), 'save_failed' => __( 'Unable to save appearance settings.', 'booking' ), 'preview_failed' => __( 'Unable to refresh calendar preview.', 'booking' ), 'security_error' => __( 'Security check failed.', 'booking' ), 'loading' => __( 'Loading', 'booking' ), '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' ), 'form_preview_option_notice' => __( 'This option is visible in the Booking form preview. Switch Preview to Booking form to inspect it.', 'booking' ), ), ) ); } add_action( 'wpbc_enqueue_js_files', 'wpbc_settings_themes_enqueue_js_files', 66 ); /** * Print tooltip initializer for Appearance / Theme. * * @return void */ function wpbc_settings_themes_print_tooltip_js() { if ( ! wpbc_settings_themes__is_page() ) { return; } if ( function_exists( 'wpbc_bs_javascript_tooltips' ) ) { wpbc_bs_javascript_tooltips(); } } add_action( 'admin_footer', 'wpbc_settings_themes_print_tooltip_js', 67 ); /** * Get day-selection settings in the same normalized shape used by calendar boot code. * * @return array */ function wpbc_settings_themes__get_days_selection_response() { $days_selection = array( 'days_select_mode' => 'multiple', 'fixed__days_num' => 0, 'fixed__week_days__start' => '-1', 'dynamic__days_min' => 0, 'dynamic__days_max' => 0, 'dynamic__days_specific' => '', 'dynamic__week_days__start' => '-1', ); if ( function_exists( 'wpbc__calendar__js_params__get_days_selection_arr' ) ) { $days_selection = wp_parse_args( wpbc__calendar__js_params__get_days_selection_arr(), $days_selection ); } return array( 'days_select_mode' => (string) $days_selection['days_select_mode'], 'fixed__days_num' => (int) $days_selection['fixed__days_num'], 'fixed__week_days__start' => (string) $days_selection['fixed__week_days__start'], 'dynamic__days_min' => (int) $days_selection['dynamic__days_min'], 'dynamic__days_max' => (int) $days_selection['dynamic__days_max'], 'dynamic__days_specific' => (string) $days_selection['dynamic__days_specific'], 'dynamic__week_days__start' => (string) $days_selection['dynamic__week_days__start'], ); } /** * Get resource options. * * @return array */ function wpbc_settings_themes__get_resources() { if ( function_exists( 'wpbc_availability_general__get_resources' ) ) { return wpbc_availability_general__get_resources(); } $resources = array(); if ( function_exists( 'wpbc_ajx_get_sorted_booking_resources_arr' ) && function_exists( 'wpbc_ajx_get_all_booking_resources_arr' ) ) { $resource_rows = wpbc_ajx_get_sorted_booking_resources_arr( wpbc_ajx_get_all_booking_resources_arr() ); foreach ( $resource_rows as $resource ) { $resources[] = array( 'id' => isset( $resource['booking_type_id'] ) ? (int) $resource['booking_type_id'] : 1, 'title' => isset( $resource['title'] ) ? $resource['title'] : __( 'Booking resource', 'booking' ), ); } } if ( empty( $resources ) ) { $resources[] = array( 'id' => function_exists( 'wpbc_get_default_resource' ) ? (int) wpbc_get_default_resource() : 1, 'title' => __( 'Booking resource', 'booking' ), ); } return $resources; } /** * Get capability required to manage Appearance / Theme. * * @return string */ function wpbc_settings_themes__get_manage_cap() { $min_user_role = get_bk_option( 'booking_user_role_settings' ); $capability = array( 'administrator' => 'activate_plugins', 'editor' => 'publish_pages', 'author' => 'publish_posts', 'contributor' => 'edit_posts', 'subscriber' => 'read', ); return isset( $capability[ $min_user_role ] ) ? $capability[ $min_user_role ] : 'manage_options'; } /** * Check if a Theme Settings upsell row is visible for current user. * * @param string $dismiss_id Dismiss ID. * * @return bool */ function wpbc_settings_themes__is_dismissed_visible( $dismiss_id ) { if ( wpbc_is_this_demo() ) { return true; } return ! function_exists( 'wpbc_is_dismissed_panel_visible' ) || wpbc_is_dismissed_panel_visible( $dismiss_id ); } /** * Get dismiss ID for Theme Settings premium option. * * @param string $option_name Option name. * * @return string */ function wpbc_settings_themes__get_premium_option_dismiss_id( $option_name ) { return 'wpbc_is_dismissed__theme_settings__' . sanitize_key( $option_name ); } /** * Render compact dismiss button for Theme Settings premium hints. * * @param string $dismiss_id Dismiss ID. * * @return void */ function wpbc_settings_themes__render_dismiss_button( $dismiss_id ) { if ( wpbc_is_this_demo() || ! function_exists( 'wpbc_is_dismissed' ) ) { return; } ?> '×', 'hint' => __( 'Hide this option', 'booking' ), 'css' => 'float:none;margin-left:4px;', ) ); ?> __( 'Calendar only', 'booking' ), 'form' => __( 'Booking form', 'booking' ), ); } /** * Sanitize preview mode. * * @param string $preview_mode Preview mode. * * @return string */ function wpbc_settings_themes__sanitize_preview_mode( $preview_mode ) { $preview_mode = sanitize_key( (string) $preview_mode ); return array_key_exists( $preview_mode, wpbc_settings_themes__get_preview_mode_options() ) ? $preview_mode : 'form'; } /** * Get preview mode from request. * * @return string */ function wpbc_settings_themes__get_preview_mode() { // phpcs:ignore WordPress.Security.NonceVerification.Recommended $preview_mode = isset( $_REQUEST['preview_mode'] ) ? sanitize_key( wp_unslash( $_REQUEST['preview_mode'] ) ) : 'form'; return wpbc_settings_themes__sanitize_preview_mode( $preview_mode ); } /** * Get booking form options for preview. * * @return array */ function wpbc_settings_themes__get_booking_form_options() { $form_options = array( 'standard' => __( 'Standard booking form', 'booking' ), ); if ( class_exists( 'WPBC_FE_Custom_Form_Helper' ) ) { $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; $forms_list = WPBC_FE_Custom_Form_Helper::get_custom_booking_forms_list( array( 'include_standard' => true, 'owner_user_id' => $owner_user_id, 'statuses' => array( 'published' ), 'list_mode' => 'auto', ) ); if ( is_array( $forms_list ) ) { foreach ( $forms_list as $form_slug => $form_data ) { $form_slug = sanitize_text_field( (string) $form_slug ); if ( '' === $form_slug ) { continue; } $form_options[ $form_slug ] = isset( $form_data['title'] ) ? sanitize_text_field( (string) $form_data['title'] ) : $form_slug; } } } return $form_options; } /** * Sanitize custom booking form. * * @param string $custom_booking_form Custom booking form slug. * * @return string */ function wpbc_settings_themes__sanitize_custom_booking_form( $custom_booking_form ) { $custom_booking_form = sanitize_text_field( (string) $custom_booking_form ); $form_options = wpbc_settings_themes__get_booking_form_options(); return array_key_exists( $custom_booking_form, $form_options ) ? $custom_booking_form : 'standard'; } /** * Get custom booking form from request. * * @return string */ function wpbc_settings_themes__get_custom_booking_form() { // phpcs:ignore WordPress.Security.NonceVerification.Recommended $custom_booking_form = isset( $_REQUEST['custom_booking_form'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['custom_booking_form'] ) ) : 'standard'; return wpbc_settings_themes__sanitize_custom_booking_form( $custom_booking_form ); } /** * Get form theme options. * * @return array */ function wpbc_settings_themes__get_form_theme_options() { return array( '' => __( 'Light', 'booking' ), 'wpbc_theme_dark_1' => __( 'Dark', 'booking' ), ); } /** * Get booking form container preset options. * * @return array */ function wpbc_settings_themes__get_form_appearance_preset_options() { return array( 'bordered' => __( 'Bordered', 'booking' ), 'none' => __( 'No border', 'booking' ), 'soft' => __( 'Soft background', 'booking' ), 'custom' => __( 'Custom per form', 'booking' ), ); } /** * Get combined booking form style choices for the visual selector. * * @return array */ function wpbc_settings_themes__get_form_style_options() { return wpbc_bfb_settings__get_form_style_options(); } /** * Resolve the combined visual form style value from saved settings. * * @param string $theme Form theme option. * @param string $preset Form appearance preset option. * * @return string */ function wpbc_settings_themes__get_form_style_value( $theme, $preset ) { $theme = ( 'wpbc_theme_dark_1' === (string) $theme ) ? 'dark' : 'light'; $preset = (string) $preset; if ( 'custom' === $preset ) { return 'custom'; } if ( ! in_array( $preset, array( 'bordered', 'none', 'soft' ), true ) ) { $preset = 'bordered'; } return $theme . '_' . $preset; } /** * Map the combined visual form style value to existing saved options. * * @param string $style Combined style value. * @param string $current_theme Current theme fallback. * * @return array */ function wpbc_settings_themes__map_form_style_to_options( $style, $current_theme = '' ) { $style = sanitize_key( (string) $style ); $current_theme = ( 'wpbc_theme_dark_1' === (string) $current_theme ) ? 'wpbc_theme_dark_1' : ''; if ( 'custom' === $style ) { return array( 'booking_form_theme' => $current_theme, 'booking_form_appearance_preset' => 'custom', ); } $parts = explode( '_', $style ); $theme = ( isset( $parts[0] ) && 'dark' === $parts[0] ) ? 'wpbc_theme_dark_1' : ''; $preset = isset( $parts[1] ) ? (string) $parts[1] : 'bordered'; $preset = in_array( $preset, array( 'bordered', 'none', 'soft' ), true ) ? $preset : 'bordered'; return array( 'booking_form_theme' => $theme, 'booking_form_appearance_preset' => $preset, ); } /** * Get time picker skin options. * * @return array */ function wpbc_settings_themes__get_time_picker_skin_options() { $automatic_skin = '/css/time_picker_skins/form_style.css'; $timeslot_picker_skins_options = array(); $upload_dir = wp_upload_dir(); if ( function_exists( 'wpbc_dir_list' ) ) { $files_in_folder = wpbc_dir_list( array( WPBC_PLUGIN_DIR . '/css/time_picker_skins/', $upload_dir['basedir'] . '/wpbc_time_picker_skins/', ) ); foreach ( $files_in_folder as $skin_file ) { $skin_file[1] = str_replace( array( WPBC_PLUGIN_DIR, WPBC_PLUGIN_URL, $upload_dir['basedir'] ), '', $skin_file[1] ); $timeslot_picker_skins_options[ $skin_file[1] ] = $skin_file[2]; } } // Keep the integrated option first and give bundled skins readable labels. if ( file_exists( WPBC_PLUGIN_DIR . $automatic_skin ) ) { unset( $timeslot_picker_skins_options[ $automatic_skin ] ); $timeslot_picker_skins_options = array_merge( array( $automatic_skin => __( 'Automatic — Match Booking Form', 'booking' ), ), $timeslot_picker_skins_options ); } $bundled_skin_titles = array( '/css/time_picker_skins/light__24_8.css' => __( 'Light', 'booking' ), '/css/time_picker_skins/grey.css' => __( 'Grey', 'booking' ), '/css/time_picker_skins/black.css' => __( 'Black', 'booking' ), '/css/time_picker_skins/blue.css' => __( 'Blue', 'booking' ), '/css/time_picker_skins/green.css' => __( 'Green', 'booking' ), '/css/time_picker_skins/orange.css' => __( 'Orange', 'booking' ), '/css/time_picker_skins/marine.css' => __( 'Marine', 'booking' ), ); foreach ( $bundled_skin_titles as $skin_path => $skin_title ) { if ( isset( $timeslot_picker_skins_options[ $skin_path ] ) ) { $timeslot_picker_skins_options[ $skin_path ] = $skin_title; } } if ( empty( $timeslot_picker_skins_options ) ) { $default_options_values = wpbc_get_default_options(); $default_skin = isset( $default_options_values['booking_timeslot_picker_skin'] ) ? $default_options_values['booking_timeslot_picker_skin'] : $automatic_skin; $timeslot_picker_skins_options[ $default_skin ] = __( 'Default', 'booking' ); } return $timeslot_picker_skins_options; } /** * Normalize calendar skin option value to a relative path. * * @param string $skin_value Calendar skin value. * * @return string */ function wpbc_settings_themes__normalize_calendar_skin_value( $skin_value ) { $skin_value = (string) $skin_value; $upload_dir = wp_upload_dir(); $upload_url = ( ! empty( $upload_dir['baseurl'] ) ) ? $upload_dir['baseurl'] : ''; return str_replace( array( WPBC_PLUGIN_URL, $upload_url, ), '', $skin_value ); } /** * Get URL for a relative calendar skin path. * * @param string $relative_skin Relative skin path. * * @return string */ function wpbc_settings_themes__get_calendar_skin_url( $relative_skin ) { $relative_skin = wpbc_settings_themes__normalize_calendar_skin_value( $relative_skin ); $upload_dir = wp_upload_dir(); $upload_url = ( ! empty( $upload_dir['baseurl'] ) ) ? $upload_dir['baseurl'] : ''; if ( 0 === strpos( $relative_skin, '/wpbc_skins/' ) && ! empty( $upload_url ) ) { return $upload_url . $relative_skin; } return WPBC_PLUGIN_URL . $relative_skin; } /** * Build calendar skin options for selectbox with live-preview URL metadata. * * @return array */ function wpbc_settings_themes__get_calendar_skin_options_for_select() { $options = function_exists( 'wpbc_get_calendar_skin_options' ) ? wpbc_get_calendar_skin_options() : array(); foreach ( $options as $option_value => $option_label ) { if ( is_array( $option_label ) && ! empty( $option_label['optgroup'] ) ) { continue; } $relative_skin = wpbc_settings_themes__normalize_calendar_skin_value( $option_value ); $skin_url = wpbc_settings_themes__get_calendar_skin_url( $relative_skin ); if ( is_array( $option_label ) ) { $option_label['attr'] = ( isset( $option_label['attr'] ) && is_array( $option_label['attr'] ) ) ? $option_label['attr'] : array(); $option_label['attr']['data-wpbc-calendar-skin-url'] = $skin_url; $options[ $relative_skin ] = $option_label; } else { $options[ $relative_skin ] = array( 'title' => $option_label, 'attr' => array( 'data-wpbc-calendar-skin-url' => $skin_url, ), ); } if ( $relative_skin !== $option_value ) { unset( $options[ $option_value ] ); } } return $options; } /** * Get current settings prepared for JavaScript and AJAX responses. * * @return array */ function wpbc_settings_themes__get_settings_response() { $form_style = wpbc_bfb_settings__get_current_form_style(); $transition_values = wpbc_settings_themes__map_form_style_to_options( $form_style, '' ); $custom_values = wpbc_bfb_settings__get_custom_form_style_options(); $accent_values = wpbc_bfb_settings__get_form_accent_options(); return array_merge( array( 'booking_form_style' => $form_style, 'booking_form_theme' => $transition_values['booking_form_theme'], 'booking_form_appearance_preset' => $transition_values['booking_form_appearance_preset'], 'booking_form_appearance_background_color' => get_bk_option( 'booking_form_appearance_background_color' ) ? get_bk_option( 'booking_form_appearance_background_color' ) : '#ffffff', 'booking_form_appearance_border_color' => get_bk_option( 'booking_form_appearance_border_color' ) ? get_bk_option( 'booking_form_appearance_border_color' ) : '#cccccc', 'booking_form_appearance_border_width' => get_bk_option( 'booking_form_appearance_border_width' ) ? get_bk_option( 'booking_form_appearance_border_width' ) : '1px', 'booking_form_appearance_border_radius' => get_bk_option( 'booking_form_appearance_border_radius' ) ? get_bk_option( 'booking_form_appearance_border_radius' ) : '2px', 'booking_form_appearance_padding' => get_bk_option( 'booking_form_appearance_padding' ) ? get_bk_option( 'booking_form_appearance_padding' ) : '10px 30px', 'booking_skin' => wpbc_settings_themes__normalize_calendar_skin_value( get_bk_option( 'booking_skin' ) ), 'booking_timeslot_picker_skin' => get_bk_option( 'booking_timeslot_picker_skin' ), 'booking_timeslot_picker' => get_bk_option( 'booking_timeslot_picker' ), ), $custom_values, $accent_values ); } /** * Override option values while rendering the live Appearance / Theme preview. * * @param mixed $value Current filter value. * @param string $option Option name. * @param mixed $default Default option value. * * @return mixed */ function wpbc_settings_themes__preview_get_bk_option( $value, $option, $default ) { global $wpbc_settings_themes__preview_options; if ( is_array( $wpbc_settings_themes__preview_options ) && array_key_exists( $option, $wpbc_settings_themes__preview_options ) ) { return $wpbc_settings_themes__preview_options[ $option ]; } return $value; } add_bk_filter( 'wpdev_bk_get_option', 'wpbc_settings_themes__preview_get_bk_option' ); /** * Prepare option overrides for the live preview renderer. * * @param array $current_settings Current preview settings. * * @return array */ function wpbc_settings_themes__get_preview_option_overrides( $current_settings ) { $option_names = array( 'booking_form_style', 'booking_form_accent_enabled', 'booking_form_accent_color', 'booking_form_custom_background_color', 'booking_form_custom_border_color', 'booking_form_custom_border_width', 'booking_form_custom_border_radius', 'booking_form_custom_padding_vertical', 'booking_form_custom_padding_horizontal', 'booking_form_custom_text_color', 'booking_form_custom_field_background_color', 'booking_form_custom_field_text_color', 'booking_form_custom_field_border_color', 'booking_form_custom_button_background_color', 'booking_form_custom_button_text_color', 'booking_form_custom_button_border_color', 'booking_form_custom_button_hover_background_color', 'booking_form_custom_button_hover_text_color', 'booking_form_custom_button_hover_border_color', 'booking_form_custom_secondary_button_background_color', 'booking_form_custom_secondary_button_text_color', 'booking_form_custom_secondary_button_border_color', 'booking_form_custom_secondary_button_hover_background_color', 'booking_form_custom_secondary_button_hover_text_color', 'booking_form_custom_secondary_button_hover_border_color', 'booking_form_custom_button_border_width', 'booking_form_custom_button_border_radius', 'booking_skin', 'booking_timeslot_picker_skin', 'booking_timeslot_picker', ); $overrides = array(); foreach ( $option_names as $option_name ) { if ( array_key_exists( $option_name, $current_settings ) ) { $overrides[ $option_name ] = $current_settings[ $option_name ]; } } if ( isset( $overrides['booking_form_style'] ) ) { $style = wpbc_bfb_settings__sanitize_form_style( $overrides['booking_form_style'] ); $preset = wpbc_bfb_settings__get_form_style_preset( $style ); $legacy_theme = isset( $preset['theme_class'] ) ? sanitize_html_class( (string) $preset['theme_class'] ) : ''; $legacy_container = isset( $preset['container_style'] ) ? sanitize_key( (string) $preset['container_style'] ) : 'bordered'; $legacy_container = in_array( $legacy_container, array( 'bordered', 'none', 'soft', 'custom' ), true ) ? $legacy_container : 'bordered'; $overrides['booking_form_theme'] = $legacy_theme; $overrides['booking_form_appearance_preset'] = $legacy_container; } return $overrides; } /** * Validate posted Appearance / Theme settings. * * @param array $post_data Raw post data. * * @return array */ function wpbc_settings_themes__validate_data( $post_data ) { $default_options_values = wpbc_get_default_options(); $calendar_skin_options = wpbc_settings_themes__get_calendar_skin_options_for_select(); $time_skin_options = wpbc_settings_themes__get_time_picker_skin_options(); $custom_values = wpbc_bfb_settings__get_custom_form_style_options(); $accent_values = wpbc_bfb_settings__get_form_accent_options(); $cleaned = array_merge( array( 'booking_form_style' => isset( $default_options_values['booking_form_style'] ) ? wpbc_bfb_settings__sanitize_form_style( $default_options_values['booking_form_style'] ) : wpbc_bfb_settings__get_default_form_style(), 'booking_skin' => isset( $default_options_values['booking_skin'] ) ? $default_options_values['booking_skin'] : '', 'booking_timeslot_picker_skin' => isset( $default_options_values['booking_timeslot_picker_skin'] ) ? $default_options_values['booking_timeslot_picker_skin'] : '', 'booking_timeslot_picker' => isset( $default_options_values['booking_timeslot_picker'] ) ? $default_options_values['booking_timeslot_picker'] : 'Off', ), $custom_values, $accent_values ); if ( isset( $post_data['booking_form_style'] ) ) { $cleaned['booking_form_style'] = wpbc_bfb_settings__sanitize_form_style( wp_unslash( $post_data['booking_form_style'] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized } $cleaned['booking_form_accent_enabled'] = ( isset( $post_data['booking_form_accent_enabled'] ) && 'On' === sanitize_text_field( wp_unslash( $post_data['booking_form_accent_enabled'] ) ) ) ? 'On' : 'Off'; if ( isset( $post_data['booking_form_accent_color'] ) ) { $cleaned['booking_form_accent_color'] = wpbc_bfb_settings__sanitize_form_accent_color( sanitize_text_field( wp_unslash( $post_data['booking_form_accent_color'] ) ), WPBC_DEFAULT_FORM_ACCENT_COLOR ); } $sanitize_color = function ( $value, $fallback ) { $value = trim( sanitize_text_field( wp_unslash( $value ) ) ); if ( preg_match( '/^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i', $value ) || 'transparent' === $value ) { return $value; } return $fallback; }; $sanitize_length = function ( $value, $fallback ) { $value = trim( sanitize_text_field( wp_unslash( $value ) ) ); if ( preg_match( '/^\d+(?:\.\d+)?(?:px|rem|em|%)$/i', $value ) ) { return $value; } return $fallback; }; $sanitize_spacing = function ( $value, $fallback ) { $value = preg_replace( '/\s+/', ' ', trim( sanitize_text_field( wp_unslash( $value ) ) ) ); if ( '' === $value ) { return $fallback; } $parts = explode( ' ', $value ); if ( count( $parts ) < 1 || count( $parts ) > 4 ) { return $fallback; } foreach ( $parts as $part ) { if ( ! preg_match( '/^\d+(?:\.\d+)?(?:px|rem|em|%)$/i', $part ) ) { return $fallback; } } return implode( ' ', $parts ); }; if ( 'custom' === $cleaned['booking_form_style'] ) { if ( isset( $post_data['booking_form_custom_background_color'] ) ) { $cleaned['booking_form_custom_background_color'] = $sanitize_color( $post_data['booking_form_custom_background_color'], '#ffffff' ); } if ( isset( $post_data['booking_form_custom_border_color'] ) ) { $cleaned['booking_form_custom_border_color'] = $sanitize_color( $post_data['booking_form_custom_border_color'], '#cccccc' ); } if ( isset( $post_data['booking_form_custom_border_width'] ) ) { $cleaned['booking_form_custom_border_width'] = $sanitize_length( $post_data['booking_form_custom_border_width'], '1px' ); } if ( isset( $post_data['booking_form_custom_border_radius'] ) ) { $cleaned['booking_form_custom_border_radius'] = $sanitize_length( $post_data['booking_form_custom_border_radius'], '2px' ); } if ( isset( $post_data['booking_form_custom_padding_vertical'] ) ) { $cleaned['booking_form_custom_padding_vertical'] = $sanitize_length( $post_data['booking_form_custom_padding_vertical'], '10px' ); } if ( isset( $post_data['booking_form_custom_padding_horizontal'] ) ) { $cleaned['booking_form_custom_padding_horizontal'] = $sanitize_length( $post_data['booking_form_custom_padding_horizontal'], '30px' ); } if ( isset( $post_data['booking_form_custom_text_color'] ) ) { $cleaned['booking_form_custom_text_color'] = $sanitize_color( $post_data['booking_form_custom_text_color'], '#1d2327' ); } if ( isset( $post_data['booking_form_custom_field_background_color'] ) ) { $cleaned['booking_form_custom_field_background_color'] = $sanitize_color( $post_data['booking_form_custom_field_background_color'], '#ffffff' ); } if ( isset( $post_data['booking_form_custom_field_text_color'] ) ) { $cleaned['booking_form_custom_field_text_color'] = $sanitize_color( $post_data['booking_form_custom_field_text_color'], '#3c434a' ); } if ( isset( $post_data['booking_form_custom_field_border_color'] ) ) { $cleaned['booking_form_custom_field_border_color'] = $sanitize_color( $post_data['booking_form_custom_field_border_color'], '#cccccc' ); } if ( isset( $post_data['booking_form_custom_button_background_color'] ) ) { $cleaned['booking_form_custom_button_background_color'] = $sanitize_color( $post_data['booking_form_custom_button_background_color'], '#066aab' ); } if ( isset( $post_data['booking_form_custom_button_text_color'] ) ) { $cleaned['booking_form_custom_button_text_color'] = $sanitize_color( $post_data['booking_form_custom_button_text_color'], '#ffffff' ); } if ( isset( $post_data['booking_form_custom_button_border_color'] ) ) { $cleaned['booking_form_custom_button_border_color'] = $sanitize_color( $post_data['booking_form_custom_button_border_color'], '#066aab' ); } if ( isset( $post_data['booking_form_custom_button_hover_background_color'] ) ) { $cleaned['booking_form_custom_button_hover_background_color'] = $sanitize_color( $post_data['booking_form_custom_button_hover_background_color'], '#055589' ); } if ( isset( $post_data['booking_form_custom_button_hover_text_color'] ) ) { $cleaned['booking_form_custom_button_hover_text_color'] = $sanitize_color( $post_data['booking_form_custom_button_hover_text_color'], '#ffffff' ); } if ( isset( $post_data['booking_form_custom_button_hover_border_color'] ) ) { $cleaned['booking_form_custom_button_hover_border_color'] = $sanitize_color( $post_data['booking_form_custom_button_hover_border_color'], '#055589' ); } if ( isset( $post_data['booking_form_custom_secondary_button_background_color'] ) ) { $cleaned['booking_form_custom_secondary_button_background_color'] = $sanitize_color( $post_data['booking_form_custom_secondary_button_background_color'], '#fdfdfd' ); } if ( isset( $post_data['booking_form_custom_secondary_button_text_color'] ) ) { $cleaned['booking_form_custom_secondary_button_text_color'] = $sanitize_color( $post_data['booking_form_custom_secondary_button_text_color'], '#444444' ); } if ( isset( $post_data['booking_form_custom_secondary_button_border_color'] ) ) { $cleaned['booking_form_custom_secondary_button_border_color'] = $sanitize_color( $post_data['booking_form_custom_secondary_button_border_color'], '#eeeeee' ); } if ( isset( $post_data['booking_form_custom_secondary_button_hover_background_color'] ) ) { $cleaned['booking_form_custom_secondary_button_hover_background_color'] = $sanitize_color( $post_data['booking_form_custom_secondary_button_hover_background_color'], '#fdfdfd' ); } if ( isset( $post_data['booking_form_custom_secondary_button_hover_text_color'] ) ) { $cleaned['booking_form_custom_secondary_button_hover_text_color'] = $sanitize_color( $post_data['booking_form_custom_secondary_button_hover_text_color'], '#444444' ); } if ( isset( $post_data['booking_form_custom_secondary_button_hover_border_color'] ) ) { $cleaned['booking_form_custom_secondary_button_hover_border_color'] = $sanitize_color( $post_data['booking_form_custom_secondary_button_hover_border_color'], '#4d91cd' ); } if ( isset( $post_data['booking_form_custom_button_border_width'] ) ) { $cleaned['booking_form_custom_button_border_width'] = $sanitize_length( $post_data['booking_form_custom_button_border_width'], '1px' ); } if ( isset( $post_data['booking_form_custom_button_border_radius'] ) ) { $cleaned['booking_form_custom_button_border_radius'] = $sanitize_length( $post_data['booking_form_custom_button_border_radius'], '3px' ); } } if ( isset( $post_data['booking_skin'] ) ) { $value = wpbc_settings_themes__normalize_calendar_skin_value( sanitize_text_field( wp_unslash( $post_data['booking_skin'] ) ) ); if ( array_key_exists( $value, $calendar_skin_options ) ) { $cleaned['booking_skin'] = $value; } } if ( isset( $post_data['booking_timeslot_picker_skin'] ) ) { $value = sanitize_text_field( wp_unslash( $post_data['booking_timeslot_picker_skin'] ) ); if ( array_key_exists( $value, $time_skin_options ) ) { $cleaned['booking_timeslot_picker_skin'] = $value; } } $timeslot_picker_value = isset( $post_data['booking_timeslot_picker'] ) ? sanitize_text_field( wp_unslash( $post_data['booking_timeslot_picker'] ) ) : ''; $cleaned['booking_timeslot_picker'] = ( 'On' === $timeslot_picker_value ) ? 'On' : 'Off'; return $cleaned; } /** * Update Appearance / Theme settings. * * @param array $cleaned_data Cleaned settings. * * @return void */ function wpbc_settings_themes__update_settings( $cleaned_data ) { update_bk_option( 'booking_form_style', $cleaned_data['booking_form_style'] ); update_bk_option( 'booking_form_accent_enabled', $cleaned_data['booking_form_accent_enabled'] ); update_bk_option( 'booking_form_accent_color', $cleaned_data['booking_form_accent_color'] ); update_bk_option( 'booking_form_custom_background_color', $cleaned_data['booking_form_custom_background_color'] ); update_bk_option( 'booking_form_custom_border_color', $cleaned_data['booking_form_custom_border_color'] ); update_bk_option( 'booking_form_custom_border_width', $cleaned_data['booking_form_custom_border_width'] ); update_bk_option( 'booking_form_custom_border_radius', $cleaned_data['booking_form_custom_border_radius'] ); update_bk_option( 'booking_form_custom_padding_vertical', $cleaned_data['booking_form_custom_padding_vertical'] ); update_bk_option( 'booking_form_custom_padding_horizontal', $cleaned_data['booking_form_custom_padding_horizontal'] ); update_bk_option( 'booking_form_custom_text_color', $cleaned_data['booking_form_custom_text_color'] ); update_bk_option( 'booking_form_custom_field_background_color', $cleaned_data['booking_form_custom_field_background_color'] ); update_bk_option( 'booking_form_custom_field_text_color', $cleaned_data['booking_form_custom_field_text_color'] ); update_bk_option( 'booking_form_custom_field_border_color', $cleaned_data['booking_form_custom_field_border_color'] ); update_bk_option( 'booking_form_custom_button_background_color', $cleaned_data['booking_form_custom_button_background_color'] ); update_bk_option( 'booking_form_custom_button_text_color', $cleaned_data['booking_form_custom_button_text_color'] ); update_bk_option( 'booking_form_custom_button_border_color', $cleaned_data['booking_form_custom_button_border_color'] ); update_bk_option( 'booking_form_custom_button_hover_background_color', $cleaned_data['booking_form_custom_button_hover_background_color'] ); update_bk_option( 'booking_form_custom_button_hover_text_color', $cleaned_data['booking_form_custom_button_hover_text_color'] ); update_bk_option( 'booking_form_custom_button_hover_border_color', $cleaned_data['booking_form_custom_button_hover_border_color'] ); update_bk_option( 'booking_form_custom_secondary_button_background_color', $cleaned_data['booking_form_custom_secondary_button_background_color'] ); update_bk_option( 'booking_form_custom_secondary_button_text_color', $cleaned_data['booking_form_custom_secondary_button_text_color'] ); update_bk_option( 'booking_form_custom_secondary_button_border_color', $cleaned_data['booking_form_custom_secondary_button_border_color'] ); update_bk_option( 'booking_form_custom_secondary_button_hover_background_color', $cleaned_data['booking_form_custom_secondary_button_hover_background_color'] ); update_bk_option( 'booking_form_custom_secondary_button_hover_text_color', $cleaned_data['booking_form_custom_secondary_button_hover_text_color'] ); update_bk_option( 'booking_form_custom_secondary_button_hover_border_color', $cleaned_data['booking_form_custom_secondary_button_hover_border_color'] ); update_bk_option( 'booking_form_custom_button_border_width', $cleaned_data['booking_form_custom_button_border_width'] ); update_bk_option( 'booking_form_custom_button_border_radius', $cleaned_data['booking_form_custom_button_border_radius'] ); update_bk_option( 'booking_skin', $cleaned_data['booking_skin'] ); update_bk_option( 'booking_timeslot_picker_skin', $cleaned_data['booking_timeslot_picker_skin'] ); update_bk_option( 'booking_timeslot_picker', $cleaned_data['booking_timeslot_picker'] ); } /** * Render select field. * * @param string $name Field name. * @param array $options Options. * @param string $selected Selected value. * @param array $args Extra args. * * @return void */ function wpbc_settings_themes__render_select( $name, $options, $selected, $args = array() ) { $args = wp_parse_args( $args, array( 'id' => $name, 'class' => '', 'data_attrs' => array(), ) ); $data_attrs = ''; foreach ( $args['data_attrs'] as $attr_name => $attr_value ) { $data_attrs .= ' ' . esc_attr( $attr_name ) . '="' . esc_attr( $attr_value ) . '"'; } ?>