| 1 |
<?php |
| 2 |
/** |
| 3 |
* Booking form visitor-message settings page. |
| 4 |
* |
| 5 |
* @package Booking Calendar |
| 6 |
*/ |
| 7 |
|
| 8 |
if ( ! defined( 'ABSPATH' ) ) { |
| 9 |
exit; |
| 10 |
} |
| 11 |
|
| 12 |
/** |
| 13 |
* Check whether the Form Messages settings tab is active. |
| 14 |
* |
| 15 |
* @return bool |
| 16 |
*/ |
| 17 |
function wpbc_settings_messages__is_page() { |
| 18 |
|
| 19 |
if ( ! is_admin() ) { |
| 20 |
return false; |
| 21 |
} |
| 22 |
if ( function_exists( 'wpbc_is_settings_messages_page' ) ) { |
| 23 |
return wpbc_is_settings_messages_page(); |
| 24 |
} |
| 25 |
|
| 26 |
// phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 27 |
$page = isset( $_REQUEST['page'] ) ? sanitize_key( wp_unslash( $_REQUEST['page'] ) ) : ''; |
| 28 |
// phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 29 |
$tab = isset( $_REQUEST['tab'] ) ? sanitize_key( wp_unslash( $_REQUEST['tab'] ) ) : ''; |
| 30 |
return ( 'wpbc-settings' === $page && 'form_messages' === $tab ); |
| 31 |
} |
| 32 |
|
| 33 |
/** |
| 34 |
* Get the capability used by this settings page. |
| 35 |
* |
| 36 |
* @return string |
| 37 |
*/ |
| 38 |
function wpbc_settings_messages__get_manage_cap() { |
| 39 |
|
| 40 |
if ( function_exists( 'wpbc_settings_calendar__get_manage_cap' ) ) { |
| 41 |
return wpbc_settings_calendar__get_manage_cap(); |
| 42 |
} |
| 43 |
|
| 44 |
return 'manage_options'; |
| 45 |
} |
| 46 |
|
| 47 |
/** |
| 48 |
* Get message group definitions. |
| 49 |
* |
| 50 |
* @return array |
| 51 |
*/ |
| 52 |
function wpbc_settings_messages__get_groups() { |
| 53 |
return array( |
| 54 |
'date_selection' => array( 'title' => __( 'Date Selection', 'booking' ), 'icon' => 'wpbc-bi-calendar3-week' ), |
| 55 |
'form_validation' => array( 'title' => __( 'Form Validation', 'booking' ), 'icon' => 'wpbc-bi-ui-checks' ), |
| 56 |
'time_validation' => array( 'title' => __( 'Time Validation', 'booking' ), 'icon' => 'wpbc-bi-clock' ), |
| 57 |
'submission' => array( 'title' => __( 'Booking Submission', 'booking' ), 'icon' => 'wpbc-bi-send' ), |
| 58 |
'booking_summaries' => array( 'title' => __( 'Booking Summaries', 'booking' ), 'icon' => 'wpbc-bi-card-text' ), |
| 59 |
'captcha' => array( 'title' => __( 'CAPTCHA', 'booking' ), 'icon' => 'wpbc-bi-shield-check' ), |
| 60 |
); |
| 61 |
} |
| 62 |
|
| 63 |
/** |
| 64 |
* Enqueue page assets. |
| 65 |
* |
| 66 |
* @param string $where_to_load Asset context. |
| 67 |
* @return void |
| 68 |
*/ |
| 69 |
function wpbc_settings_messages_enqueue_css_files( $where_to_load ) { |
| 70 |
if ( ! in_array( $where_to_load, array( 'admin', 'both' ), true ) || ! wpbc_settings_messages__is_page() ) { |
| 71 |
return; |
| 72 |
} |
| 73 |
wp_enqueue_style( |
| 74 |
'wpbc-settings-messages-page', |
| 75 |
trailingslashit( plugins_url( '', __FILE__ ) ) . '_out/settings_messages_page.css', |
| 76 |
array( 'wpbc-all-admin' ), |
| 77 |
WP_BK_VERSION_NUM |
| 78 |
); |
| 79 |
} |
| 80 |
add_action( 'wpbc_enqueue_css_files', 'wpbc_settings_messages_enqueue_css_files', 68 ); |
| 81 |
|
| 82 |
/** |
| 83 |
* Enqueue page JavaScript. |
| 84 |
* |
| 85 |
* @param string $where_to_load Asset context. |
| 86 |
* @return void |
| 87 |
*/ |
| 88 |
function wpbc_settings_messages_enqueue_js_files( $where_to_load ) { |
| 89 |
if ( ! in_array( $where_to_load, array( 'admin', 'both' ), true ) || ! wpbc_settings_messages__is_page() ) { |
| 90 |
return; |
| 91 |
} |
| 92 |
wp_enqueue_script( |
| 93 |
'wpbc-settings-messages-page', |
| 94 |
trailingslashit( plugins_url( '', __FILE__ ) ) . '_out/settings_messages_page.js', |
| 95 |
array( 'jquery', 'wpbc_all_admin' ), |
| 96 |
WP_BK_VERSION_NUM, |
| 97 |
array( 'in_footer' => true ) |
| 98 |
); |
| 99 |
wp_localize_script( |
| 100 |
'wpbc-settings-messages-page', |
| 101 |
'wpbc_settings_messages_page', |
| 102 |
array( |
| 103 |
'ajax_url' => admin_url( 'admin-ajax.php' ), |
| 104 |
'nonce' => wp_create_nonce( 'wpbc_settings_messages_ajax_nonce' ), |
| 105 |
'action' => 'WPBC_AJX_SETTINGS_MESSAGES_SAVE', |
| 106 |
'i18n' => array( |
| 107 |
'saving' => __( 'Saving', 'booking' ), |
| 108 |
'saved' => __( 'Form messages updated.', 'booking' ), |
| 109 |
'save_failed' => __( 'Unable to save form messages.', 'booking' ), |
| 110 |
'reset_confirm' => __( 'Restore every form message to its plugin default?', 'booking' ), |
| 111 |
), |
| 112 |
) |
| 113 |
); |
| 114 |
} |
| 115 |
add_action( 'wpbc_enqueue_js_files', 'wpbc_settings_messages_enqueue_js_files', 68 ); |
| 116 |
|
| 117 |
/** |
| 118 |
* Compose and validate posted form-message settings. |
| 119 |
* |
| 120 |
* @param array $post_data Raw request data. |
| 121 |
* @return array|WP_Error |
| 122 |
*/ |
| 123 |
function wpbc_settings_messages__validate_data( $post_data ) { |
| 124 |
|
| 125 |
$registry = wpbc_frontend_messages__get_registry(); |
| 126 |
$current_settings = wpbc_frontend_messages__get_settings(); |
| 127 |
$messages = ! empty( $current_settings['messages'] ) && is_array( $current_settings['messages'] ) ? $current_settings['messages'] : array(); |
| 128 |
$enabled = ! empty( $current_settings['enabled'] ) && is_array( $current_settings['enabled'] ) ? $current_settings['enabled'] : array(); |
| 129 |
$defaults = isset( $post_data['message_default'] ) && is_array( $post_data['message_default'] ) ? $post_data['message_default'] : array(); |
| 130 |
$translations = isset( $post_data['message_translations'] ) && is_array( $post_data['message_translations'] ) ? $post_data['message_translations'] : array(); |
| 131 |
$raw_messages = isset( $post_data['message_raw'] ) && is_array( $post_data['message_raw'] ) ? $post_data['message_raw'] : array(); |
| 132 |
$raw_modes = isset( $post_data['message_raw_mode'] ) && is_array( $post_data['message_raw_mode'] ) ? $post_data['message_raw_mode'] : array(); |
| 133 |
$enabled_post = isset( $post_data['message_enabled'] ) && is_array( $post_data['message_enabled'] ) ? $post_data['message_enabled'] : array(); |
| 134 |
|
| 135 |
foreach ( $registry as $message_key => $config ) { |
| 136 |
$is_message_posted = array_key_exists( $message_key, $defaults ) || array_key_exists( $message_key, $translations ) || array_key_exists( $message_key, $raw_messages ) || array_key_exists( $message_key, $raw_modes ); |
| 137 |
if ( ! $is_message_posted ) { |
| 138 |
continue; |
| 139 |
} |
| 140 |
|
| 141 |
if ( isset( $raw_modes[ $message_key ] ) && is_scalar( $raw_modes[ $message_key ] ) && '1' === (string) wp_unslash( $raw_modes[ $message_key ] ) ) { |
| 142 |
$raw_value = isset( $raw_messages[ $message_key ] ) ? $raw_messages[ $message_key ] : ''; |
| 143 |
} else { |
| 144 |
$default_text = isset( $defaults[ $message_key ] ) && is_scalar( $defaults[ $message_key ] ) ? trim( (string) $defaults[ $message_key ] ) : ''; |
| 145 |
$message_translations = isset( $translations[ $message_key ] ) && is_array( $translations[ $message_key ] ) ? $translations[ $message_key ] : array(); |
| 146 |
$translation_sections = array(); |
| 147 |
|
| 148 |
foreach ( $message_translations as $locale => $translation ) { |
| 149 |
$locale = sanitize_text_field( wp_unslash( (string) $locale ) ); |
| 150 |
if ( ! preg_match( '/^[A-Za-z0-9_@.\-]+$/', $locale ) || ! is_scalar( $translation ) ) { |
| 151 |
return new WP_Error( 'invalid_locale', __( 'A message contains an invalid locale.', 'booking' ) ); |
| 152 |
} |
| 153 |
$translation = trim( (string) $translation ); |
| 154 |
if ( '' !== $translation ) { |
| 155 |
$translation_sections[ $locale ] = $translation; |
| 156 |
} |
| 157 |
} |
| 158 |
|
| 159 |
$raw_value = $default_text; |
| 160 |
foreach ( $translation_sections as $locale => $translation ) { |
| 161 |
$raw_value .= "\n[lang=" . $locale . "]\n" . $translation; |
| 162 |
} |
| 163 |
} |
| 164 |
|
| 165 |
$validated = wpbc_frontend_messages__validate_value( $message_key, $raw_value ); |
| 166 |
if ( is_wp_error( $validated ) ) { |
| 167 |
return new WP_Error( |
| 168 |
$validated->get_error_code(), |
| 169 |
sprintf( '%1$s: %2$s', $config['title'], $validated->get_error_message() ) |
| 170 |
); |
| 171 |
} |
| 172 |
if ( '' !== $validated && $validated !== $config['default'] ) { |
| 173 |
$messages[ $message_key ] = $validated; |
| 174 |
} else { |
| 175 |
unset( $messages[ $message_key ] ); |
| 176 |
} |
| 177 |
if ( ! empty( $config['optional'] ) ) { |
| 178 |
$enabled[ $message_key ] = isset( $enabled_post[ $message_key ] ) ? 'On' : 'Off'; |
| 179 |
} |
| 180 |
} |
| 181 |
|
| 182 |
return array( 'version' => 1, 'messages' => $messages, 'enabled' => $enabled ); |
| 183 |
} |
| 184 |
|
| 185 |
/** |
| 186 |
* Show the standard Save button in the settings top toolbar. |
| 187 |
* |
| 188 |
* @param string $page_tag Current page tag. |
| 189 |
* @param string $active_page_tab Current tab. |
| 190 |
* @param string $active_page_subtab Current subtab. |
| 191 |
* @return void |
| 192 |
*/ |
| 193 |
function wpbc_settings_messages__top_toolbar_save_button( $page_tag, $active_page_tab, $active_page_subtab ) { |
| 194 |
|
| 195 |
if ( 'wpbc-settings' !== $page_tag || 'form_messages' !== $active_page_tab ) { |
| 196 |
return; |
| 197 |
} |
| 198 |
if ( ! wpbc_is_mu_user_can_be_here( 'only_super_admin' ) || ! current_user_can( wpbc_settings_messages__get_manage_cap() ) ) { |
| 199 |
return; |
| 200 |
} |
| 201 |
?> |
| 202 |
<div class="wpbc_ui_el__buttons_group wpbc_messages__top_toolbar_group"> |
| 203 |
<a href="javascript:void(0);" |
| 204 |
class="button button-primary wpbc_messages__top_btn_save" |
| 205 |
data-wpbc-messages-save="1" |
| 206 |
data-wpbc-u-busy-text="<?php esc_attr_e( 'Saving', 'booking' ); ?>..."> |
| 207 |
<i class="menu_icon icon-1x wpbc-bi-check2-circle"></i> |
| 208 |
<span class="in-button-text"> <?php esc_html_e( 'Save Changes', 'booking' ); ?></span> |
| 209 |
</a> |
| 210 |
</div> |
| 211 |
<?php |
| 212 |
} |
| 213 |
add_action( 'wpbc_ui_el__top_nav__content_end', 'wpbc_settings_messages__top_toolbar_save_button', 20, 3 ); |
| 214 |
|
| 215 |
/** |
| 216 |
* Settings tab definition and page output. |
| 217 |
*/ |
| 218 |
class WPBC_Page_Settings_Messages extends WPBC_Page_Structure { |
| 219 |
|
| 220 |
/** @return string */ |
| 221 |
public function in_page() { |
| 222 |
return ( wpbc_is_mu_user_can_be_here( 'only_super_admin' ) && current_user_can( wpbc_settings_messages__get_manage_cap() ) ) ? 'wpbc-settings' : (string) wp_rand( 100000, 1000000 ); |
| 223 |
} |
| 224 |
|
| 225 |
/** @return array */ |
| 226 |
public function tabs() { |
| 227 |
return array( |
| 228 |
'form_messages' => array( |
| 229 |
'is_show_top_path' => true, |
| 230 |
'right_vertical_sidebar__is_show' => true, |
| 231 |
'right_vertical_sidebar__default_view_mode' => '', |
| 232 |
'right_vertical_sidebar_compact__is_show' => true, |
| 233 |
'left_navigation__default_view_mode' => '', // FixIn:11.7.1.1: 'compact', |
| 234 |
'top_path_title' => __( 'Form Messages', 'booking' ), |
| 235 |
'title' => __( 'Form Messages', 'booking' ), |
| 236 |
'hint' => __( 'Customize visitor-facing booking form notices and validation messages.', 'booking' ), |
| 237 |
'page_title' => __( 'Form Messages', 'booking' ), |
| 238 |
'link' => function_exists( 'wpbc_get_settings_messages_url' ) ? wpbc_get_settings_messages_url() : admin_url( 'admin.php?page=wpbc-settings&tab=form_messages' ), 'position' => '', 'css_classes' => 'wpbc_top_tab__form_messages', |
| 239 |
'icon' => '', 'font_icon' => 'wpbc-bi-chat-square-text', 'font_icon_right' => '', |
| 240 |
'default' => false, 'disabled' => false, 'hided' => false, 'subtabs' => array(), |
| 241 |
'folder_style' => 'order:22;', |
| 242 |
), |
| 243 |
); |
| 244 |
} |
| 245 |
|
| 246 |
/** @return void */ |
| 247 |
public function right_sidebar_compact_content() { |
| 248 |
WPBC_UI_Sidebar_Panels::render_rightbar_tabs( |
| 249 |
array( |
| 250 |
array( 'id' => 'wpbc_tab_messages_options', 'panel_id' => 'wpbc_messages__inspector_options', 'title' => __( 'Sections', 'booking' ), 'icon' => 'wpbc-bi-list-ul', 'selected' => true ), |
| 251 |
array( 'id' => 'wpbc_tab_messages_help', 'panel_id' => 'wpbc_messages__inspector_help', 'title' => __( 'Help', 'booking' ), 'icon' => 'wpbc-bi-info-circle' ), |
| 252 |
), |
| 253 |
array( 'aria_label' => __( 'Form Message Panels', 'booking' ), 'context' => 'settings_messages', 'class' => 'wpbc_messages_rightbar_tabs' ) |
| 254 |
); |
| 255 |
} |
| 256 |
|
| 257 |
/** @return void */ |
| 258 |
public function right_sidebar_content() { |
| 259 |
?> |
| 260 |
<div class="wpbc_bfb__panel--library wpbc_rightbar_palette wpbc_messages_rightbar_panels"> |
| 261 |
<?php |
| 262 |
WPBC_UI_Sidebar_Panels::render_panel( |
| 263 |
array( 'id' => 'wpbc_messages__inspector_options', 'labelledby' => 'wpbc_tab_messages_options', 'class' => 'wpbc_messages__inspector_options' ), |
| 264 |
array( $this, 'right_panel_options_content' ) |
| 265 |
); |
| 266 |
WPBC_UI_Sidebar_Panels::render_panel( |
| 267 |
array( 'id' => 'wpbc_messages__inspector_help', 'labelledby' => 'wpbc_tab_messages_help', 'class' => 'wpbc_messages__inspector_help', 'hidden' => true ), |
| 268 |
array( $this, 'right_panel_help_content' ) |
| 269 |
); |
| 270 |
?> |
| 271 |
</div> |
| 272 |
<?php |
| 273 |
} |
| 274 |
|
| 275 |
/** @return void */ |
| 276 |
public function right_panel_options_content() { |
| 277 |
WPBC_UI_Sidebar_Panels::render_inspector_header( __( 'Sections', 'booking' ), __( 'Jump directly to a message group on this page.', 'booking' ) ); |
| 278 |
?> |
| 279 |
<div class="wpbc_messages_sidebar_body"> |
| 280 |
<nav class="wpbc_messages_section_nav" aria-label="<?php esc_attr_e( 'Form message sections', 'booking' ); ?>"> |
| 281 |
<?php foreach ( wpbc_settings_messages__get_groups() as $group_key => $group ) : ?> |
| 282 |
<a href="#wpbc_messages_group_<?php echo esc_attr( $group_key ); ?>"><i class="<?php echo esc_attr( $group['icon'] ); ?>" aria-hidden="true"></i><span><?php echo esc_html( $group['title'] ); ?></span></a> |
| 283 |
<?php endforeach; ?> |
| 284 |
</nav> |
| 285 |
<hr> |
| 286 |
<button type="button" class="button" data-wpbc-messages-reset-all="1"><?php esc_html_e( 'Restore All Defaults', 'booking' ); ?></button> |
| 287 |
</div> |
| 288 |
<?php |
| 289 |
} |
| 290 |
|
| 291 |
/** @return void */ |
| 292 |
public function right_panel_help_content() { |
| 293 |
WPBC_UI_Sidebar_Panels::render_inspector_header( __( 'Language Shortcodes', 'booking' ), __( 'Add translations only when a custom message needs language-specific text.', 'booking' ) ); |
| 294 |
?> |
| 295 |
<div class="wpbc_messages_sidebar_body"> |
| 296 |
<p><?php esc_html_e( 'Enter the default text first, followed by one language block for each translation.', 'booking' ); ?></p> |
| 297 |
<pre>Default message |
| 298 |
[lang=fr_FR] |
| 299 |
Message en français |
| 300 |
[lang=de_DE] |
| 301 |
Nachricht auf Deutsch</pre> |
| 302 |
<p><?php esc_html_e( 'Only plain text and valid [lang=LOCALE] blocks are accepted.', 'booking' ); ?></p> |
| 303 |
</div> |
| 304 |
<?php |
| 305 |
} |
| 306 |
|
| 307 |
/** @return void */ |
| 308 |
public function content() { |
| 309 |
do_action( 'wpbc_hook_settings_page_header', 'page_settings_form_messages' ); |
| 310 |
if ( ! wpbc_is_mu_user_can_be_here( 'only_super_admin' ) || ! current_user_can( wpbc_settings_messages__get_manage_cap() ) ) { |
| 311 |
return; |
| 312 |
} |
| 313 |
|
| 314 |
$registry = wpbc_frontend_messages__get_registry(); |
| 315 |
$settings = wpbc_frontend_messages__get_settings(); |
| 316 |
$groups = wpbc_settings_messages__get_groups(); |
| 317 |
?> |
| 318 |
<div class="wpbc_settings_messages_page"> |
| 319 |
<form id="wpbc_settings_messages_form" class="wpbc_settings_messages_form"> |
| 320 |
<input type="hidden" name="action" value="WPBC_AJX_SETTINGS_MESSAGES_SAVE"> |
| 321 |
<input type="hidden" name="nonce" value="<?php echo esc_attr( wp_create_nonce( 'wpbc_settings_messages_ajax_nonce' ) ); ?>"> |
| 322 |
<input type="hidden" name="reset_all" value="0" data-wpbc-messages-reset-input="1"> |
| 323 |
<?php foreach ( $groups as $group_key => $group ) : ?> |
| 324 |
<section class="wpbc_settings_messages_group" aria-labelledby="wpbc_messages_group_<?php echo esc_attr( $group_key ); ?>"> |
| 325 |
<h2 id="wpbc_messages_group_<?php echo esc_attr( $group_key ); ?>"><i class="<?php echo esc_attr( $group['icon'] ); ?>"></i><?php echo esc_html( $group['title'] ); ?></h2> |
| 326 |
<?php foreach ( $registry as $message_key => $config ) : ?> |
| 327 |
<?php if ( $group_key !== $config['group'] ) { continue; } ?> |
| 328 |
<?php |
| 329 |
$stored = isset( $settings['messages'][ $message_key ] ) && is_string( $settings['messages'][ $message_key ] ) ? $settings['messages'][ $message_key ] : ''; |
| 330 |
$field_value = ( '' !== $stored ) ? $stored : $config['default']; |
| 331 |
$is_enabled = wpbc_frontend_messages__is_enabled( $message_key ); |
| 332 |
?> |
| 333 |
<div class="wpbc_settings_message_row" data-message-key="<?php echo esc_attr( $message_key ); ?>"> |
| 334 |
<label for="wpbc_message_<?php echo esc_attr( $message_key ); ?>"><strong><?php echo esc_html( $config['title'] ); ?></strong></label> |
| 335 |
<p class="description"><?php echo esc_html( $config['description'] ); ?></p> |
| 336 |
<?php if ( ! empty( $config['optional'] ) ) : ?> |
| 337 |
<label class="wpbc_message_enabled"><input type="checkbox" name="message_enabled[<?php echo esc_attr( $message_key ); ?>]" value="On" <?php checked( $is_enabled ); ?>> <?php esc_html_e( 'Show this message', 'booking' ); ?></label> |
| 338 |
<?php endif; ?> |
| 339 |
<input type="hidden" name="message_raw_mode[<?php echo esc_attr( $message_key ); ?>]" value="1"> |
| 340 |
<textarea id="wpbc_message_<?php echo esc_attr( $message_key ); ?>" rows="3" name="message_raw[<?php echo esc_attr( $message_key ); ?>]" data-default-message="<?php echo esc_attr( $config['default'] ); ?>"><?php echo esc_textarea( $field_value ); ?></textarea> |
| 341 |
<div class="wpbc_message_row_actions"><button type="button" class="button-link" data-reset-message="1"><?php esc_html_e( 'Restore Default', 'booking' ); ?></button></div> |
| 342 |
</div> |
| 343 |
<?php endforeach; ?> |
| 344 |
</section> |
| 345 |
<?php endforeach; ?> |
| 346 |
</form> |
| 347 |
</div> |
| 348 |
<?php |
| 349 |
do_action( 'wpbc_hook_settings_page_footer', 'page_settings_form_messages' ); |
| 350 |
} |
| 351 |
} |
| 352 |
add_action( 'wpbc_menu_created', array( new WPBC_Page_Settings_Messages(), '__construct' ) ); |
| 353 |
|