PluginProbe
Booking Calendar / 11.8.2
Booking Calendar v11.8.2
11.8.3 11.8.2 11.8.1 11.8 11.7 11.6.1 11.6 11.5 11.4.3 11.4.2 11.4.1 11.4 11.3 11.2.1 11.2 11.1 11.0 10.15.7 10.15.6 10.1.3 10.10 10.10.1 10.10.2 10.11 10.11.2 All 203 releases
← All changes | includes/page-setup/setup_steps.php +514 -51 11.211.8.2 View file →
@@ -1,4 +1,4 @@
1 1 <?php /**
2 2 * @version 1.0
3 3 * @description Steps Structure for Setup Wizard Page
4 4 * @category Setup Class
@@ -17,8 +17,18 @@
17 17
18 18 private $steps_arr = array();
19 19
20 20 /**
21 + * Whether setup route data has been initialized for this instance.
22 + *
23 + * The class is used both as a renderer and as an early setup-state helper. Some callers can reach it before the
24 + * WordPress init hook, so route data must be available before any DB normalization or status checks run.
25 + *
26 + * @var bool
27 + */
28 + private $is_steps_data_initialized = false;
29 +
30 + /**
21 31 * Whether the setup bar render hook has already been registered.
22 32 *
23 33 * This class is also used as a setup-state helper in AJAX and routing code, so multiple instances can exist during
24 34 * one request. Only one of them should render the floating setup bar.
@@ -31,12 +41,31 @@
31 41 * Whether the setup bar has already been printed in the current request.
32 42 *
33 43 * @var bool
34 44 */
35 - private static $is_top_bar_rendered = false;
45 + private static $is_top_bar_rendered = false;
46 +
47 + /**
48 + * Check whether the legacy floating Setup Wizard bar is enabled.
49 + *
50 + * The bar is temporarily disabled while the initial Setup Wizard hands the
51 + * user directly to Form Builder. The filter preserves a bounded rollback
52 + * path without changing Setup Wizard progress or stored configuration.
53 + *
54 + * @return bool True when the floating Setup Wizard bar may be registered.
55 + */
56 + private static function is_floating_setup_bar_enabled() {
57 +
58 + /**
59 + * Filter whether the legacy floating Setup Wizard bar is enabled.
60 + *
61 + * @param bool $is_enabled Whether the floating Setup Wizard bar is enabled.
62 + */
63 + return (bool) apply_filters( 'wpbc_setup_wizard_floating_bar_enabled', false );
64 + }
65 +
66 + public function __construct() {
36 67
37 - public function __construct() {
38 -
39 68 if ( WPBC()->is_wp_inited() || did_action( 'init' ) ) {
40 69 $this->init_steps_data();
41 70 } else {
42 71 add_action( 'init', array( $this, 'init_steps_data' ) );
@@ -41,16 +70,26 @@
41 70 } else {
42 71 add_action( 'init', array( $this, 'init_steps_data' ) );
43 72 }
44 73
45 - if ( ! self::$is_top_bar_hook_registered ) {
46 - add_action( 'wpbc_after_wpbc_page_top__header_tabs', array( $this, 'show_top_right_wizard_button' ), 10, 3 );
47 - self::$is_top_bar_hook_registered = true;
48 - }
74 + if ( self::is_floating_setup_bar_enabled() && ! self::$is_top_bar_hook_registered ) {
75 + add_action( 'wpbc_after_wpbc_page_top__header_tabs', array( $this, 'show_top_right_wizard_button' ), 10, 3 );
76 + self::$is_top_bar_hook_registered = true;
77 + }
49 78
50 79 }
51 80
81 + /**
82 + * Check whether translated strings can be loaded without triggering WordPress just-in-time translation notices.
83 + *
84 + * @return bool
85 + */
86 + private function is_i18n_ready() {
52 87
88 + return ( WPBC()->is_wp_inited() || did_action( 'init' ) );
89 + }
90 +
91 +
53 92 /**
54 93 * Define Steps Data Structure - Init
55 94 *
56 95 * @return void
@@ -56,8 +95,10 @@
56 95 * @return void
57 96 */
58 97 public function init_steps_data(){
59 98
99 + $is_i18n_ready = $this->is_i18n_ready();
100 +
60 101 $step_default_params = array(
61 102 'show_section_left' => false,
62 103 'show_section_right' => false,
63 104 'is_done' => false,
@@ -63,10 +104,10 @@
63 104 'is_done' => false,
64 105 'do_action' => 'none',
65 106 'prior' => '',
66 107 'next' => '',
67 - 'prior_title' => __( 'Go Back', 'booking' ),
68 - 'next_title' => __( 'Save and Continue', 'booking' )
108 + 'prior_title' => $is_i18n_ready ? __( 'Go Back', 'booking' ) : 'Go Back',
109 + 'next_title' => $is_i18n_ready ? __( 'Save and Continue', 'booking' ) : 'Save and Continue'
69 110 );
70 111 $steps_arr = array();
71 112
72 113 if ( function_exists( 'wpbc_setup_wizard__get_intro_route' ) ) {
@@ -86,9 +127,9 @@
86 127 $steps_arr[ $step_name ]['do_action'] = 'save_and_continue__' . $step_name;
87 128 $steps_arr[ $step_name ]['prior'] = ( 0 === $step_index ) ? '' : $route[ $step_index - 1 ];
88 129 $steps_arr[ $step_name ]['next'] = isset( $route[ $step_index + 1 ] ) ? $route[ $step_index + 1 ] : 'welcome';
89 130
90 - if ( function_exists( 'wpbc_setup_wizard__get_step_route_metadata' ) ) {
131 + if ( $is_i18n_ready && function_exists( 'wpbc_setup_wizard__get_step_route_metadata' ) ) {
91 132 $steps_arr[ $step_name ] = array_merge(
92 133 $steps_arr[ $step_name ],
93 134 wpbc_setup_wizard__get_step_route_metadata( $step_name )
94 135 );
@@ -94,23 +135,38 @@
94 135 );
95 136 }
96 137 }
97 138
98 - foreach ( array( 'date_selection', 'working_time', 'time_slots_availability', 'date_availability', 'form_structure', 'color_theme', 'wizard_publish' ) as $continue_step_name ) {
139 + foreach ( array( 'service_provider', 'date_selection', 'changeover_days', 'working_time', 'time_slots_availability', 'date_availability', 'form_structure', 'color_theme', 'wizard_publish' ) as $continue_step_name ) {
99 140 if ( isset( $steps_arr[ $continue_step_name ] ) ) {
100 - $steps_arr[ $continue_step_name ]['next_title'] = __( 'Continue', 'booking' );
141 + $steps_arr[ $continue_step_name ]['next_title'] = $is_i18n_ready ? __( 'Continue', 'booking' ) : 'Continue';
101 142 }
102 143 }
103 144
104 145 $this->steps_arr = $steps_arr;
146 + $this->is_steps_data_initialized = true;
105 147 }
106 148
107 149 /**
150 + * Ensure setup route data is available before this instance reads or normalizes step state.
151 + *
152 + * @return void
153 + */
154 + private function ensure_steps_data_initialized() {
155 +
156 + if ( ! $this->is_steps_data_initialized ) {
157 + $this->init_steps_data();
158 + }
159 + }
160 +
161 + /**
108 162 * Get Steps Data Structure
109 163 * @return array
110 164 */
111 165 public function get_steps_arr(){
112 - return $this->steps_arr;
166 + $this->ensure_steps_data_initialized();
167 +
168 + return $this->steps_arr;
113 169 }
114 170
115 171
116 172 // =================================================================================================================
@@ -478,8 +534,12 @@
478 534
479 535 $active_steps_names = array_keys( $this->get_steps_arr() );
480 536 $normalized_steps = array();
481 537
538 + if ( empty( $active_steps_names ) ) {
539 + return is_array( $steps_is_done ) ? $steps_is_done : array();
540 + }
541 +
482 542 foreach ( $active_steps_names as $step_name ) {
483 543 $normalized_steps[ $step_name ] = $is_completed ? true : ( ( is_array( $steps_is_done ) && isset( $steps_is_done[ $step_name ] ) ) ? (bool) $steps_is_done[ $step_name ] : false );
484 544 }
485 545
@@ -710,8 +770,12 @@
710 770 }
711 771
712 772 $steps_arr = $this->db__get_steps_is_done();
713 773
774 + if ( empty( $steps_arr ) ) {
775 + return false;
776 + }
777 +
714 778 foreach ( $steps_arr as $step_name => $steps_val ) {
715 779 if ( empty( $steps_val ) ) {
716 780 return false;
717 781 }
@@ -767,16 +831,30 @@
767 831 *
768 832 * Show Continue Setup Wizard Button
769 833 * @return void
770 834 */
771 - public function show_top_right_wizard_button() {
835 + public function show_top_right_wizard_button() {
836 +
837 + if ( ! self::is_floating_setup_bar_enabled() ) {
838 + return false;
839 + }
840 +
841 + if ( ! wpbc_is_setup_wizard_page() ) {
842 + $explicit_step_context = false;
772 843
773 - if ( ! wpbc_is_setup_wizard_page() ){
844 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only Setup Wizard routing context.
845 + if ( isset( $_GET['wpbc_setup_step'] ) && is_scalar( $_GET['wpbc_setup_step'] ) ) {
846 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only Setup Wizard routing context.
847 + $request_step = sanitize_key( wp_unslash( $_GET['wpbc_setup_step'] ) );
848 + $explicit_step_context = isset( $this->steps_arr[ $request_step ] )
849 + && function_exists( 'wpbc_setup_wizard_page__has_explicit_step_context' )
850 + && wpbc_setup_wizard_page__has_explicit_step_context( $request_step );
851 + }
774 852
775 853 if (
776 854 ( ! wpbc_is_user_can_access_wizard_page() ) ||
777 - ( $this->db__is_all_steps_completed() )
778 - ){
855 + ( $this->db__is_all_steps_completed() && ! $explicit_step_context )
856 + ) {
779 857 return false;
780 858 }
781 859
782 860 if ( self::$is_top_bar_rendered ) {
@@ -801,16 +879,26 @@
801 879 $save_behavior = $this->get_step_save_behavior( $current_step );
802 880 $target_selector = $this->get_step_meta_value( $current_step, 'target_selector' );
803 881 $scroll_selector = $this->get_step_meta_value( $current_step, 'scroll_selector' );
804 882 $highlight_selector = $this->get_step_meta_value( $current_step, 'highlight_selector' );
883 + $highlight_disabled = $this->get_step_meta_value( $current_step, 'highlight_disabled' );
884 + $highlight_all = $this->get_step_meta_value( $current_step, 'highlight_all' );
805 885 $form_selector = $this->get_step_meta_value( $current_step, 'form_selector' );
806 886 $save_selector = $this->get_step_meta_value( $current_step, 'save_selector' );
887 + $save_ajax_action = $this->get_step_meta_value( $current_step, 'save_ajax_action' );
807 888 $save_events = $this->get_step_meta_value( $current_step, 'save_events' );
808 889 $open_action = $this->get_step_meta_value( $current_step, 'open_action' );
809 - $continue_title = ( 'complete' === $save_behavior ) ? __( 'Finish Setup', 'booking' ) : __( 'Continue', 'booking' );
810 - $is_step_saved = $this->db__is_step_saved( $current_step );
811 - $is_continue_disabled = ( 'manual_save_required' === $save_behavior && ! $is_step_saved );
812 - $continue_href = $is_continue_disabled ? '#wpbc_setup_save_required' : $continue_url;
890 + $secondary_action_url = $this->get_step_meta_value( $current_step, 'secondary_action_url' );
891 + $secondary_action_label = $this->get_step_meta_value( $current_step, 'secondary_action_label' );
892 + $can_save_from_bar = ( 'manual_save_required' === $save_behavior && ! empty( $save_selector ) );
893 + $continue_title = ( 'complete' === $save_behavior ) ? __( 'Finish Setup', 'booking' ) : __( 'Continue', 'booking' );
894 + if ( $can_save_from_bar ) {
895 + $continue_title = __( 'Save and Continue', 'booking' );
896 + }
897 + $is_step_saved = $this->db__is_step_saved( $current_step );
898 + $is_step_unsaved = ( 'manual_save_required' === $save_behavior && ! $is_step_saved );
899 + $is_continue_disabled = ( $is_step_unsaved && ! $can_save_from_bar );
900 + $continue_href = $is_step_unsaved ? '#wpbc_setup_save_required' : $continue_url;
813 901 $mark_saved_nonce = wp_create_nonce( 'wpbc_setup_wizard_mark_step_saved' );
814 902 $step_target_url = $this->get_step_target_url( $current_step );
815 903 $skip_wizard_url = add_query_arg( 'wpbc_setup_wizard', 'completed', wpbc_get_bookings_url() );
816 904 $reset_wizard_url = add_query_arg( 'wpbc_setup_wizard', 'reset', wpbc_get_setup_wizard_page_url() );
@@ -818,8 +906,12 @@
818 906 /* translators: %s: setup target page title. */
819 907 __( 'Save changes on the %s page before continuing.', 'booking' ),
820 908 '<a href="' . esc_url( $step_target_url ) . '">' . esc_html( $step_save_page_title ) . '</a>'
821 909 );
910 + $test_page_links = (
911 + 'wizard_publish' === $current_step
912 + && function_exists( 'wpbc_booking_modes_get_setup_test_page_links' )
913 + ) ? wpbc_booking_modes_get_setup_test_page_links() : array();
822 914
823 915 // FixIn: 10.12.1.1.
824 916 ?><style type="text/css">
825 917 @media screen and (max-width: 782px) {
@@ -854,8 +946,14 @@
854 946 top: auto !important;
855 947 right: var(--wpbc-setup-bar-auto-right, 15px) !important;
856 948 bottom: 15px !important;
857 949 }
950 + .wpbc_page_top__wizard_button.wpbc_setup_wizard_bar_auto_top {
951 + left: auto !important;
952 + top: var(--wpbc-setup-bar-auto-top, 15px) !important;
953 + right: var(--wpbc-setup-bar-auto-right, 15px) !important;
954 + bottom: auto !important;
955 + }
858 956 .wpbc_page_top__wizard_button.wpbc_setup_wizard_bar_is_dragging {
859 957 user-select: none;
860 958 }
861 959 .wpbc_page_top__wizard_button.wpbc_setup_wizard_bar_collapsed {
@@ -953,8 +1051,42 @@
953 1051 }
954 1052 .wpbc_page_top__wizard_button_actions .button.button-secondary {
955 1053 background-color: #e4e4e4;
956 1054 }
1055 + .wpbc_setup_wizard_test_page_actions {
1056 + display: flex;
1057 + flex-flow: row wrap;
1058 + align-items: center;
1059 + gap: 8px;
1060 + font-size: 11px;
1061 + font-weight: 400;
1062 + line-height: 1.35;
1063 + }
1064 + .wpbc_page_top__wizard_button[data-wpbc-setup-step="wizard_publish"] .wpbc_page_top__wizard_button_actions {
1065 + flex-flow: row wrap;
1066 + }
1067 + .wpbc_page_top__wizard_button_actions .button.wpbc_setup_wizard_test_page_button,
1068 + .wpbc_page_top__wizard_button_actions .button.wpbc_setup_wizard_test_page_button:hover,
1069 + .wpbc_page_top__wizard_button_actions .button.wpbc_setup_wizard_test_page_button:focus {
1070 + margin: 20px 0;
1071 + background: #71a501;
1072 + border-color: #71a501;
1073 + color: #f0ffce;
1074 + }
1075 + .wpbc_page_top__wizard_button_actions .button.wpbc_setup_wizard_test_page_button:first-child {
1076 + margin-right: auto;
1077 + margin-left: 0;
1078 + }
1079 + .wpbc_page_top__wizard_button[data-wpbc-setup-step="wizard_publish"] .wpbc_page_top__wizard_button_actions.wpbc_page_top__wizard_button_links {
1080 + margin: 0;
1081 + gap: 10px 15px;
1082 + justify-content: flex-start;
1083 + }
1084 + .wpbc_page_top__wizard_button_actions.wpbc_page_top__wizard_button_links .button.wpbc_setup_wizard_test_page_button:first-child,
1085 + .wpbc_page_top__wizard_button[data-wpbc-setup-step="wizard_publish"] .wpbc_page_top__wizard_button_actions.wpbc_page_top__wizard_button_links a {
1086 + margin: 0;
1087 + flex: 0 1 auto;
1088 + }
957 1089 .wpbc_page_top__wizard_button_actions .button.disabled,
958 1090 .wpbc_page_top__wizard_button_actions .button[aria-disabled="true"] {
959 1091 cursor: not-allowed;
960 1092 opacity: 0.55;
@@ -1054,10 +1186,13 @@
1054 1186 data-wpbc-setup-mark-saved-nonce="<?php echo esc_attr( $mark_saved_nonce ); ?>"
1055 1187 data-wpbc-setup-target-selector="<?php echo esc_attr( $target_selector ); ?>"
1056 1188 data-wpbc-setup-scroll-selector="<?php echo esc_attr( $scroll_selector ); ?>"
1057 1189 data-wpbc-setup-highlight-selector="<?php echo esc_attr( $highlight_selector ); ?>"
1190 + data-wpbc-setup-highlight-disabled="<?php echo esc_attr( $highlight_disabled ); ?>"
1191 + data-wpbc-setup-highlight-all="<?php echo esc_attr( $highlight_all ); ?>"
1058 1192 data-wpbc-setup-form-selector="<?php echo esc_attr( $form_selector ); ?>"
1059 1193 data-wpbc-setup-save-selector="<?php echo esc_attr( $save_selector ); ?>"
1194 + data-wpbc-setup-save-ajax-action="<?php echo esc_attr( $save_ajax_action ); ?>"
1060 1195 data-wpbc-setup-save-events="<?php echo esc_attr( $save_events ); ?>"
1061 1196 data-wpbc-setup-open-action="<?php echo esc_attr( $open_action ); ?>">
1062 1197 <div class="wpbc_ui_control wpbc_page_top__wizard_button_content">
1063 1198 <div class="in-button-text"
@@ -1082,9 +1217,9 @@
1082 1217 <button type="button"
1083 1218 class="wpbc_setup_wizard_bar_icon_button wpbc_setup_wizard_bar_reset_button"
1084 1219 title="<?php esc_attr_e( 'Reset setup bar position', 'booking' ); ?>"
1085 1220 aria-label="<?php esc_attr_e( 'Reset setup bar position', 'booking' ); ?>">
1086 - <i class="menu_icon icon-1x wpbc_icn_refresh"></i>
1221 + <i class="menu_icon icon-1x wpbc_icn_rotate_90 wpbc_icn_pin_invoke"></i>
1087 1222 </button>
1088 1223 <button type="button"
1089 1224 class="wpbc_setup_wizard_bar_icon_button wpbc_setup_wizard_bar_toggle_button"
1090 1225 title="<?php esc_attr_e( 'Collapse setup bar', 'booking' ); ?>"
@@ -1089,9 +1224,9 @@
1089 1224 class="wpbc_setup_wizard_bar_icon_button wpbc_setup_wizard_bar_toggle_button"
1090 1225 title="<?php esc_attr_e( 'Collapse setup bar', 'booking' ); ?>"
1091 1226 aria-label="<?php esc_attr_e( 'Collapse setup bar', 'booking' ); ?>"
1092 1227 aria-expanded="true">
1093 - <i class="menu_icon icon-1x wpbc_icn_expand_less"></i>
1228 + <i class="menu_icon icon-1x wpbc_icn_minimize"></i>
1094 1229 </button>
1095 1230 </div>
1096 1231 </div>
1097 1232 <div class="name_item wpbc_setup_wizard_bar_expandable" style="flex:1 1 100%;font-size:13px;font-weight:600;line-height:1.35;margin:3px 0 0;color:#f1f1f1;">
@@ -1125,9 +1260,32 @@
1125 1260 }
1126 1261 ?>
1127 1262 </div>
1128 1263 <?php } ?>
1264 + <?php if ( 'wizard_publish' === $current_step && empty( $test_page_links ) ) { ?>
1265 + <div class="wpbc_setup_wizard_test_page_actions wpbc_setup_wizard_bar_expandable">
1266 + <span><?php esc_html_e( 'No published booking page was found yet. Use QuickStart or the page publishing controls, then return to this step.', 'booking' ); ?></span>
1267 + </div>
1268 + <?php } ?>
1269 + <?php if ( 'wizard_publish' === $current_step && ! empty( $test_page_links ) ) { ?>
1270 + <div class="wpbc_page_top__wizard_button_actions wpbc_setup_wizard_bar_expandable wpbc_page_top__wizard_button_links">
1271 + <?php foreach ( $test_page_links as $test_page_link ) {
1272 + if ( empty( $test_page_link['url'] ) || empty( $test_page_link['label'] ) ) {
1273 + continue;
1274 + }
1275 + ?>
1276 + <a class="button button-primary secondary wpbc_setup_wizard_test_page_button"
1277 + href="<?php echo esc_url( $test_page_link['url'] ); ?>"
1278 + target="_blank"
1279 + rel="noopener noreferrer"><?php echo esc_html( $test_page_link['label'] ); ?></a>
1280 + <?php } ?>
1281 + </div>
1282 + <?php } ?>
1129 1283 <div class="wpbc_page_top__wizard_button_actions wpbc_setup_wizard_bar_expandable">
1284 + <?php if ( ! empty( $secondary_action_url ) && ! empty( $secondary_action_label ) ) { ?>
1285 + <a class="button button-secondary wpbc_setup_wizard_secondary_action"
1286 + href="<?php echo esc_url( $secondary_action_url ); ?>"><?php echo esc_html( $secondary_action_label ); ?></a>
1287 + <?php } ?>
1130 1288 <?php if ( ! empty( $prior_url ) ) { ?>
1131 1289 <a href="<?php echo esc_url( $prior_url ); ?>" class="button button-secondary"><?php esc_html_e( 'Back', 'booking' ); ?></a>
1132 1290 <?php } ?>
1133 1291 <a href="<?php echo esc_url( $continue_href ); ?>"
@@ -1156,10 +1314,13 @@
1156 1314 var saveBehavior = $bar.attr( 'data-wpbc-setup-save-behavior' ) || '';
1157 1315 var selector = $bar.attr( 'data-wpbc-setup-target-selector' ) || '';
1158 1316 var scrollSelector = $bar.attr( 'data-wpbc-setup-scroll-selector' ) || selector;
1159 1317 var highlightSelector = $bar.attr( 'data-wpbc-setup-highlight-selector' ) || selector;
1318 + var highlightDisabled = ( '1' === ( $bar.attr( 'data-wpbc-setup-highlight-disabled' ) || '' ) );
1319 + var highlightAll = ( '1' === ( $bar.attr( 'data-wpbc-setup-highlight-all' ) || '' ) );
1160 1320 var formSelector = $bar.attr( 'data-wpbc-setup-form-selector' ) || '';
1161 1321 var saveSelector = $bar.attr( 'data-wpbc-setup-save-selector' ) || '';
1322 + var saveAjaxAction = $bar.attr( 'data-wpbc-setup-save-ajax-action' ) || '';
1162 1323 var saveEvents = ( $bar.attr( 'data-wpbc-setup-save-events' ) || '' ).split( ',' );
1163 1324 var openAction = $bar.attr( 'data-wpbc-setup-open-action' ) || '';
1164 1325 var ajaxUrl = $bar.attr( 'data-wpbc-setup-ajax-url' ) || '';
1165 1326 var nonce = $bar.attr( 'data-wpbc-setup-mark-saved-nonce' ) || '';
@@ -1166,8 +1327,11 @@
1166 1327 var $continueButton = $bar.find( '.wpbc_setup_wizard_continue_button' ).first();
1167 1328 var $note = $bar.find( '.wpbc_page_top__wizard_button_note' ).first();
1168 1329 var savedNote = '<?php echo esc_js( __( 'Changes saved. You can continue.', 'booking' ) ); ?>';
1169 1330 var saveRequiredNote = <?php echo wp_json_encode( wp_kses_post( $save_required_note ) ); ?>;
1331 + var continueTitle = <?php echo wp_json_encode( ( 'complete' === $save_behavior ) ? __( 'Finish Setup', 'booking' ) : __( 'Continue', 'booking' ) ); ?>;
1332 + var saveAndContinueTitle = <?php echo wp_json_encode( __( 'Save and Continue', 'booking' ) ); ?>;
1333 + var savingTitle = <?php echo wp_json_encode( __( 'Saving', 'booking' ) . '...' ); ?>;
1170 1334 var $toggleButton = $bar.find( '.wpbc_setup_wizard_bar_toggle_button' ).first();
1171 1335 var $toggleIcon = $toggleButton.find( 'i' ).first();
1172 1336 var $resetButton = $bar.find( '.wpbc_setup_wizard_bar_reset_button' ).first();
1173 1337 var $dragHandle = $bar.find( '.wpbc_setup_wizard_bar_drag_handle' ).first();
@@ -1175,9 +1339,12 @@
1175 1339 var collapsedStorageKey = 'wpbc_setup_wizard_bar_collapsed';
1176 1340 var collapseLabel = <?php echo wp_json_encode( __( 'Collapse setup bar', 'booking' ) ); ?>;
1177 1341 var expandLabel = <?php echo wp_json_encode( __( 'Expand setup bar', 'booking' ) ); ?>;
1178 1342 var $target;
1343 + var $highlightTargets = jQuery();
1179 1344 var saveClicked = false;
1345 + var saveAndContinueRequested = false;
1346 + var saveAndContinueRedirecting = false;
1180 1347
1181 1348 function wpbcSetupWizardStorageGet( key ) {
1182 1349 try {
1183 1350 return window.localStorage.getItem( key );
@@ -1222,12 +1389,14 @@
1222 1389 if ( wpbcSetupWizardIsSmallViewport() || ! position ) {
1223 1390 $bar
1224 1391 .removeClass( 'wpbc_setup_wizard_bar_is_moved' )
1225 1392 .removeClass( 'wpbc_setup_wizard_bar_auto_shifted' )
1393 + .removeClass( 'wpbc_setup_wizard_bar_auto_top' )
1226 1394 .css( {
1227 1395 '--wpbc-setup-bar-left': '',
1228 1396 '--wpbc-setup-bar-bottom': '',
1229 - '--wpbc-setup-bar-auto-right': ''
1397 + '--wpbc-setup-bar-auto-right': '',
1398 + '--wpbc-setup-bar-auto-top': ''
1230 1399 } );
1231 1400 return;
1232 1401 }
1233 1402
@@ -1239,15 +1408,27 @@
1239 1408 clampedPosition = wpbcSetupWizardClampPosition( parseFloat( position.left ) || 15, isNaN( positionBottom ) ? 15 : positionBottom );
1240 1409 $bar
1241 1410 .addClass( 'wpbc_setup_wizard_bar_is_moved' )
1242 1411 .removeClass( 'wpbc_setup_wizard_bar_auto_shifted' )
1412 + .removeClass( 'wpbc_setup_wizard_bar_auto_top' )
1243 1413 .css( {
1244 1414 '--wpbc-setup-bar-left': clampedPosition.left + 'px',
1245 1415 '--wpbc-setup-bar-bottom': clampedPosition.bottom + 'px',
1246 - '--wpbc-setup-bar-auto-right': ''
1416 + '--wpbc-setup-bar-auto-right': '',
1417 + '--wpbc-setup-bar-auto-top': ''
1247 1418 } );
1248 1419 }
1249 1420
1421 + function wpbcSetupWizardShouldUseTopDefault() {
1422 + return -1 !== jQuery.inArray( step, [
1423 + 'date_selection',
1424 + 'changeover_days',
1425 + 'working_time',
1426 + 'time_slots_availability',
1427 + 'date_availability'
1428 + ] );
1429 + }
1430 +
1250 1431 function wpbcSetupWizardGetRightSidebarOffset() {
1251 1432 var viewportWidth = jQuery( window ).width();
1252 1433 var viewportHeight = jQuery( window ).height();
1253 1434 var $sidebar = jQuery();
@@ -1289,19 +1470,39 @@
1289 1470 wpbcSetupWizardApplyPosition( null );
1290 1471 return;
1291 1472 }
1292 1473
1474 + // Clear any visible inspector while retaining the minimum offset used by the Days Availability page.
1293 1475 rightOffset = wpbcSetupWizardGetRightSidebarOffset();
1476 + if ( 'date_availability' === step ) {
1477 + rightOffset = Math.max( rightOffset, 60 );
1478 + }
1294 1479 maxRight = Math.max( 15, jQuery( window ).width() - barWidth - 10 );
1295 1480
1481 + if ( wpbcSetupWizardShouldUseTopDefault() ) {
1482 + $bar
1483 + .removeClass( 'wpbc_setup_wizard_bar_is_moved' )
1484 + .addClass( 'wpbc_setup_wizard_bar_auto_shifted' )
1485 + .addClass( 'wpbc_setup_wizard_bar_auto_top' )
1486 + .css( {
1487 + '--wpbc-setup-bar-left': '',
1488 + '--wpbc-setup-bar-bottom': '',
1489 + '--wpbc-setup-bar-auto-right': Math.min( Math.max( rightOffset, 15 ), maxRight ) + 'px',
1490 + '--wpbc-setup-bar-auto-top': '15px'
1491 + } );
1492 + return;
1493 + }
1494 +
1296 1495 if ( rightOffset > 15 ) {
1297 1496 $bar
1298 1497 .removeClass( 'wpbc_setup_wizard_bar_is_moved' )
1498 + .removeClass( 'wpbc_setup_wizard_bar_auto_top' )
1299 1499 .addClass( 'wpbc_setup_wizard_bar_auto_shifted' )
1300 1500 .css( {
1301 1501 '--wpbc-setup-bar-left': '',
1302 1502 '--wpbc-setup-bar-bottom': '',
1303 - '--wpbc-setup-bar-auto-right': Math.min( rightOffset, maxRight ) + 'px'
1503 + '--wpbc-setup-bar-auto-right': Math.min( rightOffset, maxRight ) + 'px',
1504 + '--wpbc-setup-bar-auto-top': ''
1304 1505 } );
1305 1506 return;
1306 1507 }
1307 1508
@@ -1316,8 +1517,11 @@
1316 1517 }
1317 1518
1318 1519 function wpbcSetupWizardApplySavedPosition() {
1319 1520 var savedPosition = wpbcSetupWizardStorageGet( positionStorageKey );
1521 + var rightSidebarOffset;
1522 + var barRect;
1523 + var sidebarLeft;
1320 1524
1321 1525 if ( ! savedPosition ) {
1322 1526 wpbcSetupWizardApplyDefaultPosition();
1323 1527 return;
@@ -1327,9 +1531,20 @@
1327 1531 wpbcSetupWizardApplyPosition( JSON.parse( savedPosition ) );
1328 1532 } catch ( _e ) {
1329 1533 wpbcSetupWizardStorageRemove( positionStorageKey );
1330 1534 wpbcSetupWizardApplyDefaultPosition();
1535 + return;
1331 1536 }
1537 +
1538 + rightSidebarOffset = wpbcSetupWizardGetRightSidebarOffset();
1539 + if ( 'service_provider' === step && rightSidebarOffset > 15 ) {
1540 + barRect = $bar[0].getBoundingClientRect();
1541 + sidebarLeft = jQuery( window ).width() - rightSidebarOffset + 15;
1542 +
1543 + if ( barRect.right > ( sidebarLeft - 10 ) ) {
1544 + wpbcSetupWizardApplyDefaultPosition();
1545 + }
1546 + }
1332 1547 }
1333 1548
1334 1549 function wpbcSetupWizardResetPosition() {
1335 1550 wpbcSetupWizardStorageRemove( positionStorageKey );
@@ -1342,10 +1557,10 @@
1342 1557 .attr( 'aria-expanded', isCollapsed ? 'false' : 'true' )
1343 1558 .attr( 'title', isCollapsed ? expandLabel : collapseLabel )
1344 1559 .attr( 'aria-label', isCollapsed ? expandLabel : collapseLabel );
1345 1560 $toggleIcon
1346 - .toggleClass( 'wpbc_icn_expand_less', ! isCollapsed )
1347 - .toggleClass( 'wpbc_icn_expand_more', !! isCollapsed );
1561 + .toggleClass( 'wpbc_icn_minimize', ! isCollapsed )
1562 + .toggleClass( 'wpbc_icn_fullscreen', !! isCollapsed );
1348 1563 wpbcSetupWizardStorageSet( collapsedStorageKey, isCollapsed ? '1' : '0' );
1349 1564 wpbcSetupWizardApplySavedPosition();
1350 1565 }
1351 1566
@@ -1400,11 +1615,16 @@
1400 1615 wpbcSetupWizardApplySavedPosition();
1401 1616 setTimeout( wpbcSetupWizardApplySavedPosition, 400 );
1402 1617 setTimeout( wpbcSetupWizardApplySavedPosition, 1000 );
1403 1618 jQuery( window ).on( 'resize.wpbc_setup_wizard_bar', wpbcSetupWizardApplySavedPosition );
1619 + jQuery( document ).on( 'wpbc_setup_wizard_layout_changed.wpbc_setup_wizard_bar', wpbcSetupWizardApplySavedPosition );
1404 1620
1405 1621 function wpbcSetupWizardOpenPublishArea() {
1406 - var isResourcesPage = -1 !== window.location.href.indexOf( 'page=wpbc-resources' );
1622 + var currentUrl = new window.URL( window.location.href );
1623 + var currentResourcesTab = currentUrl.searchParams.get( 'tab' ) || '';
1624 + var isResourcesPage = 'wpbc-resources' === currentUrl.searchParams.get( 'page' )
1625 + && ( '' === currentResourcesTab || 'resources' === currentResourcesTab );
1626 + var catalogMount = document.getElementById( 'wpbc_catalog_booking_resources' );
1407 1627 var publishTabSelectors = [
1408 1628 '.wpdvlp-sub-tabs .nav-tab',
1409 1629 '.wpdvlp-top-tabs .nav-tab',
1410 1630 '.wpbc_settings_navigation_item a',
@@ -1422,23 +1642,90 @@
1422 1642 'button.button'
1423 1643 ].join( ',' );
1424 1644 var publishTargetSelector = [
1425 1645 '.wpbc_resources_table .ui_group__publish_btn:visible',
1646 + '#wpbc_booking_resource_table .ui_group__publish_btn:visible',
1426 1647 '.wpbc_resource_field__switchable.wpbc_resource_field__publish:visible',
1427 1648 '.wpbc_resource_field__publish:visible',
1428 1649 '.wpbc_resource_publish:visible',
1429 1650 '.wpbc_publish_resources:visible',
1430 - '.wpbc_resource_shortcode:visible',
1431 - '[data-wpbc-resource-publish]:visible',
1432 - '#wpbc_booking_resource_table:visible'
1651 + '[data-wpbc-resource-publish]:visible'
1433 1652 ].join( ',' );
1434 1653 var $publishTab;
1435 1654 var $publishToggle;
1436 1655
1437 - if ( ( 'wizard_publish' !== step && 'publish_area' !== openAction ) || ! isResourcesPage ) {
1656 + if ( 'wizard_publish' !== step || ! isResourcesPage ) {
1438 1657 return;
1439 1658 }
1440 1659
1660 + if ( 'catalog_publish' === openAction && catalogMount ) {
1661 + var catalogPublishRequested = false;
1662 + /**
1663 + * Open the first authorized Resource at its publishing inspector section.
1664 + *
1665 + * @param {CustomEvent|null} renderEvent Shared catalog render event.
1666 + * @return {void}
1667 + */
1668 + var openCatalogPublishing = function( renderEvent ) {
1669 + var catalogResponse = renderEvent && renderEvent.detail ? renderEvent.detail.response : null;
1670 + var publishAction = catalogMount.querySelector( '[data-wpbc-booking-resource-action="publish_resource"][data-wpbc-booking-resource-id]' );
1671 + var resourceId = publishAction ? Number( publishAction.getAttribute( 'data-wpbc-booking-resource-id' ) || 0 ) : 0;
1672 +
1673 + if ( ! resourceId && catalogResponse && Array.isArray( catalogResponse.items ) ) {
1674 + catalogResponse.items.some( function( resource ) {
1675 + var isPublishAuthorized = Array.isArray( resource.action_items ) && resource.action_items.some( function( resourceAction ) {
1676 + return resourceAction && 'publish_resource' === resourceAction.id;
1677 + } );
1678 +
1679 + if ( ! isPublishAuthorized ) {
1680 + return false;
1681 + }
1682 +
1683 + resourceId = Number( resource.id || 0 );
1684 + return 0 < resourceId;
1685 + } );
1686 + }
1687 + if ( catalogPublishRequested || ! resourceId ) {
1688 + return;
1689 + }
1690 +
1691 + catalogPublishRequested = true;
1692 + catalogMount.removeEventListener( 'wpbc:ui-catalog-rendered', openCatalogPublishing );
1693 +
1694 + // Defer until the domain catalog has completed its synchronous mount listeners.
1695 + window.setTimeout( function() {
1696 + var resourceActionEvent;
1697 +
1698 + if ( 'function' === typeof window.CustomEvent ) {
1699 + resourceActionEvent = new window.CustomEvent( 'wpbc:booking-resource-action', {
1700 + bubbles: false,
1701 + detail: {
1702 + action: 'publish_resource',
1703 + resource_id: resourceId,
1704 + source: 'setup_wizard'
1705 + }
1706 + } );
1707 + } else {
1708 + resourceActionEvent = document.createEvent( 'CustomEvent' );
1709 + resourceActionEvent.initCustomEvent( 'wpbc:booking-resource-action', false, false, {
1710 + action: 'publish_resource',
1711 + resource_id: resourceId,
1712 + source: 'setup_wizard'
1713 + } );
1714 + }
1715 + document.dispatchEvent( resourceActionEvent );
1716 + }, 0 );
1717 + };
1718 +
1719 + catalogMount.addEventListener( 'wpbc:ui-catalog-rendered', openCatalogPublishing );
1720 + openCatalogPublishing( null );
1721 + return;
1722 + }
1723 +
1724 + if ( 'publish_area' !== openAction ) {
1725 + return;
1726 + }
1727 +
1441 1728 $publishTab = jQuery( publishTabSelectors ).filter( ':visible' ).filter( function() {
1442 1729 var $element = jQuery( this );
1443 1730 var text = $element.text() || '';
1444 1731 var href = $element.attr( 'href' ) || '';
@@ -1627,9 +1914,10 @@
1627 1914 $bar.attr( 'data-wpbc-setup-is-saved', '1' );
1628 1915 $continueButton
1629 1916 .removeClass( 'disabled' )
1630 1917 .removeAttr( 'aria-disabled' )
1631 - .attr( 'href', $continueButton.attr( 'data-wpbc-setup-continue-url' ) || '#' );
1918 + .attr( 'href', $continueButton.attr( 'data-wpbc-setup-continue-url' ) || '#' )
1919 + .text( continueTitle );
1632 1920 if ( $note.length ) {
1633 1921 $note
1634 1922 .addClass( 'wpbc_setup_wizard_bar_note_saved' )
1635 1923 .text( savedNote );
@@ -1637,12 +1925,14 @@
1637 1925 }
1638 1926
1639 1927 function wpbcSetupWizardSetUnsaved() {
1640 1928 $bar.attr( 'data-wpbc-setup-is-saved', '0' );
1641 - $continueButton
1642 - .addClass( 'disabled' )
1643 - .attr( 'aria-disabled', 'true' )
1644 - .attr( 'href', '#wpbc_setup_save_required' );
1929 + $continueButton.attr( 'href', '#wpbc_setup_save_required' ).text( saveSelector ? saveAndContinueTitle : continueTitle );
1930 + if ( saveSelector ) {
1931 + $continueButton.removeClass( 'disabled' ).removeAttr( 'aria-disabled' );
1932 + } else {
1933 + $continueButton.addClass( 'disabled' ).attr( 'aria-disabled', 'true' );
1934 + }
1645 1935 if ( $note.length ) {
1646 1936 $note
1647 1937 .removeClass( 'wpbc_setup_wizard_bar_note_saved' )
1648 1938 .html( saveRequiredNote );
@@ -1648,11 +1938,48 @@
1648 1938 .html( saveRequiredNote );
1649 1939 }
1650 1940 }
1651 1941
1652 - function wpbcSetupWizardMarkSaved() {
1942 + function wpbcSetupWizardSetSaveAndContinueBusy( isBusy ) {
1943 + if ( ! saveSelector ) {
1944 + return;
1945 + }
1946 +
1947 + $continueButton.toggleClass( 'disabled', !! isBusy ).text( isBusy ? savingTitle : saveAndContinueTitle );
1948 + if ( isBusy ) {
1949 + $continueButton.attr( 'aria-disabled', 'true' );
1950 + } else {
1951 + $continueButton.removeAttr( 'aria-disabled' );
1952 + }
1953 + }
1954 +
1955 + function wpbcSetupWizardGetContinueUrl() {
1956 + return $continueButton.attr( 'data-wpbc-setup-continue-url' ) || $continueButton.attr( 'href' ) || '';
1957 + }
1958 +
1959 + function wpbcSetupWizardContinueAfterSave() {
1960 + var continueUrl;
1961 +
1962 + if ( saveAndContinueRedirecting ) {
1963 + return;
1964 + }
1965 +
1966 + continueUrl = wpbcSetupWizardGetContinueUrl();
1967 + if ( ! continueUrl || '#wpbc_setup_save_required' === continueUrl ) {
1968 + wpbcSetupWizardSetSaveAndContinueBusy( false );
1969 + return;
1970 + }
1971 +
1972 + saveAndContinueRedirecting = true;
1973 + window.location.href = continueUrl;
1974 + }
1975 +
1976 + function wpbcSetupWizardMarkSaved( afterSavedCallback ) {
1653 1977 if ( ! step || ! ajaxUrl || ! nonce ) {
1654 1978 wpbcSetupWizardSetSaved();
1979 + if ( 'function' === typeof afterSavedCallback ) {
1980 + afterSavedCallback();
1981 + }
1655 1982 return;
1656 1983 }
1657 1984
1658 1985 jQuery.post( ajaxUrl, {
@@ -1666,9 +1993,17 @@
1666 1993 } catch ( _e ) {}
1667 1994 }
1668 1995 if ( response && response.success ) {
1669 1996 wpbcSetupWizardSetSaved();
1997 + if ( 'function' === typeof afterSavedCallback ) {
1998 + afterSavedCallback();
1999 + }
1670 2000 }
2001 + } ).fail( function() {
2002 + if ( saveAndContinueRequested ) {
2003 + wpbcSetupWizardSetSaveAndContinueBusy( false );
2004 + saveAndContinueRequested = false;
2005 + }
1671 2006 } );
1672 2007 }
1673 2008
1674 2009 function wpbcSetupWizardSaveStarted() {
@@ -1676,9 +2011,9 @@
1676 2011 }
1677 2012
1678 2013 function wpbcSetupWizardLooksSuccessfulResponse( response ) {
1679 2014 if ( ! response ) {
1680 - return true;
2015 + return false;
1681 2016 }
1682 2017
1683 2018 return (
1684 2019 !! response.success
@@ -1688,8 +2023,54 @@
1688 2023 || ( response.data && response.data.setup_step_saved )
1689 2024 );
1690 2025 }
1691 2026
2027 + function wpbcSetupWizardGetAjaxAction( ajaxSettings ) {
2028 + var data = ajaxSettings && ajaxSettings.data ? ajaxSettings.data : '';
2029 + var matches;
2030 +
2031 + if ( ! data ) {
2032 + return '';
2033 + }
2034 +
2035 + if ( 'string' === typeof data ) {
2036 + matches = data.match( /(?:^|&)action=([^&]+)/ );
2037 + return matches && matches[1] ? decodeURIComponent( matches[1].replace( /\+/g, ' ' ) ) : '';
2038 + }
2039 +
2040 + if ( window.FormData && data instanceof window.FormData && 'function' === typeof data.get ) {
2041 + return data.get( 'action' ) || '';
2042 + }
2043 +
2044 + if ( 'object' === typeof data && data.action ) {
2045 + return data.action;
2046 + }
2047 +
2048 + return '';
2049 + }
2050 +
2051 + function wpbcSetupWizardIsExpectedSaveAjax( ajaxSettings ) {
2052 + var ajaxAction;
2053 +
2054 + if ( ! saveAjaxAction ) {
2055 + return true;
2056 + }
2057 +
2058 + ajaxAction = wpbcSetupWizardGetAjaxAction( ajaxSettings );
2059 +
2060 + return saveAjaxAction === ajaxAction;
2061 + }
2062 +
2063 + function wpbcSetupWizardHandleSavedEvent() {
2064 + saveClicked = false;
2065 + wpbcSetupWizardSetSaved();
2066 + if ( saveAndContinueRequested ) {
2067 + wpbcSetupWizardMarkSaved( wpbcSetupWizardContinueAfterSave );
2068 + return;
2069 + }
2070 + wpbcSetupWizardMarkSaved();
2071 + }
2072 +
1692 2073 function wpbcSetupWizardRegisterSavedEvent( eventName ) {
1693 2074 eventName = ( eventName || '' ).replace( /^\s+|\s+$/g, '' );
1694 2075 if ( ! eventName ) {
1695 2076 return;
@@ -1694,14 +2075,55 @@
1694 2075 if ( ! eventName ) {
1695 2076 return;
1696 2077 }
1697 2078
1698 - document.addEventListener( eventName, function() {
1699 - wpbcSetupWizardSetSaved();
1700 - wpbcSetupWizardMarkSaved();
1701 - }, true );
2079 + document.addEventListener( eventName, wpbcSetupWizardHandleSavedEvent, true );
2080 + jQuery( document ).on( eventName + '.wpbc_setup_wizard', wpbcSetupWizardHandleSavedEvent );
1702 2081 }
1703 2082
2083 + function wpbcSetupWizardFindSaveControl() {
2084 + var $saveControl = wpbcSetupWizardGetFirstElement( saveSelector );
2085 +
2086 + if ( $saveControl.length ) {
2087 + return $saveControl;
2088 + }
2089 +
2090 + if ( ! formSelector ) {
2091 + return jQuery();
2092 + }
2093 +
2094 + return wpbcSetupWizardGetFirstElement(
2095 + formSelector + ' button[type="submit"],' +
2096 + formSelector + ' input[type="submit"],' +
2097 + formSelector + ' .wpbc_submit_button_trigger,' +
2098 + formSelector + ' .wpbc_submit_button'
2099 + );
2100 + }
2101 +
2102 + function wpbcSetupWizardTriggerSaveAndContinue() {
2103 + var $saveControl = wpbcSetupWizardFindSaveControl();
2104 +
2105 + if ( saveAndContinueRequested ) {
2106 + return;
2107 + }
2108 +
2109 + if ( ! $saveControl.length || $saveControl.hasClass( 'disabled' ) || 'true' === $saveControl.attr( 'aria-disabled' ) ) {
2110 + if ( typeof wpbc_admin_show_message === 'function' ) {
2111 + wpbc_admin_show_message( '<?php echo esc_js( __( 'Please save changes on this page before continuing setup.', 'booking' ) ); ?>', 'warning', 4000, false );
2112 + }
2113 + wpbcSetupWizardPulseSaveRequiredMessage();
2114 + return;
2115 + }
2116 +
2117 + saveAndContinueRequested = true;
2118 + wpbcSetupWizardSaveStarted();
2119 + wpbcSetupWizardSetSaveAndContinueBusy( true );
2120 + if ( formSelector ) {
2121 + jQuery( formSelector ).find( 'input[name="wpbc_setup_continue_after_save"]' ).val( '1' );
2122 + }
2123 + $saveControl.trigger( 'click' );
2124 + }
2125 +
1704 2126 if ( 'manual_save_required' === saveBehavior ) {
1705 2127 window.wpbc_setup_wizard_set_current_step_saved = wpbcSetupWizardSetSaved;
1706 2128 window.wpbc_setup_wizard_mark_current_step_saved = wpbcSetupWizardMarkSaved;
1707 2129
@@ -1711,8 +2133,11 @@
1711 2133 }
1712 2134 wpbcSetupWizardSaveStarted();
1713 2135 event.detail.payload.wpbc_setup = '1';
1714 2136 event.detail.payload.wpbc_setup_step = step;
2137 + if ( saveAndContinueRequested ) {
2138 + event.detail.payload.wpbc_setup_continue_after_save = '1';
2139 + }
1715 2140 }, true );
1716 2141
1717 2142 saveEvents.forEach( wpbcSetupWizardRegisterSavedEvent );
1718 2143
@@ -1730,15 +2155,19 @@
1730 2155 }
1731 2156 if ( ! $form.find( 'input[name="wpbc_setup"]' ).length ) {
1732 2157 $form.append( '<input type="hidden" name="wpbc_setup" value="" />' );
1733 2158 }
2159 + if ( ! $form.find( 'input[name="wpbc_setup_continue_after_save"]' ).length ) {
2160 + $form.append( '<input type="hidden" name="wpbc_setup_continue_after_save" value="" />' );
2161 + }
1734 2162 $form.find( 'input[name="wpbc_setup_saved_step"]' ).val( step );
1735 2163 $form.find( 'input[name="wpbc_setup_step"]' ).val( step );
1736 2164 $form.find( 'input[name="wpbc_setup"]' ).val( '1' );
2165 + $form.find( 'input[name="wpbc_setup_continue_after_save"]' ).val( '0' );
1737 2166 $form
1738 2167 .off( 'change.wpbc_setup_wizard input.wpbc_setup_wizard', ':input' )
1739 2168 .on( 'change.wpbc_setup_wizard input.wpbc_setup_wizard', ':input', function() {
1740 - if ( jQuery( this ).is( '[name="wpbc_setup_saved_step"],[name="wpbc_setup_step"],[name="wpbc_setup"],[name="form_visible_section"]' ) ) {
2169 + if ( jQuery( this ).is( '[name="wpbc_setup_saved_step"],[name="wpbc_setup_step"],[name="wpbc_setup"],[name="wpbc_setup_continue_after_save"],[name="form_visible_section"]' ) ) {
1741 2170 return;
1742 2171 }
1743 2172 wpbcSetupWizardSetUnsaved();
1744 2173 } );
@@ -1748,8 +2177,9 @@
1748 2177 wpbcSetupWizardSaveStarted();
1749 2178 $form.find( 'input[name="wpbc_setup_saved_step"]' ).val( step );
1750 2179 $form.find( 'input[name="wpbc_setup_step"]' ).val( step );
1751 2180 $form.find( 'input[name="wpbc_setup"]' ).val( '1' );
2181 + $form.find( 'input[name="wpbc_setup_continue_after_save"]' ).val( saveAndContinueRequested ? '1' : '0' );
1752 2182 } );
1753 2183 } );
1754 2184 }
1755 2185
@@ -1755,8 +2185,12 @@
1755 2185
1756 2186 $continueButton.on( 'click', function( event ) {
1757 2187 if ( '1' !== $bar.attr( 'data-wpbc-setup-is-saved' ) ) {
1758 2188 event.preventDefault();
2189 + if ( saveSelector ) {
2190 + wpbcSetupWizardTriggerSaveAndContinue();
2191 + return;
2192 + }
1759 2193 if ( typeof wpbc_admin_show_message === 'function' ) {
1760 2194 wpbc_admin_show_message( '<?php echo esc_js( __( 'Please save changes on this page before continuing setup.', 'booking' ) ); ?>', 'warning', 4000, false );
1761 2195 }
1762 2196 wpbcSetupWizardPulseSaveRequiredMessage();
@@ -1772,13 +2206,16 @@
1772 2206 }
1773 2207 } );
1774 2208 }
1775 2209
1776 - jQuery( document ).ajaxComplete( function( _event, xhr ) {
2210 + jQuery( document ).ajaxComplete( function( _event, xhr, ajaxSettings ) {
1777 2211 var response;
1778 2212 if ( ! saveClicked ) {
1779 2213 return;
1780 2214 }
2215 + if ( ! wpbcSetupWizardIsExpectedSaveAjax( ajaxSettings ) ) {
2216 + return;
2217 + }
1781 2218 saveClicked = false;
1782 2219
1783 2220 response = xhr && xhr.responseJSON ? xhr.responseJSON : null;
1784 2221 if ( ! response && xhr && xhr.responseText ) {
@@ -1787,25 +2224,51 @@
1787 2224 } catch ( _e ) {}
1788 2225 }
1789 2226 if ( response && response.data && response.data.setup_step_saved ) {
1790 2227 wpbcSetupWizardSetSaved();
2228 + if ( saveAndContinueRequested ) {
2229 + wpbcSetupWizardContinueAfterSave();
2230 + }
1791 2231 } else if ( wpbcSetupWizardLooksSuccessfulResponse( response ) ) {
1792 - wpbcSetupWizardMarkSaved();
2232 + if ( saveAndContinueRequested ) {
2233 + wpbcSetupWizardMarkSaved( wpbcSetupWizardContinueAfterSave );
2234 + } else {
2235 + wpbcSetupWizardMarkSaved();
2236 + }
2237 + } else if ( saveAndContinueRequested ) {
2238 + wpbcSetupWizardSetSaveAndContinueBusy( false );
2239 + saveAndContinueRequested = false;
1793 2240 }
1794 2241 } );
1795 2242 }
1796 2243
2244 + if ( highlightDisabled ) {
2245 + highlightSelector = '';
2246 + }
2247 +
1797 2248 if ( ! selector && ! scrollSelector && ! highlightSelector ) {
1798 2249 return;
1799 2250 }
1800 2251
1801 - $target = wpbcSetupWizardGetFirstElement( highlightSelector || selector );
1802 - if ( $target.length ) {
1803 - wpbcSetupWizardHighlightElement( $target );
2252 + if ( ! highlightDisabled && highlightAll ) {
2253 + try {
2254 + $highlightTargets = jQuery( highlightSelector || selector ).filter( ':visible' );
2255 + } catch ( _e ) {
2256 + $highlightTargets = jQuery();
2257 + }
2258 +
2259 + $highlightTargets.each( function() {
2260 + wpbcSetupWizardHighlightElement( jQuery( this ) );
2261 + } );
2262 + } else if ( ! highlightDisabled ) {
2263 + $highlightTargets = wpbcSetupWizardGetFirstElement( highlightSelector || selector );
2264 + wpbcSetupWizardHighlightElement( $highlightTargets );
1804 2265 }
1805 2266
2267 + $target = $highlightTargets.first();
2268 +
1806 2269 setTimeout( function() {
1807 - var $scrollTarget = wpbcSetupWizardGetFirstElement( scrollSelector || highlightSelector || selector );
2270 + var $scrollTarget = wpbcSetupWizardGetFirstElement( scrollSelector || ( highlightDisabled ? selector : highlightSelector ) || selector );
1808 2271 if ( ! $scrollTarget.length ) {
1809 2272 $scrollTarget = $target;
1810 2273 }
1811 2274 wpbcSetupWizardScrollToElement( $scrollTarget );