PluginProbe
Booking Calendar / 11.8.3
Booking Calendar v11.8.3
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 +1929 -142 10.10.211.8.3 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
@@ -16,21 +16,80 @@
16 16 class WPBC_SETUP_WIZARD_STEPS {
17 17
18 18 private $steps_arr = array();
19 19
20 - public function __construct() {
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;
21 29
22 - if ( WPBC()->is_wp_inited() ) {
30 + /**
31 + * Whether the setup bar render hook has already been registered.
32 + *
33 + * This class is also used as a setup-state helper in AJAX and routing code, so multiple instances can exist during
34 + * one request. Only one of them should render the floating setup bar.
35 + *
36 + * @var bool
37 + */
38 + private static $is_top_bar_hook_registered = false;
39 +
40 + /**
41 + * Whether the setup bar has already been printed in the current request.
42 + *
43 + * @var bool
44 + */
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() {
67 +
68 + if ( WPBC()->is_wp_inited() || did_action( 'init' ) ) {
23 69 $this->init_steps_data();
24 70 } else {
25 71 add_action( 'init', array( $this, 'init_steps_data' ) );
26 72 }
27 73
28 - add_action( 'wpbc_after_wpbc_page_top__header_tabs', array( $this, 'show_top_right_wizard_button' ), 10, 3 );
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 + }
29 78
30 79 }
31 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() {
32 87
88 + return ( WPBC()->is_wp_inited() || did_action( 'init' ) );
89 + }
90 +
91 +
33 92 /**
34 93 * Define Steps Data Structure - Init
35 94 *
36 95 * @return void
@@ -36,8 +95,10 @@
36 95 * @return void
37 96 */
38 97 public function init_steps_data(){
39 98
99 + $is_i18n_ready = $this->is_i18n_ready();
100 +
40 101 $step_default_params = array(
41 102 'show_section_left' => false,
42 103 'show_section_right' => false,
43 104 'is_done' => false,
@@ -43,102 +104,59 @@
43 104 'is_done' => false,
44 105 'do_action' => 'none',
45 106 'prior' => '',
46 107 'next' => '',
47 - 'prior_title' => __( 'Go Back', 'booking' ),
48 - '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'
49 110 );
50 111 $steps_arr = array();
51 112
113 + if ( function_exists( 'wpbc_setup_wizard__get_intro_route' ) ) {
114 + $route = wpbc_setup_wizard__get_intro_route();
115 + } else {
116 + $route = array( 'welcome' );
117 + if ( ! wpbc_is_this_demo() ) {
118 + $route[] = 'general_info';
119 + }
120 + $route[] = 'date_time_formats';
121 + $route[] = 'bookings_types';
122 + }
123 + $route = array_merge( $route, wpbc_setup_wizard__get_profile_route() );
52 124
53 - // Step #1
54 - $step_name = 'welcome';
55 - $steps_arr[ $step_name ] = $step_default_params;
56 - $steps_arr[ $step_name ]['do_action'] = 'save_and_continue__welcome';
57 - $steps_arr[ $step_name ]['next'] = ( wpbc_is_this_demo() ) ? 'date_time_formats' : 'general_info';
58 - //$steps_arr[ $step_name ]['next_title'] = __( 'Let\'s Get Started', 'booking' );
125 + foreach ( $route as $step_index => $step_name ) {
126 + $steps_arr[ $step_name ] = $step_default_params;
127 + $steps_arr[ $step_name ]['do_action'] = 'save_and_continue__' . $step_name;
128 + $steps_arr[ $step_name ]['prior'] = ( 0 === $step_index ) ? '' : $route[ $step_index - 1 ];
129 + $steps_arr[ $step_name ]['next'] = isset( $route[ $step_index + 1 ] ) ? $route[ $step_index + 1 ] : 'welcome';
59 130
60 - if ( ! wpbc_is_this_demo() ) {
61 - // Step #2
62 - $step_name = 'general_info';
63 - $steps_arr[ $step_name ] = $step_default_params;
64 - $steps_arr[ $step_name ]['do_action'] = 'save_and_continue__general_info';
65 - //$steps_arr[ $step_name ]['prior'] = 'bookings_types';
66 - $steps_arr[ $step_name ]['next'] = 'date_time_formats';
131 + if ( $is_i18n_ready && function_exists( 'wpbc_setup_wizard__get_step_route_metadata' ) ) {
132 + $steps_arr[ $step_name ] = array_merge(
133 + $steps_arr[ $step_name ],
134 + wpbc_setup_wizard__get_step_route_metadata( $step_name )
135 + );
136 + }
67 137 }
68 138
69 - // Step #3
70 - $step_name = 'date_time_formats';
71 - $steps_arr[ $step_name ] = $step_default_params;
72 - $steps_arr[ $step_name ]['do_action'] = 'save_and_continue__date_time_formats';
73 - if ( ! wpbc_is_this_demo() ) {
74 - $steps_arr[ $step_name ]['prior'] = 'general_info';
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 ) {
140 + if ( isset( $steps_arr[ $continue_step_name ] ) ) {
141 + $steps_arr[ $continue_step_name ]['next_title'] = $is_i18n_ready ? __( 'Continue', 'booking' ) : 'Continue';
142 + }
75 143 }
76 - $steps_arr[ $step_name ]['next'] = 'bookings_types';
77 144
78 - // Step #4
79 - $step_name = 'bookings_types';
80 - $steps_arr[ $step_name ] = $step_default_params;
81 - $steps_arr[ $step_name ]['do_action'] = 'save_and_continue__bookings_types';
82 - $steps_arr[ $step_name ]['prior'] = 'date_time_formats';
83 - $steps_arr[ $step_name ]['next'] = 'form_structure';
145 + $this->steps_arr = $steps_arr;
146 + $this->is_steps_data_initialized = true;
147 + }
84 148
85 - // Step #5
86 - $step_name = 'form_structure';
87 - $steps_arr[ $step_name ] = $step_default_params;
88 - $steps_arr[ $step_name ]['do_action'] = 'save_and_continue__form_structure';
89 - $steps_arr[ $step_name ]['prior'] = 'bookings_types';
90 - $steps_arr[ $step_name ]['next'] = 'cal_availability';
91 - $steps_arr[ $step_name ]['next_title'] = __( 'Continue', 'booking' );
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() {
92 155
93 - // Step #6
94 - $step_name = 'cal_availability';
95 - $steps_arr[ $step_name ] = $step_default_params;
96 - $steps_arr[ $step_name ]['do_action'] = 'save_and_continue__cal_availability';
97 - $steps_arr[ $step_name ]['prior'] = 'form_structure';
98 - $steps_arr[ $step_name ]['next'] = 'color_theme';
99 - $steps_arr[ $step_name ]['next_title'] = __( 'Continue', 'booking' );
100 -
101 - // Step #7
102 - $step_name = 'color_theme';
103 - $steps_arr[ $step_name ] = $step_default_params;
104 - $steps_arr[ $step_name ]['do_action'] = 'save_and_continue__color_theme';
105 - $steps_arr[ $step_name ]['prior'] = 'cal_availability';
106 - $steps_arr[ $step_name ]['next'] = 'optional_other_settings';
107 -
108 - // Step #8
109 - $step_name = 'optional_other_settings';
110 - $steps_arr[ $step_name ] = $step_default_params;
111 - //$steps_arr[ $step_name ]['show_section_left'] = true;
112 - //$steps_arr[ $step_name ]['show_section_right'] = true;
113 - $steps_arr[ $step_name ]['do_action'] = 'save_and_continue__optional_other_settings';
114 - $steps_arr[ $step_name ]['prior'] = 'color_theme';
115 - $steps_arr[ $step_name ]['next'] = ( wpbc_is_this_demo() ) ? 'get_started' : 'wizard_publish';
116 - $steps_arr[ $step_name ]['next_title'] = __( 'Continue', 'booking' );
117 -
118 - if ( ! wpbc_is_this_demo() ) {
119 - // Step #9
120 - $step_name = 'wizard_publish';
121 - $steps_arr[ $step_name ] = $step_default_params;
122 - //$steps_arr[ $step_name ]['show_section_left'] = true;
123 - //$steps_arr[ $step_name ]['show_section_right'] = true;
124 - $steps_arr[ $step_name ]['do_action'] = 'save_and_continue__wizard_publish';
125 - $steps_arr[ $step_name ]['prior'] = 'optional_other_settings';
126 - $steps_arr[ $step_name ]['next'] = 'get_started';
127 - $steps_arr[ $step_name ]['next_title'] = __( 'Continue', 'booking' );
156 + if ( ! $this->is_steps_data_initialized ) {
157 + $this->init_steps_data();
128 158 }
129 -
130 - // Step #10
131 - $step_name = 'get_started';
132 - $steps_arr[ $step_name ] = $step_default_params;
133 - //$steps_arr[ $step_name ]['show_section_left'] = true;
134 - //$steps_arr[ $step_name ]['show_section_right'] = true;
135 - $steps_arr[ $step_name ]['do_action'] = 'save_and_continue__get_started';
136 - $steps_arr[ $step_name ]['prior'] = ( wpbc_is_this_demo() ) ? 'optional_other_settings' : 'wizard_publish';
137 - $steps_arr[ $step_name ]['next'] = 'welcome';
138 - //$steps_arr[ $step_name ]['next_title'] = __( 'Complete', 'booking' );
139 -
140 - $this->steps_arr = $steps_arr;
141 159 }
142 160
143 161 /**
144 162 * Get Steps Data Structure
@@ -144,9 +162,11 @@
144 162 * Get Steps Data Structure
145 163 * @return array
146 164 */
147 165 public function get_steps_arr(){
148 - return $this->steps_arr;
166 + $this->ensure_steps_data_initialized();
167 +
168 + return $this->steps_arr;
149 169 }
150 170
151 171
152 172 // =================================================================================================================
@@ -153,9 +173,9 @@
153 173 // == Steps STRUCTURE ==
154 174 // =================================================================================================================
155 175
156 176 /**
157 - * Actual Step Number -> 'general_info' or 'optional_other_settings'
177 + * Actual Step Number -> 'general_info' or 'date_availability'
158 178 *
159 179 * @return int
160 180 */
161 181 public function get_active_step_name() {
@@ -179,23 +199,292 @@
179 199 * Actual Step Number -> 2
180 200 *
181 201 * @return int
182 202 */
183 - public function get_active_step_num() {
203 + public function get_active_step_num( $current_step = '' ) {
184 204
185 - $steps_arr = $this->db__get_steps_is_done();
186 - $active_step = 0;
205 + if ( ! empty( $current_step ) ) {
206 + return $this->get_step_num_by_name( $current_step );
207 + }
208 +
209 + $steps_arr = $this->db__get_steps_is_done();
210 + $total_steps = count( $steps_arr );
211 + $completed_steps = 0;
212 +
187 213 foreach ( $steps_arr as $step ) {
214 + if ( ! empty( $step ) ) {
215 + $completed_steps++;
216 + }
217 + }
188 218
189 - if ( ! empty( $step ) ) {
190 - $active_step++;
219 + if ( $completed_steps >= $total_steps ) {
220 + return $total_steps;
221 + }
222 +
223 + return min( $completed_steps + 1, $total_steps );
224 + }
225 +
226 + /**
227 + * Get Step Number by step name.
228 + *
229 + * @param string $current_step Step name.
230 + *
231 + * @return int
232 + */
233 + public function get_step_num_by_name( $current_step ) {
234 +
235 + $step_num = 1;
236 +
237 + foreach ( array_keys( $this->get_steps_arr() ) as $step_name ) {
238 + if ( $step_name === $current_step ) {
239 + return $step_num;
191 240 }
241 + $step_num++;
192 242 }
193 - return $active_step;
243 +
244 + return 1;
194 245 }
195 246
247 + /**
248 + * Get the last wizard step saved in the setup wizard request history.
249 + *
250 + * @return string
251 + */
252 + public function get_saved_current_step_name() {
196 253
254 + $steps_arr = $this->get_steps_arr();
255 + $current_step = $this->get_active_step_name();
256 +
257 + if ( function_exists( 'wpbc_setup_wizard_page__get_cleaned_params__saved_request_default' ) ) {
258 + $saved_request_params = wpbc_setup_wizard_page__get_cleaned_params__saved_request_default();
259 +
260 + if (
261 + is_array( $saved_request_params )
262 + && ( ! empty( $saved_request_params['current_step'] ) )
263 + && isset( $steps_arr[ $saved_request_params['current_step'] ] )
264 + ) {
265 + $current_step = $saved_request_params['current_step'];
266 + }
267 + }
268 +
269 + return $current_step;
270 + }
271 +
197 272 /**
273 + * Get target URL for a setup step.
274 + *
275 + * @param string $step_name Step name.
276 + *
277 + * @return string
278 + */
279 + public function get_step_target_url( $step_name ) {
280 +
281 + $steps_arr = $this->get_steps_arr();
282 +
283 + if ( isset( $steps_arr[ $step_name ]['target_url'] ) && ( ! empty( $steps_arr[ $step_name ]['target_url'] ) ) ) {
284 + return $steps_arr[ $step_name ]['target_url'];
285 + }
286 +
287 + return function_exists( 'wpbc_setup_wizard__get_step_target_url' )
288 + ? wpbc_setup_wizard__get_step_target_url( $step_name )
289 + : wpbc_get_setup_wizard_page_url();
290 + }
291 +
292 + /**
293 + * Get Continue URL for the floating setup bar.
294 + *
295 + * @param string $step_name Step name.
296 + *
297 + * @return string
298 + */
299 + public function get_step_continue_url( $step_name ) {
300 +
301 + return function_exists( 'wpbc_setup_wizard__get_step_continue_url' )
302 + ? wpbc_setup_wizard__get_step_continue_url( $step_name )
303 + : $this->get_step_target_url( $step_name );
304 + }
305 +
306 + /**
307 + * Get step name from setup URL context or first incomplete setup step.
308 + *
309 + * @return string
310 + */
311 + public function get_context_step_name() {
312 +
313 + $steps_arr = $this->get_steps_arr();
314 + $current_step = $this->get_saved_current_step_name();
315 +
316 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
317 + if ( isset( $_REQUEST['wpbc_setup_step'] ) ) {
318 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
319 + $request_step = sanitize_key( wp_unslash( $_REQUEST['wpbc_setup_step'] ) );
320 + if ( isset( $steps_arr[ $request_step ] ) ) {
321 + $current_step = $request_step;
322 + $this->db__save_current_step_name( $current_step );
323 + return $current_step;
324 + }
325 + }
326 +
327 + if ( $this->db__is_step_completed( 'bookings_types' ) && function_exists( 'wpbc_setup_wizard__detect_step_from_admin_request' ) ) {
328 + $detected_step = wpbc_setup_wizard__detect_step_from_admin_request();
329 + if ( ! empty( $detected_step ) && isset( $steps_arr[ $detected_step ] ) ) {
330 + $current_step = $detected_step;
331 + $this->db__save_current_step_name( $current_step );
332 + return $current_step;
333 + }
334 + }
335 +
336 + return $current_step;
337 + }
338 +
339 + /**
340 + * Save the current setup step into the per-user wizard request state.
341 + *
342 + * @param string $step_name Step name.
343 + *
344 + * @return bool
345 + */
346 + public function db__save_current_step_name( $step_name ) {
347 +
348 + $steps_arr = $this->get_steps_arr();
349 + if ( empty( $step_name ) || ! isset( $steps_arr[ $step_name ] ) || ! function_exists( 'wpbc_setup_wizard_page__request_rules_structure' ) ) {
350 + return false;
351 + }
352 +
353 + $request_params_to_save = function_exists( 'wpbc_setup_wizard_page__get_cleaned_params__saved_request_default' )
354 + ? wpbc_setup_wizard_page__get_cleaned_params__saved_request_default()
355 + : array();
356 +
357 + if ( ! is_array( $request_params_to_save ) || empty( $request_params_to_save ) ) {
358 + $request_params_to_save = function_exists( 'wpbc_setup_wizard_page__get__request_values__default' )
359 + ? wpbc_setup_wizard_page__get__request_values__default()
360 + : array();
361 + }
362 +
363 + $request_params_to_save['current_step'] = $step_name;
364 +
365 + $user_request = new WPBC_AJX__REQUEST( array(
366 + 'db_option_name' => 'booking_setup_wizard_page_request_params',
367 + 'user_id' => wpbc_get_current_user_id(),
368 + 'request_rules_structure' => wpbc_setup_wizard_page__request_rules_structure()
369 + )
370 + );
371 +
372 + return (bool) $user_request->user_request_params__db_save( $request_params_to_save );
373 + }
374 +
375 + /**
376 + * Get target URL for prior setup step.
377 + *
378 + * @param string $step_name Step name.
379 + *
380 + * @return string
381 + */
382 + public function get_step_prior_url( $step_name ) {
383 +
384 + $steps_arr = $this->get_steps_arr();
385 + $prior = isset( $steps_arr[ $step_name ]['prior'] ) ? $steps_arr[ $step_name ]['prior'] : '';
386 +
387 + return ( empty( $prior ) ) ? '' : $this->get_step_target_url( $prior );
388 + }
389 +
390 + /**
391 + * Get step title for setup bar.
392 + *
393 + * @param string $step_name Step name.
394 + *
395 + * @return string
396 + */
397 + public function get_step_title( $step_name ) {
398 +
399 + $steps_arr = $this->get_steps_arr();
400 +
401 + if ( isset( $steps_arr[ $step_name ]['title'] ) ) {
402 + return $steps_arr[ $step_name ]['title'];
403 + }
404 +
405 + return function_exists( 'wpbc_setup_wizard__get_step_title' )
406 + ? wpbc_setup_wizard__get_step_title( $step_name )
407 + : $step_name;
408 + }
409 +
410 + /**
411 + * Get action-oriented setup step heading.
412 + *
413 + * @param string $step_name Step name.
414 + *
415 + * @return string
416 + */
417 + public function get_step_heading( $step_name ) {
418 +
419 + $steps_arr = $this->get_steps_arr();
420 +
421 + if ( isset( $steps_arr[ $step_name ]['heading'] ) ) {
422 + return $steps_arr[ $step_name ]['heading'];
423 + }
424 +
425 + return function_exists( 'wpbc_setup_wizard__get_step_heading' )
426 + ? wpbc_setup_wizard__get_step_heading( $step_name )
427 + : $this->get_step_title( $step_name );
428 + }
429 +
430 + /**
431 + * Get setup step description.
432 + *
433 + * @param string $step_name Step name.
434 + *
435 + * @return string
436 + */
437 + public function get_step_description( $step_name ) {
438 +
439 + $steps_arr = $this->get_steps_arr();
440 +
441 + if ( isset( $steps_arr[ $step_name ]['description'] ) ) {
442 + return $steps_arr[ $step_name ]['description'];
443 + }
444 +
445 + return function_exists( 'wpbc_setup_wizard__get_step_description' )
446 + ? wpbc_setup_wizard__get_step_description( $step_name )
447 + : '';
448 + }
449 +
450 + /**
451 + * Get setup step save behavior.
452 + *
453 + * @param string $step_name Step name.
454 + *
455 + * @return string
456 + */
457 + public function get_step_save_behavior( $step_name ) {
458 +
459 + $steps_arr = $this->get_steps_arr();
460 +
461 + if ( isset( $steps_arr[ $step_name ]['save_behavior'] ) ) {
462 + return $steps_arr[ $step_name ]['save_behavior'];
463 + }
464 +
465 + return function_exists( 'wpbc_setup_wizard__get_step_save_behavior' )
466 + ? wpbc_setup_wizard__get_step_save_behavior( $step_name )
467 + : 'link_only';
468 + }
469 +
470 + /**
471 + * Get route metadata value.
472 + *
473 + * @param string $step_name Step name.
474 + * @param string $key Metadata key.
475 + *
476 + * @return string
477 + */
478 + public function get_step_meta_value( $step_name, $key ) {
479 +
480 + $steps_arr = $this->get_steps_arr();
481 +
482 + return ( isset( $steps_arr[ $step_name ][ $key ] ) ) ? (string) $steps_arr[ $step_name ][ $key ] : '';
483 + }
484 +
485 +
486 + /**
198 487 * Get Steps Count -> 9
199 488 *
200 489 * @return int
201 490 */
@@ -210,11 +499,16 @@
210 499 /**
211 500 * Get % Progress for Setup Steps -> 30
212 501 * @return int
213 502 */
214 - public function get_progess_value() {
503 + public function get_progess_value( $current_step = '' ) {
215 504
216 - $progess_value = ( ($this->get_active_step_num()-0) * 100 ) / $this->get_total_steps_count();
505 + $total_steps = $this->get_total_steps_count();
506 + if ( $total_steps <= 0 ) {
507 + return 0;
508 + }
509 +
510 + $progess_value = ( $this->get_active_step_num( $current_step ) * 100 ) / $total_steps;
217 511 $progess_value = intval( $progess_value );
218 512
219 513 return $progess_value;
220 514 }
@@ -235,31 +529,26 @@
235 529 */
236 530 public function db__get_steps_is_done() {
237 531
238 532 $steps_is_done = get_bk_option( 'booking_setup_wizard_page_steps_is_done' );
533 + $is_completed = ( 'On' === get_bk_option( 'booking_setup_wizard_page_is_completed' ) );
239 534
240 - if ( empty( $steps_is_done ) ) {
241 - // Get Default Steps from the Steps structure
535 + $active_steps_names = array_keys( $this->get_steps_arr() );
536 + $normalized_steps = array();
242 537
243 - $steps_names = $this->get_steps_arr();
244 - $steps_names = array_keys( $steps_names );
538 + if ( empty( $active_steps_names ) ) {
539 + return is_array( $steps_is_done ) ? $steps_is_done : array();
540 + }
245 541
246 - $steps_values = array_fill( 0, count( $steps_names ), false );
247 - $steps_is_done = array_combine( $steps_names, $steps_values );
248 - } else {
542 + foreach ( $active_steps_names as $step_name ) {
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 );
544 + }
249 545
250 - // Check if some new steps here ?
251 - $possible_new_steps_names = $this->get_steps_arr();
252 - $possible_new_steps_names = array_keys( $possible_new_steps_names );
253 - foreach ( $possible_new_steps_names as $possible_new_steps_name ) {
254 - if ( ! isset( $steps_is_done[ $possible_new_steps_name ] ) ) {
255 - $steps_is_done[ $possible_new_steps_name ] = false;
256 - }
257 - }
258 -
546 + if ( $steps_is_done !== $normalized_steps ) {
547 + $this->db__save_steps_is_done( $normalized_steps );
259 548 }
260 549
261 - return $steps_is_done;
550 + return $normalized_steps;
262 551 }
263 552
264 553
265 554 /**
@@ -286,8 +575,13 @@
286 575
287 576 $steps_arr[ $step_name ] = true;
288 577
289 578 $this->db__save_steps_is_done( $steps_arr );
579 + $this->db__set_step_as_saved( $step_name, true );
580 +
581 + if ( ! in_array( false, $steps_arr, true ) ) {
582 + update_bk_option( 'booking_setup_wizard_page_is_completed', 'On' );
583 + }
290 584 }
291 585
292 586 /**
293 587 * Set specific step as Uncompleted
@@ -301,12 +595,54 @@
301 595 $steps_arr = $this->db__get_steps_is_done();
302 596
303 597 $steps_arr[ $step_name ] = false;
304 598
599 + delete_bk_option( 'booking_setup_wizard_page_is_completed' );
600 +
305 601 $this->db__save_steps_is_done( $steps_arr );
306 602 }
307 603
308 604 /**
605 + * Reset a step and all following steps in the active route.
606 + *
607 + * Older wizard versions could leave later steps marked as completed, which made the continue handler think setup
608 + * was finished too early after Step 5.
609 + *
610 + * @param string $first_step_name First step to reset.
611 + *
612 + * @return bool
613 + */
614 + public function db__reset_steps_from( $first_step_name ) {
615 +
616 + $steps_is_done = $this->db__get_steps_is_done();
617 + $steps_is_saved = $this->db__get_steps_is_saved();
618 + $should_reset = false;
619 +
620 + if ( ! array_key_exists( $first_step_name, $steps_is_done ) ) {
621 + return false;
622 + }
623 +
624 + foreach ( array_keys( $steps_is_done ) as $step_name ) {
625 + if ( $first_step_name === $step_name ) {
626 + $should_reset = true;
627 + }
628 +
629 + if ( $should_reset ) {
630 + $steps_is_done[ $step_name ] = false;
631 + if ( array_key_exists( $step_name, $steps_is_saved ) ) {
632 + $steps_is_saved[ $step_name ] = false;
633 + }
634 + }
635 + }
636 +
637 + delete_bk_option( 'booking_setup_wizard_page_is_completed' );
638 + $this->db__save_steps_is_done( $steps_is_done );
639 + $this->db__save_steps_is_saved( $steps_is_saved );
640 +
641 + return true;
642 + }
643 +
644 + /**
309 645 * Check if specific step 'Is completed' ?
310 646 *
311 647 * @param string $step_name
312 648 *
@@ -334,8 +670,11 @@
334 670 public function db__set_all_steps_as( $is_completed = true ) {
335 671
336 672 if ( false === $is_completed ) {
337 673 delete_bk_option( 'booking_setup_wizard_page_steps_is_done' );
674 + delete_bk_option( 'booking_setup_wizard_page_is_completed' );
675 + } else {
676 + update_bk_option( 'booking_setup_wizard_page_is_completed', 'On' );
338 677 }
339 678
340 679 $steps_names = $this->db__get_steps_is_done();
341 680
@@ -344,18 +683,99 @@
344 683 $steps_is_done = array_combine( $steps_names, $steps_values );
345 684
346 685 // Set all steps as not completed
347 686 $this->db__save_steps_is_done( $steps_is_done );
687 + $this->db__save_steps_is_saved( $steps_is_done );
348 688 }
349 689
350 690 /**
691 + * Get saved state for setup steps.
692 + *
693 + * @return array
694 + */
695 + public function db__get_steps_is_saved() {
696 +
697 + $steps_is_saved = get_bk_option( 'booking_setup_wizard_page_steps_is_saved' );
698 + $is_completed = ( 'On' === get_bk_option( 'booking_setup_wizard_page_is_completed' ) );
699 + $normalized = array();
700 +
701 + foreach ( array_keys( $this->get_steps_arr() ) as $step_name ) {
702 + $normalized[ $step_name ] = $is_completed ? true : ( ( is_array( $steps_is_saved ) && isset( $steps_is_saved[ $step_name ] ) ) ? (bool) $steps_is_saved[ $step_name ] : false );
703 + }
704 +
705 + if ( $steps_is_saved !== $normalized ) {
706 + $this->db__save_steps_is_saved( $normalized );
707 + }
708 +
709 + return $normalized;
710 + }
711 +
712 + /**
713 + * Save setup step saved states.
714 + *
715 + * @param array $steps_arr Saved states.
716 + *
717 + * @return void
718 + */
719 + public function db__save_steps_is_saved( $steps_arr ) {
720 + update_bk_option( 'booking_setup_wizard_page_steps_is_saved', $steps_arr );
721 + }
722 +
723 + /**
724 + * Mark a setup step as saved or unsaved.
725 + *
726 + * @param string $step_name Step name.
727 + * @param bool $is_saved Saved flag.
728 + *
729 + * @return bool
730 + */
731 + public function db__set_step_as_saved( $step_name, $is_saved = true ) {
732 +
733 + $steps_arr = $this->db__get_steps_is_saved();
734 + if ( ! array_key_exists( $step_name, $steps_arr ) ) {
735 + return false;
736 + }
737 +
738 + $steps_arr[ $step_name ] = (bool) $is_saved;
739 + $this->db__save_steps_is_saved( $steps_arr );
740 +
741 + return true;
742 + }
743 +
744 + /**
745 + * Check whether a setup step has been saved.
746 + *
747 + * @param string $step_name Step name.
748 + *
749 + * @return bool
750 + */
751 + public function db__is_step_saved( $step_name ) {
752 +
753 + if ( 'manual_save_required' !== $this->get_step_save_behavior( $step_name ) ) {
754 + return true;
755 + }
756 +
757 + $steps_arr = $this->db__get_steps_is_saved();
758 +
759 + return ! empty( $steps_arr[ $step_name ] );
760 + }
761 +
762 + /**
351 763 * Check Is all steps Completed
352 764 * @return bool
353 765 */
354 766 public function db__is_all_steps_completed() {
355 767
768 + if ( 'On' === get_bk_option( 'booking_setup_wizard_page_is_completed' ) ) {
769 + return true;
770 + }
771 +
356 772 $steps_arr = $this->db__get_steps_is_done();
357 773
774 + if ( empty( $steps_arr ) ) {
775 + return false;
776 + }
777 +
358 778 foreach ( $steps_arr as $step_name => $steps_val ) {
359 779 if ( empty( $steps_val ) ) {
360 780 return false;
361 781 }
@@ -378,23 +798,25 @@
378 798 * Main Left Menu Title - "Setup" with Progress Bar
379 799 *
380 800 * @return false|string
381 801 */
382 - public function get_plugin_menu_title__setup_progress(){
802 + public function get_plugin_menu_title__setup_progress( $current_step = '' ){
383 803
384 804
805 + $current_step_for_progress = ( ! empty( $current_step ) ) ? $current_step : $this->get_context_step_name();
806 +
385 807 ob_start();
386 808
387 809 ?><div class="setup_wizard_page_container" style="display: flex;flex-flow: row wrap;justify-content: flex-start;align-items: center;color: #fff;margin: 0 -5px 0 0;overflow: visible;">
388 810 <div class="name_item" style="margin-top: 0;white-space: nowrap;padding: 0 0 0 0;"><?php esc_html_e( 'Setup', 'booking' ); ?></div>
389 - <div style="margin:3px 0px 0 0;margin-left: auto;font-size: 9px;background: #2271b1;height: 15px;" class="wpbc_badge_count name_item update-plugins">
811 + <div style="margin:3px 0px 0 0;margin-left: auto;font-size: 9px;background: var(--wpbc_admin-theme-color, #2271b1);height: 15px;" class="wpbc_badge_count name_item update-plugins">
390 812 <span class="update-count" style="white-space: nowrap;word-wrap: normal;"><?php
391 - echo esc_html( $this->get_active_step_num() . ' / ' . $this->get_total_steps_count() );
813 + echo esc_html( $this->get_active_step_num( $current_step_for_progress ) . ' / ' . $this->get_total_steps_count() );
392 814 ?></span>
393 815 </div>
394 816 <div class="progress_line_container" style="width: 100%;border: 0px solid #757575;height: 3px;border-radius: 6px;margin: 7px 0 -3px -3px;overflow: hidden;background: #555;">
395 817 <div class="progress_line" style="font-size: 6px;font-weight: 600;word-wrap: normal;border-radius: 6px;white-space: nowrap;background: #8ECE01;width: <?php
396 - echo esc_html( $this->get_progess_value() ); ?>%;height: 3px;"></div>
818 + echo esc_html( $this->get_progess_value( $current_step_for_progress ) ); ?>%;height: 3px;"></div>
397 819 </div>
398 820 </div><?php
399 821
400 822 return ob_get_clean();
@@ -409,42 +831,142 @@
409 831 *
410 832 * Show Continue Setup Wizard Button
411 833 * @return void
412 834 */
413 - 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;
414 843
415 - 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 + }
416 852
417 853 if (
418 854 ( ! wpbc_is_user_can_access_wizard_page() ) ||
419 - ( $this->db__is_all_steps_completed() )
420 - ){
855 + ( $this->db__is_all_steps_completed() && ! $explicit_step_context )
856 + ) {
421 857 return false;
422 858 }
423 859
424 - ?><style tye="text/css">
860 + if ( self::$is_top_bar_rendered ) {
861 + return false;
862 + }
863 + self::$is_top_bar_rendered = true;
864 +
865 + $current_step = $this->get_context_step_name();
866 + $is_external_setup_flow_started = $this->db__is_step_completed( 'bookings_types' );
867 + $detected_page_step = ( $is_external_setup_flow_started && function_exists( 'wpbc_setup_wizard__detect_step_from_admin_request' ) )
868 + ? wpbc_setup_wizard__detect_step_from_admin_request()
869 + : '';
870 + $continue_url = $this->get_step_continue_url( $current_step );
871 + if ( ! empty( $detected_page_step ) && isset( $this->steps_arr[ $detected_page_step ] ) ) {
872 + $continue_url = add_query_arg( 'wpbc_setup_from_page_step', $detected_page_step, $continue_url );
873 + }
874 + $prior_url = $this->get_step_prior_url( $current_step );
875 + $step_title = $this->get_step_title( $current_step );
876 + $step_heading = $this->get_step_heading( $current_step );
877 + $step_save_page_title = ( 'form_structure' === $current_step ) ? __( 'Form Builder', 'booking' ) : $step_title;
878 + $description = $this->get_step_description( $current_step );
879 + $save_behavior = $this->get_step_save_behavior( $current_step );
880 + $target_selector = $this->get_step_meta_value( $current_step, 'target_selector' );
881 + $scroll_selector = $this->get_step_meta_value( $current_step, 'scroll_selector' );
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' );
885 + $form_selector = $this->get_step_meta_value( $current_step, 'form_selector' );
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' );
888 + $save_events = $this->get_step_meta_value( $current_step, 'save_events' );
889 + $open_action = $this->get_step_meta_value( $current_step, 'open_action' );
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;
901 + $mark_saved_nonce = wp_create_nonce( 'wpbc_setup_wizard_mark_step_saved' );
902 + $step_target_url = $this->get_step_target_url( $current_step );
903 + $skip_wizard_url = add_query_arg( 'wpbc_setup_wizard', 'completed', wpbc_get_bookings_url() );
904 + $reset_wizard_url = add_query_arg( 'wpbc_setup_wizard', 'reset', wpbc_get_setup_wizard_page_url() );
905 + $save_required_note = sprintf(
906 + /* translators: %s: setup target page title. */
907 + __( 'Save changes on the %s page before continuing.', 'booking' ),
908 + '<a href="' . esc_url( $step_target_url ) . '">' . esc_html( $step_save_page_title ) . '</a>'
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();
914 +
915 + // FixIn: 10.12.1.1.
916 + ?><style type="text/css">
425 917 @media screen and (max-width: 782px) {
426 918 .ui_element.wpbc_page_top__wizard_button {
427 - top: 49px !important;
919 + /*top: 49px !important;*/
428 920 }
429 921 }
430 - .wpbc_header_news{
922 + .wp-admin.wpbc_admin_full_screen .wpbc_header_news {
431 923 display: none !important;
432 924 }
433 - .wpbc_admin_full_screen .wpbc_page_top__wizard_button {
434 - display: none;
435 - }
436 925 .wpbc_page_top__wizard_button {
437 926 width: auto;
927 + min-width: 330px;
928 + max-width: min(420px, calc(100vw - 30px));
438 929 position: fixed;
439 - z-index: 90000;
930 + z-index: 150000;
440 931 box-shadow: 0 0 10px #c1c1c1;
441 932 border-radius: 9px;
442 933 background: transparent;
443 - right: 20px;
444 - top: 40px;
934 + right: 15px;
935 + top: auto !important;
936 + bottom: 15px !important;
445 937 }
446 -
938 + .wpbc_page_top__wizard_button.wpbc_setup_wizard_bar_is_moved {
939 + left: var(--wpbc-setup-bar-left, auto) !important;
940 + top: auto !important;
941 + right: auto !important;
942 + bottom: var(--wpbc-setup-bar-bottom, auto) !important;
943 + }
944 + .wpbc_page_top__wizard_button.wpbc_setup_wizard_bar_auto_shifted {
945 + left: auto !important;
946 + top: auto !important;
947 + right: var(--wpbc-setup-bar-auto-right, 15px) !important;
948 + bottom: 15px !important;
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 + }
956 + .wpbc_page_top__wizard_button.wpbc_setup_wizard_bar_is_dragging {
957 + user-select: none;
958 + }
959 + .wpbc_page_top__wizard_button.wpbc_setup_wizard_bar_collapsed {
960 + min-width: 260px;
961 + }
962 + .wpbc_page_top__wizard_button.wpbc_setup_wizard_bar_collapsed .wpbc_setup_wizard_bar_expandable {
963 + display: none !important;
964 + }
965 + div .wpbc_admin_page__tab__builder_booking_form .wpbc_page_top__wizard_button {
966 + top: calc(var(--wpbc_ui_top_nav__wp_top_menu_height) + var(--wpbc_ui_top_nav__height) + 10px) !important;
967 + top: auto !important;
968 + }
447 969 .ui_element.wpbc_page_top__wizard_button .wpbc_page_top__wizard_button_content,
448 970 .ui_element.wpbc_page_top__wizard_button .wpbc_page_top__wizard_button_content:hover {
449 971 border-radius: 5px;
450 972 border: none;
@@ -454,41 +976,1306 @@
454 976 color: #fff;
455 977 font-weight: 600;
456 978 padding: 8px 10px 8px 15px;
457 979 display: flex;
980 + flex-flow: column nowrap;
981 + justify-content: flex-start;
982 + align-items: stretch;
983 + gap: 8px;
984 + }
985 + .wpbc_setup_wizard_bar_title_row {
986 + display: flex;
458 987 flex-flow: row nowrap;
459 988 justify-content: flex-start;
460 989 align-items: center;
990 + gap: 8px;
991 + width: 100%;
992 + border-bottom: 2px solid #686868;
993 + padding-bottom: 8px;
994 + margin-bottom: 10px;
461 995 }
996 + .wpbc_setup_wizard_bar_title {
997 + flex: 1 1 auto;
998 + min-width: 0;
999 + white-space: nowrap;
1000 + overflow: hidden;
1001 + text-overflow: ellipsis;
1002 + margin-top: 0;
1003 + padding: 0;
1004 + }
1005 + .wpbc_setup_wizard_bar_header_actions {
1006 + display: flex;
1007 + flex: 0 0 auto;
1008 + flex-flow: row nowrap;
1009 + align-items: center;
1010 + gap: 2px;
1011 + margin-left: auto;
1012 + }
1013 + .wpbc_setup_wizard_bar_icon_button {
1014 + display: inline-flex;
1015 + align-items: center;
1016 + justify-content: center;
1017 + width: 24px;
1018 + height: 24px;
1019 + min-width: 24px;
1020 + min-height: 24px;
1021 + border: 0;
1022 + border-radius: 4px;
1023 + background: transparent;
1024 + color: #fff;
1025 + cursor: pointer;
1026 + padding: 0;
1027 + margin: 0;
1028 + }
1029 + .wpbc_setup_wizard_bar_icon_button:hover,
1030 + .wpbc_setup_wizard_bar_icon_button:focus {
1031 + background: rgba(255,255,255,0.16);
1032 + color: #fff;
1033 + outline: none;
1034 + box-shadow: none;
1035 + }
1036 + .wpbc_setup_wizard_bar_drag_handle {
1037 + cursor: move;
1038 + }
1039 + .wpbc_page_top__wizard_button_actions {
1040 + display: flex;
1041 + flex-flow: row nowrap;
1042 + justify-content: flex-end;
1043 + align-items: center;
1044 + gap: 8px;
1045 + }
1046 + .wpbc_page_top__wizard_button_actions .button {
1047 + font-size: 11px;
1048 + min-height: 10px;
1049 + line-height: 1.8;
1050 + margin: 0;
1051 + }
1052 + .wpbc_page_top__wizard_button_actions .button.button-secondary {
1053 + background-color: #e4e4e4;
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 + }
1089 + .wpbc_page_top__wizard_button_actions .button.disabled,
1090 + .wpbc_page_top__wizard_button_actions .button[aria-disabled="true"] {
1091 + cursor: not-allowed;
1092 + opacity: 0.55;
1093 + pointer-events: auto;
1094 + }
1095 + .wpbc_page_top__wizard_button_links {
1096 + display: flex;
1097 + flex-flow: row wrap;
1098 + justify-content: flex-start;
1099 + align-items: center;
1100 + gap: 1.5em;
1101 + font-size: 10px;
1102 + font-weight: 400;
1103 + line-height: 1.4;
1104 + margin-top: -2px;
1105 + }
1106 + .wpbc_page_top__wizard_button_links a {
1107 + color: #e6e6e6;
1108 + text-decoration: underline;
1109 + text-underline-offset: 2px;
1110 + }
1111 + .wpbc_page_top__wizard_button_links a:hover,
1112 + .wpbc_page_top__wizard_button_links a:focus {
1113 + color: #fff;
1114 + }
1115 + .wpbc_page_top__wizard_button_links a.wpbc_setup_wizard_bar_danger_link {
1116 + /*color: #ff9b00;*/
1117 + }
1118 + .wpbc_page_top__wizard_button_links a.wpbc_setup_wizard_bar_danger_link:hover,
1119 + .wpbc_page_top__wizard_button_links a.wpbc_setup_wizard_bar_danger_link:focus {
1120 + color: #fff;
1121 + }
1122 + .wpbc_page_top__wizard_button_note {
1123 + font-size: 12px;
1124 + font-weight: 400;
1125 + line-height: 1.35;
1126 + color: #fff;
1127 + background: rgb(160, 160, 95);
1128 + background: rgb(160, 132, 95);
1129 + background: rgb(160, 116, 95);
1130 + border-radius: 4px;
1131 + padding: 10px 14px;
1132 + margin: 8px 0 5px;
1133 + }
1134 + .wpbc_page_top__wizard_button_note a {
1135 + color: #fff;
1136 + text-decoration: underline;
1137 + text-underline-offset: 2px;
1138 + }
1139 + .wpbc_page_top__wizard_button_note.wpbc_setup_wizard_bar_note_saved {
1140 + background: #4f8f16;
1141 + }
1142 + .wpbc_setup_wizard_attention_pulse {
1143 + animation: wpbc_setup_wizard_attention_pulse 0.62s ease-in-out 3;
1144 + }
1145 + @keyframes wpbc_setup_wizard_attention_pulse {
1146 + 0% {
1147 + box-shadow: 0 0 0 0 rgba(255, 196, 0, 0.82);
1148 + transform: scale(1);
1149 + }
1150 + 50% {
1151 + box-shadow: 0 0 0 7px rgba(255, 196, 0, 0.2);
1152 + transform: scale(1.025);
1153 + }
1154 + 100% {
1155 + box-shadow: 0 0 0 0 rgba(255, 196, 0, 0);
1156 + transform: scale(1);
1157 + }
1158 + }
1159 + .wpbc_setup_wizard__target_highlight {
1160 + outline: 2px solid #8ECE01 !important;
1161 + outline-offset: 3px !important;
1162 + box-shadow: 0 0 0 5px rgba(142, 206, 1, 0.16) !important;
1163 + transition: outline-color 0.2s ease, box-shadow 0.2s ease;
1164 + }
1165 + @media screen and (max-width: 782px) {
1166 + .wpbc_page_top__wizard_button {
1167 + left: 10px !important;
1168 + right: 10px !important;
1169 + bottom: 10px !important;
1170 + top: auto !important;
1171 + min-width: 0;
1172 + max-width: none;
1173 + }
1174 + .wpbc_setup_wizard_bar_drag_handle,
1175 + .wpbc_setup_wizard_bar_reset_button {
1176 + display: none;
1177 + }
1178 + }
462 1179 </style>
463 - <div style="min-width: 240px;top: 35px;font-size: 15px;" class="ui_element wpbc_page_top__wizard_button">
1180 + <div style="top: 35px;font-size: 15px;"
1181 + class="ui_element wpbc_page_top__wizard_button"
1182 + data-wpbc-setup-step="<?php echo esc_attr( $current_step ); ?>"
1183 + data-wpbc-setup-save-behavior="<?php echo esc_attr( $save_behavior ); ?>"
1184 + data-wpbc-setup-is-saved="<?php echo esc_attr( $is_step_saved ? '1' : '0' ); ?>"
1185 + data-wpbc-setup-ajax-url="<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>"
1186 + data-wpbc-setup-mark-saved-nonce="<?php echo esc_attr( $mark_saved_nonce ); ?>"
1187 + data-wpbc-setup-target-selector="<?php echo esc_attr( $target_selector ); ?>"
1188 + data-wpbc-setup-scroll-selector="<?php echo esc_attr( $scroll_selector ); ?>"
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 ); ?>"
1192 + data-wpbc-setup-form-selector="<?php echo esc_attr( $form_selector ); ?>"
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 ); ?>"
1195 + data-wpbc-setup-save-events="<?php echo esc_attr( $save_events ); ?>"
1196 + data-wpbc-setup-open-action="<?php echo esc_attr( $open_action ); ?>">
464 1197 <div class="wpbc_ui_control wpbc_page_top__wizard_button_content">
465 1198 <div class="in-button-text"
466 - style="width: 100%;margin: 0;display: flex;flex-flow: row nowrap;justify-content: flex-start;align-items: center;">
1199 + style="width: 100%;margin: 0;display: flex;flex-flow: column nowrap;justify-content: flex-start;align-items: stretch;gap:8px;">
467 1200 <div class="setup_wizard_page_container"
468 1201 style="display: flex;flex-flow: row wrap;justify-content: flex-start;align-items: center;color: #fff;overflow: visible;flex: 1 1 auto;">
469 - <div class="name_item" style="margin-top: 0;white-space: nowrap;padding: 0;margin-right: 20px;">
470 - <i style="margin-right: 4px;" class="menu_icon icon-1x wpbc_icn_donut_large wpbc_icn_adjust0"></i> <?php esc_html_e( 'Finish Setup', 'booking' ); ?>
1202 + <div class="wpbc_setup_wizard_bar_title_row">
1203 + <div class="wpbc_setup_wizard_bar_header_actions">
1204 + <button type="button"
1205 + style="margin: -1px 5px 0 -7px;"
1206 + class="wpbc_setup_wizard_bar_icon_button wpbc_setup_wizard_bar_drag_handle"
1207 + title="<?php esc_attr_e( 'Move setup bar', 'booking' ); ?>"
1208 + aria-label="<?php esc_attr_e( 'Move setup bar', 'booking' ); ?>">
1209 + <i class="menu_icon icon-1x wpbc_icn_drag_indicator"></i>
1210 + </button>
1211 + </div>
1212 +
1213 + <div class="name_item wpbc_setup_wizard_bar_title">
1214 + <i style="margin-right: 4px;" class="menu_icon icon-1x wpbc_icn_donut_large wpbc_icn_adjust0"></i> <?php echo esc_html( $step_title ); ?>
1215 + </div>
1216 + <div class="wpbc_setup_wizard_bar_header_actions">
1217 + <button type="button"
1218 + class="wpbc_setup_wizard_bar_icon_button wpbc_setup_wizard_bar_reset_button"
1219 + title="<?php esc_attr_e( 'Reset setup bar position', 'booking' ); ?>"
1220 + aria-label="<?php esc_attr_e( 'Reset setup bar position', 'booking' ); ?>">
1221 + <i class="menu_icon icon-1x wpbc_icn_rotate_90 wpbc_icn_pin_invoke"></i>
1222 + </button>
1223 + <button type="button"
1224 + class="wpbc_setup_wizard_bar_icon_button wpbc_setup_wizard_bar_toggle_button"
1225 + title="<?php esc_attr_e( 'Collapse setup bar', 'booking' ); ?>"
1226 + aria-label="<?php esc_attr_e( 'Collapse setup bar', 'booking' ); ?>"
1227 + aria-expanded="true">
1228 + <i class="menu_icon icon-1x wpbc_icn_minimize"></i>
1229 + </button>
1230 + </div>
471 1231 </div>
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;">
1233 + <?php echo esc_html( $step_heading ); ?>
1234 + </div>
1235 + <?php if ( ! empty( $description ) ) { ?>
1236 + <div class="name_item wpbc_setup_wizard_bar_expandable" style="flex:1 1 100%;font-size:11px;font-weight:400;line-height:1.35;margin:2px 0 0;color:#e6e6e6;">
1237 + <?php echo esc_html( $description ); ?>
1238 + </div>
1239 + <?php } ?>
472 1240 <div
473 1241 style="margin:2px 0px 0 9px;font-size: 9px;background: #3e3e3e;height: auto;border-radius: 5px;padding: 0px 7px 0px;margin-left: auto;"
474 1242 class="wpbc_badge_count name_item update-plugins">
475 1243 <span class="update-count"
476 - style="white-space: nowrap;word-wrap: normal;"><?php echo esc_html( $this->get_active_step_num() . ' / ' . $this->get_total_steps_count() ); ?></span>
1244 + style="white-space: nowrap;word-wrap: normal;"><?php echo esc_html( $this->get_active_step_num( $current_step ) . ' / ' . $this->get_total_steps_count() ); ?></span>
477 1245 </div>
478 1246
479 1247 <div class="progress_line_container"
480 1248 style="width: 100%;border: 0px solid #757575;height: 3px;border-radius: 6px;margin: 7px 0 0 0;overflow: hidden;background: #202020;">
481 1249 <div class="progress_line"
482 - style="font-size: 6px;font-weight: 600;border-radius: 6px;word-wrap: normal;white-space: nowrap;background: #8ECE01;width: <?php echo esc_attr( $this->get_progess_value() ); ?>%;height: 3px;"></div>
1250 + style="font-size: 6px;font-weight: 600;border-radius: 6px;word-wrap: normal;white-space: nowrap;background: #8ECE01;width: <?php echo esc_attr( $this->get_progess_value( $current_step ) ); ?>%;height: 3px;"></div>
483 1251 </div>
484 1252 </div>
485 - <a <?php // onclick="javascript:jQuery( '.wpbc_page_top__wizard_button').remove();" href="javascript:void(0);" ?>
486 - href="<?php echo esc_url( wpbc_get_setup_wizard_page_url() ); ?>"
487 - class="button button-primary"
488 - style="margin-left: auto;font-size: 11px;min-height: 10px;margin-left: 25px;">Continue</a></div>
1253 + <?php if ( 'manual_save_required' === $save_behavior ) { ?>
1254 + <div class="wpbc_page_top__wizard_button_note wpbc_setup_wizard_bar_expandable<?php echo $is_step_saved ? ' wpbc_setup_wizard_bar_note_saved' : ''; ?>">
1255 + <?php
1256 + if ( $is_step_saved ) {
1257 + esc_html_e( 'Changes saved. You can continue.', 'booking' );
1258 + } else {
1259 + echo wp_kses_post( $save_required_note );
1260 + }
1261 + ?>
1262 + </div>
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 } ?>
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 } ?>
1288 + <?php if ( ! empty( $prior_url ) ) { ?>
1289 + <a href="<?php echo esc_url( $prior_url ); ?>" class="button button-secondary"><?php esc_html_e( 'Back', 'booking' ); ?></a>
1290 + <?php } ?>
1291 + <a href="<?php echo esc_url( $continue_href ); ?>"
1292 + class="button button-primary wpbc_setup_wizard_continue_button<?php echo $is_continue_disabled ? ' disabled' : ''; ?>"
1293 + data-wpbc-setup-continue-url="<?php echo esc_url( $continue_url ); ?>"
1294 + <?php echo $is_continue_disabled ? 'aria-disabled="true"' : ''; ?>><?php echo esc_html( $continue_title ); ?></a>
1295 + </div>
1296 + <div class="wpbc_page_top__wizard_button_links wpbc_setup_wizard_bar_expandable">
1297 + <a href="<?php echo esc_url( $skip_wizard_url ); ?>"
1298 + title="<?php esc_attr_e( 'Exit and skip the setup wizard', 'booking' ); ?>">
1299 + <?php esc_html_e( 'Exit and skip the setup wizard', 'booking' ); ?>
1300 + </a>
1301 + <a href="<?php echo esc_url( $reset_wizard_url ); ?>"
1302 + class="wpbc_setup_wizard_bar_danger_link"
1303 + title="<?php esc_attr_e( 'Start Setup from Beginning', 'booking' ); ?>">
1304 + <?php esc_html_e( 'Reset Wizard', 'booking' ); ?>
1305 + </a>
1306 + </div>
1307 + </div>
489 1308 </div>
490 - </div><?php
1309 + </div>
1310 + <script type="text/javascript">
1311 + jQuery( document ).ready( function() {
1312 + var $bar = jQuery( '.wpbc_page_top__wizard_button[data-wpbc-setup-step]' ).first();
1313 + var step = $bar.attr( 'data-wpbc-setup-step' ) || '';
1314 + var saveBehavior = $bar.attr( 'data-wpbc-setup-save-behavior' ) || '';
1315 + var selector = $bar.attr( 'data-wpbc-setup-target-selector' ) || '';
1316 + var scrollSelector = $bar.attr( 'data-wpbc-setup-scroll-selector' ) || selector;
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' ) || '' ) );
1320 + var formSelector = $bar.attr( 'data-wpbc-setup-form-selector' ) || '';
1321 + var saveSelector = $bar.attr( 'data-wpbc-setup-save-selector' ) || '';
1322 + var saveAjaxAction = $bar.attr( 'data-wpbc-setup-save-ajax-action' ) || '';
1323 + var saveEvents = ( $bar.attr( 'data-wpbc-setup-save-events' ) || '' ).split( ',' );
1324 + var openAction = $bar.attr( 'data-wpbc-setup-open-action' ) || '';
1325 + var ajaxUrl = $bar.attr( 'data-wpbc-setup-ajax-url' ) || '';
1326 + var nonce = $bar.attr( 'data-wpbc-setup-mark-saved-nonce' ) || '';
1327 + var $continueButton = $bar.find( '.wpbc_setup_wizard_continue_button' ).first();
1328 + var $note = $bar.find( '.wpbc_page_top__wizard_button_note' ).first();
1329 + var savedNote = '<?php echo esc_js( __( 'Changes saved. You can continue.', 'booking' ) ); ?>';
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' ) . '...' ); ?>;
1334 + var $toggleButton = $bar.find( '.wpbc_setup_wizard_bar_toggle_button' ).first();
1335 + var $toggleIcon = $toggleButton.find( 'i' ).first();
1336 + var $resetButton = $bar.find( '.wpbc_setup_wizard_bar_reset_button' ).first();
1337 + var $dragHandle = $bar.find( '.wpbc_setup_wizard_bar_drag_handle' ).first();
1338 + var positionStorageKey = 'wpbc_setup_wizard_bar_position';
1339 + var collapsedStorageKey = 'wpbc_setup_wizard_bar_collapsed';
1340 + var collapseLabel = <?php echo wp_json_encode( __( 'Collapse setup bar', 'booking' ) ); ?>;
1341 + var expandLabel = <?php echo wp_json_encode( __( 'Expand setup bar', 'booking' ) ); ?>;
1342 + var $target;
1343 + var $highlightTargets = jQuery();
1344 + var saveClicked = false;
1345 + var saveAndContinueRequested = false;
1346 + var saveAndContinueRedirecting = false;
1347 +
1348 + function wpbcSetupWizardStorageGet( key ) {
1349 + try {
1350 + return window.localStorage.getItem( key );
1351 + } catch ( _e ) {
1352 + return null;
1353 + }
1354 + }
1355 +
1356 + function wpbcSetupWizardStorageSet( key, value ) {
1357 + try {
1358 + window.localStorage.setItem( key, value );
1359 + } catch ( _e ) {}
1360 + }
1361 +
1362 + function wpbcSetupWizardStorageRemove( key ) {
1363 + try {
1364 + window.localStorage.removeItem( key );
1365 + } catch ( _e ) {}
1366 + }
1367 +
1368 + function wpbcSetupWizardIsSmallViewport() {
1369 + return window.matchMedia && window.matchMedia( '(max-width: 782px)' ).matches;
1370 + }
1371 +
1372 + function wpbcSetupWizardClampPosition( left, bottom ) {
1373 + var margin = 10;
1374 + var barWidth = $bar.outerWidth() || 330;
1375 + var barHeight = $bar.outerHeight() || 120;
1376 + var maxLeft = Math.max( margin, jQuery( window ).width() - barWidth - margin );
1377 + var maxBottom = Math.max( margin, jQuery( window ).height() - barHeight - margin );
1378 +
1379 + return {
1380 + left: Math.min( Math.max( margin, left ), maxLeft ),
1381 + bottom: Math.min( Math.max( margin, bottom ), maxBottom )
1382 + };
1383 + }
1384 +
1385 + function wpbcSetupWizardApplyPosition( position ) {
1386 + var clampedPosition;
1387 + var positionBottom;
1388 +
1389 + if ( wpbcSetupWizardIsSmallViewport() || ! position ) {
1390 + $bar
1391 + .removeClass( 'wpbc_setup_wizard_bar_is_moved' )
1392 + .removeClass( 'wpbc_setup_wizard_bar_auto_shifted' )
1393 + .removeClass( 'wpbc_setup_wizard_bar_auto_top' )
1394 + .css( {
1395 + '--wpbc-setup-bar-left': '',
1396 + '--wpbc-setup-bar-bottom': '',
1397 + '--wpbc-setup-bar-auto-right': '',
1398 + '--wpbc-setup-bar-auto-top': ''
1399 + } );
1400 + return;
1401 + }
1402 +
1403 + positionBottom = parseFloat( position.bottom );
1404 + if ( isNaN( positionBottom ) && ! isNaN( parseFloat( position.top ) ) ) {
1405 + positionBottom = jQuery( window ).height() - parseFloat( position.top ) - ( $bar.outerHeight() || 120 );
1406 + }
1407 +
1408 + clampedPosition = wpbcSetupWizardClampPosition( parseFloat( position.left ) || 15, isNaN( positionBottom ) ? 15 : positionBottom );
1409 + $bar
1410 + .addClass( 'wpbc_setup_wizard_bar_is_moved' )
1411 + .removeClass( 'wpbc_setup_wizard_bar_auto_shifted' )
1412 + .removeClass( 'wpbc_setup_wizard_bar_auto_top' )
1413 + .css( {
1414 + '--wpbc-setup-bar-left': clampedPosition.left + 'px',
1415 + '--wpbc-setup-bar-bottom': clampedPosition.bottom + 'px',
1416 + '--wpbc-setup-bar-auto-right': '',
1417 + '--wpbc-setup-bar-auto-top': ''
1418 + } );
1419 + }
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 +
1431 + function wpbcSetupWizardGetRightSidebarOffset() {
1432 + var viewportWidth = jQuery( window ).width();
1433 + var viewportHeight = jQuery( window ).height();
1434 + var $sidebar = jQuery();
1435 + var sidebarSelectors = [
1436 + '.wpbc_ui_el__vert_right_bar__wrapper',
1437 + '.wpbc_ui_el__vert_right_bar',
1438 + '.wpbc_ui_el__vert_right_bar__content',
1439 + '.wpbc_ui_el__vert_right_bar__content .simplebar-content-wrapper'
1440 + ].join( ',' );
1441 +
1442 + jQuery( sidebarSelectors ).filter( ':visible' ).each( function() {
1443 + var rect = this.getBoundingClientRect();
1444 +
1445 + if (
1446 + rect.width >= 140
1447 + && rect.left > ( viewportWidth * 0.45 )
1448 + && rect.right > ( viewportWidth - 80 )
1449 + && rect.top < ( viewportHeight - 90 )
1450 + && rect.bottom > ( viewportHeight * 0.35 )
1451 + ) {
1452 + $sidebar = jQuery( this );
1453 + return false;
1454 + }
1455 + } );
1456 +
1457 + if ( ! $sidebar.length ) {
1458 + return 0;
1459 + }
1460 +
1461 + return Math.max( 0, viewportWidth - $sidebar[0].getBoundingClientRect().left + 15 );
1462 + }
1463 +
1464 + function wpbcSetupWizardApplyDefaultPosition() {
1465 + var rightOffset;
1466 + var maxRight;
1467 + var barWidth = $bar.outerWidth() || 330;
1468 +
1469 + if ( wpbcSetupWizardIsSmallViewport() ) {
1470 + wpbcSetupWizardApplyPosition( null );
1471 + return;
1472 + }
1473 +
1474 + // Clear any visible inspector while retaining the minimum offset used by the Days Availability page.
1475 + rightOffset = wpbcSetupWizardGetRightSidebarOffset();
1476 + if ( 'date_availability' === step ) {
1477 + rightOffset = Math.max( rightOffset, 60 );
1478 + }
1479 + maxRight = Math.max( 15, jQuery( window ).width() - barWidth - 10 );
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 +
1495 + if ( rightOffset > 15 ) {
1496 + $bar
1497 + .removeClass( 'wpbc_setup_wizard_bar_is_moved' )
1498 + .removeClass( 'wpbc_setup_wizard_bar_auto_top' )
1499 + .addClass( 'wpbc_setup_wizard_bar_auto_shifted' )
1500 + .css( {
1501 + '--wpbc-setup-bar-left': '',
1502 + '--wpbc-setup-bar-bottom': '',
1503 + '--wpbc-setup-bar-auto-right': Math.min( rightOffset, maxRight ) + 'px',
1504 + '--wpbc-setup-bar-auto-top': ''
1505 + } );
1506 + return;
1507 + }
1508 +
1509 + wpbcSetupWizardApplyPosition( null );
1510 + }
1511 +
1512 + function wpbcSetupWizardSavePosition( left, bottom ) {
1513 + var clampedPosition = wpbcSetupWizardClampPosition( left, bottom );
1514 +
1515 + wpbcSetupWizardStorageSet( positionStorageKey, JSON.stringify( clampedPosition ) );
1516 + wpbcSetupWizardApplyPosition( clampedPosition );
1517 + }
1518 +
1519 + function wpbcSetupWizardApplySavedPosition() {
1520 + var savedPosition = wpbcSetupWizardStorageGet( positionStorageKey );
1521 + var rightSidebarOffset;
1522 + var barRect;
1523 + var sidebarLeft;
1524 +
1525 + if ( ! savedPosition ) {
1526 + wpbcSetupWizardApplyDefaultPosition();
1527 + return;
1528 + }
1529 +
1530 + try {
1531 + wpbcSetupWizardApplyPosition( JSON.parse( savedPosition ) );
1532 + } catch ( _e ) {
1533 + wpbcSetupWizardStorageRemove( positionStorageKey );
1534 + wpbcSetupWizardApplyDefaultPosition();
1535 + return;
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 + }
1547 + }
1548 +
1549 + function wpbcSetupWizardResetPosition() {
1550 + wpbcSetupWizardStorageRemove( positionStorageKey );
1551 + wpbcSetupWizardApplyDefaultPosition();
1552 + }
1553 +
1554 + function wpbcSetupWizardSetCollapsed( isCollapsed ) {
1555 + $bar.toggleClass( 'wpbc_setup_wizard_bar_collapsed', !! isCollapsed );
1556 + $toggleButton
1557 + .attr( 'aria-expanded', isCollapsed ? 'false' : 'true' )
1558 + .attr( 'title', isCollapsed ? expandLabel : collapseLabel )
1559 + .attr( 'aria-label', isCollapsed ? expandLabel : collapseLabel );
1560 + $toggleIcon
1561 + .toggleClass( 'wpbc_icn_minimize', ! isCollapsed )
1562 + .toggleClass( 'wpbc_icn_fullscreen', !! isCollapsed );
1563 + wpbcSetupWizardStorageSet( collapsedStorageKey, isCollapsed ? '1' : '0' );
1564 + wpbcSetupWizardApplySavedPosition();
1565 + }
1566 +
1567 + $toggleButton.on( 'click', function() {
1568 + wpbcSetupWizardSetCollapsed( ! $bar.hasClass( 'wpbc_setup_wizard_bar_collapsed' ) );
1569 + } );
1570 +
1571 + $resetButton.on( 'click', function() {
1572 + wpbcSetupWizardResetPosition();
1573 + } );
1574 +
1575 + $dragHandle.on( 'mousedown', function( event ) {
1576 + var startX;
1577 + var startY;
1578 + var startLeft;
1579 + var startBottom;
1580 + var rect;
1581 + var barHeight;
1582 +
1583 + if ( wpbcSetupWizardIsSmallViewport() || ( event.which && 1 !== event.which ) ) {
1584 + return;
1585 + }
1586 +
1587 + event.preventDefault();
1588 + rect = $bar[0].getBoundingClientRect();
1589 + startX = event.clientX;
1590 + startY = event.clientY;
1591 + startLeft = rect.left;
1592 + barHeight = $bar.outerHeight() || rect.height || 120;
1593 + startBottom = jQuery( window ).height() - rect.top - barHeight;
1594 + $bar.addClass( 'wpbc_setup_wizard_bar_is_dragging' );
1595 +
1596 + jQuery( document )
1597 + .off( '.wpbc_setup_wizard_bar_drag' )
1598 + .on( 'mousemove.wpbc_setup_wizard_bar_drag', function( moveEvent ) {
1599 + wpbcSetupWizardApplyPosition( {
1600 + left: startLeft + moveEvent.clientX - startX,
1601 + bottom: startBottom - moveEvent.clientY + startY
1602 + } );
1603 + } )
1604 + .on( 'mouseup.wpbc_setup_wizard_bar_drag', function( upEvent ) {
1605 + var movedRect = $bar[0].getBoundingClientRect();
1606 + var movedBottom = jQuery( window ).height() - movedRect.top - ( $bar.outerHeight() || movedRect.height || 120 );
1607 +
1608 + wpbcSetupWizardSavePosition( movedRect.left, movedBottom );
1609 + $bar.removeClass( 'wpbc_setup_wizard_bar_is_dragging' );
1610 + jQuery( document ).off( '.wpbc_setup_wizard_bar_drag' );
1611 + } );
1612 + } );
1613 +
1614 + wpbcSetupWizardSetCollapsed( '1' === wpbcSetupWizardStorageGet( collapsedStorageKey ) );
1615 + wpbcSetupWizardApplySavedPosition();
1616 + setTimeout( wpbcSetupWizardApplySavedPosition, 400 );
1617 + setTimeout( wpbcSetupWizardApplySavedPosition, 1000 );
1618 + jQuery( window ).on( 'resize.wpbc_setup_wizard_bar', wpbcSetupWizardApplySavedPosition );
1619 + jQuery( document ).on( 'wpbc_setup_wizard_layout_changed.wpbc_setup_wizard_bar', wpbcSetupWizardApplySavedPosition );
1620 +
1621 + function wpbcSetupWizardOpenPublishArea() {
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' );
1627 + var publishTabSelectors = [
1628 + '.wpdvlp-sub-tabs .nav-tab',
1629 + '.wpdvlp-top-tabs .nav-tab',
1630 + '.wpbc_settings_navigation_item a',
1631 + '.wpbc_ui_el__vert_nav_item a',
1632 + '[role="tab"]',
1633 + '[data-tab]',
1634 + '[data-subtab]'
1635 + ].join( ',' );
1636 + var publishToggleSelectors = [
1637 + '.wpbc_resource_field__switchable a',
1638 + '.wpbc_resource_field__switchable button',
1639 + '.wpbc_ajx_toolbar a',
1640 + '.wpbc_ajx_toolbar button',
1641 + 'a.button',
1642 + 'button.button'
1643 + ].join( ',' );
1644 + var publishTargetSelector = [
1645 + '.wpbc_resources_table .ui_group__publish_btn:visible',
1646 + '#wpbc_booking_resource_table .ui_group__publish_btn:visible',
1647 + '.wpbc_resource_field__switchable.wpbc_resource_field__publish:visible',
1648 + '.wpbc_resource_field__publish:visible',
1649 + '.wpbc_resource_publish:visible',
1650 + '.wpbc_publish_resources:visible',
1651 + '[data-wpbc-resource-publish]:visible'
1652 + ].join( ',' );
1653 + var $publishTab;
1654 + var $publishToggle;
1655 +
1656 + if ( 'wizard_publish' !== step || ! isResourcesPage ) {
1657 + return;
1658 + }
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 +
1728 + $publishTab = jQuery( publishTabSelectors ).filter( ':visible' ).filter( function() {
1729 + var $element = jQuery( this );
1730 + var text = $element.text() || '';
1731 + var href = $element.attr( 'href' ) || '';
1732 + var dataTab = $element.attr( 'data-tab' ) || '';
1733 + var dataSubtab = $element.attr( 'data-subtab' ) || '';
1734 + var haystack = ( text + ' ' + href + ' ' + dataTab + ' ' + dataSubtab ).toLowerCase();
1735 +
1736 + if ( $element.closest( '.wpbc_page_top__wizard_button' ).length ) {
1737 + return false;
1738 + }
1739 +
1740 + return (
1741 + -1 !== haystack.indexOf( 'publish' )
1742 + || -1 !== haystack.indexOf( 'shortcode' )
1743 + || -1 !== haystack.indexOf( 'embed' )
1744 + );
1745 + } ).first();
1746 +
1747 + if ( $publishTab.length && ! $publishTab.hasClass( 'nav-tab-active' ) && ! $publishTab.parent().hasClass( 'active' ) ) {
1748 + $publishTab.trigger( 'click' );
1749 + }
1750 +
1751 + if ( ! $publishTab.length ) {
1752 + $publishToggle = jQuery( publishToggleSelectors ).filter( ':visible' ).filter( function() {
1753 + var $element = jQuery( this );
1754 + var text = $element.text() || '';
1755 + var title = $element.attr( 'title' ) || $element.attr( 'data-original-title' ) || '';
1756 + var onclick = $element.attr( 'onclick' ) || '';
1757 + var className = $element.attr( 'class' ) || '';
1758 + var haystack = ( text + ' ' + title + ' ' + className ).toLowerCase();
1759 +
1760 + if ( $element.closest( '.wpbc_page_top__wizard_button' ).length ) {
1761 + return false;
1762 + }
1763 +
1764 + if ( -1 !== onclick.indexOf( 'wpbc_modal_dialog__show__resource_publish' ) ) {
1765 + return false;
1766 + }
1767 +
1768 + return (
1769 + -1 !== haystack.indexOf( 'show publish' )
1770 + || -1 !== haystack.indexOf( 'publish option' )
1771 + || -1 !== haystack.indexOf( 'shortcode' )
1772 + || -1 !== haystack.indexOf( 'resource_field__publish' )
1773 + );
1774 + } ).first();
1775 +
1776 + if ( $publishToggle.length ) {
1777 + $publishToggle.trigger( 'click' );
1778 + }
1779 + }
1780 +
1781 + setTimeout( function() {
1782 + var $publishTarget = jQuery( publishTargetSelector ).first();
1783 +
1784 + if ( ! $publishTarget.length ) {
1785 + $publishTarget = jQuery( selector ).filter( ':visible' ).first();
1786 + }
1787 +
1788 + if ( ! $publishTarget.length ) {
1789 + return;
1790 + }
1791 +
1792 + if ( typeof wpbc_scroll_to === 'function' ) {
1793 + wpbc_scroll_to( $publishTarget );
1794 + } else if ( $publishTarget.offset() ) {
1795 + jQuery( 'html, body' ).animate( { scrollTop: $publishTarget.offset().top - 80 }, 300 );
1796 + }
1797 +
1798 + if ( typeof wpbc_blink_element === 'function' ) {
1799 + wpbc_blink_element( $publishTarget, 3, 300 );
1800 + }
1801 + }, 450 );
1802 + }
1803 +
1804 + wpbcSetupWizardOpenPublishArea();
1805 +
1806 + function wpbcSetupWizardGetFirstElement( selectors ) {
1807 + var $element = jQuery();
1808 +
1809 + if ( ! selectors ) {
1810 + return $element;
1811 + }
1812 +
1813 + try {
1814 + $element = jQuery( selectors ).filter( ':visible' ).first();
1815 + if ( $element.length ) {
1816 + return $element;
1817 + }
1818 + return jQuery( selectors ).first();
1819 + } catch ( _e ) {
1820 + return jQuery();
1821 + }
1822 + }
1823 +
1824 + function wpbcSetupWizardGetScrollableParent( $element ) {
1825 + var $scrollParent;
1826 +
1827 + if ( ! $element || ! $element.length ) {
1828 + return jQuery();
1829 + }
1830 +
1831 + $scrollParent = $element.parents().filter( function() {
1832 + var $parent = jQuery( this );
1833 + var overflowY = $parent.css( 'overflow-y' );
1834 +
1835 + return (
1836 + /(auto|scroll)/.test( overflowY )
1837 + && this.scrollHeight > Math.ceil( $parent.innerHeight() ) + 5
1838 + );
1839 + } ).first();
1840 +
1841 + return $scrollParent;
1842 + }
1843 +
1844 + function wpbcSetupWizardScrollToElement( $element ) {
1845 + var $scrollParent;
1846 + var targetTop;
1847 +
1848 + if ( ! $element || ! $element.length || ! $element.offset() ) {
1849 + return;
1850 + }
1851 +
1852 + $scrollParent = wpbcSetupWizardGetScrollableParent( $element );
1853 + if ( $scrollParent.length && ! $scrollParent.is( 'html, body' ) ) {
1854 + targetTop = $element.offset().top - $scrollParent.offset().top + $scrollParent.scrollTop() - 40;
1855 + $scrollParent.stop().animate( {
1856 + scrollTop: Math.max( 0, targetTop )
1857 + }, 350 );
1858 + return;
1859 + }
1860 +
1861 + if ( typeof wpbc_scroll_to === 'function' ) {
1862 + wpbc_scroll_to( $element );
1863 + } else {
1864 + jQuery( 'html, body' ).stop().animate( {
1865 + scrollTop: Math.max( 0, $element.offset().top - 90 )
1866 + }, 350 );
1867 + }
1868 + }
1869 +
1870 + function wpbcSetupWizardHighlightElement( $element ) {
1871 + if ( ! $element || ! $element.length ) {
1872 + return;
1873 + }
1874 +
1875 + $element.addClass( 'wpbc_setup_wizard__target_highlight' );
1876 + if ( typeof wpbc_blink_element === 'function' ) {
1877 + wpbc_blink_element( $element, 3, 300 );
1878 + }
1879 + }
1880 +
1881 + function wpbcSetupWizardPulseElement( $element ) {
1882 + if ( ! $element || ! $element.length ) {
1883 + return;
1884 + }
1885 +
1886 + $element
1887 + .removeClass( 'wpbc_setup_wizard_attention_pulse' )
1888 + .each( function() {
1889 + // Restart the CSS animation when the user clicks Continue repeatedly.
1890 + void this.offsetWidth;
1891 + } )
1892 + .addClass( 'wpbc_setup_wizard_attention_pulse' );
1893 +
1894 + setTimeout( function() {
1895 + $element.removeClass( 'wpbc_setup_wizard_attention_pulse' );
1896 + }, 2100 );
1897 + }
1898 +
1899 + function wpbcSetupWizardPulseSaveRequiredMessage() {
1900 + if ( $bar.hasClass( 'wpbc_setup_wizard_bar_collapsed' ) ) {
1901 + wpbcSetupWizardSetCollapsed( false );
1902 + }
1903 +
1904 + if ( $note.length ) {
1905 + wpbcSetupWizardPulseElement( $note );
1906 + }
1907 +
1908 + setTimeout( function() {
1909 + wpbcSetupWizardPulseElement( jQuery( '#ajax_working .wpbc_inner_message.notice-warning' ).last() );
1910 + }, 50 );
1911 + }
1912 +
1913 + function wpbcSetupWizardSetSaved() {
1914 + $bar.attr( 'data-wpbc-setup-is-saved', '1' );
1915 + $continueButton
1916 + .removeClass( 'disabled' )
1917 + .removeAttr( 'aria-disabled' )
1918 + .attr( 'href', $continueButton.attr( 'data-wpbc-setup-continue-url' ) || '#' )
1919 + .text( continueTitle );
1920 + if ( $note.length ) {
1921 + $note
1922 + .addClass( 'wpbc_setup_wizard_bar_note_saved' )
1923 + .text( savedNote );
1924 + }
1925 + }
1926 +
1927 + function wpbcSetupWizardSetUnsaved() {
1928 + $bar.attr( 'data-wpbc-setup-is-saved', '0' );
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 + }
1935 + if ( $note.length ) {
1936 + $note
1937 + .removeClass( 'wpbc_setup_wizard_bar_note_saved' )
1938 + .html( saveRequiredNote );
1939 + }
1940 + }
1941 +
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 ) {
1977 + if ( ! step || ! ajaxUrl || ! nonce ) {
1978 + wpbcSetupWizardSetSaved();
1979 + if ( 'function' === typeof afterSavedCallback ) {
1980 + afterSavedCallback();
1981 + }
1982 + return;
1983 + }
1984 +
1985 + jQuery.post( ajaxUrl, {
1986 + action: 'WPBC_AJX_SETUP_WIZARD_MARK_STEP_SAVED',
1987 + nonce: nonce,
1988 + wpbc_setup_step: step
1989 + } ).done( function( response ) {
1990 + if ( 'string' === typeof response ) {
1991 + try {
1992 + response = JSON.parse( response );
1993 + } catch ( _e ) {}
1994 + }
1995 + if ( response && response.success ) {
1996 + wpbcSetupWizardSetSaved();
1997 + if ( 'function' === typeof afterSavedCallback ) {
1998 + afterSavedCallback();
1999 + }
2000 + }
2001 + } ).fail( function() {
2002 + if ( saveAndContinueRequested ) {
2003 + wpbcSetupWizardSetSaveAndContinueBusy( false );
2004 + saveAndContinueRequested = false;
2005 + }
2006 + } );
2007 + }
2008 +
2009 + function wpbcSetupWizardSaveStarted() {
2010 + saveClicked = true;
2011 + }
2012 +
2013 + function wpbcSetupWizardLooksSuccessfulResponse( response ) {
2014 + if ( ! response ) {
2015 + return false;
2016 + }
2017 +
2018 + return (
2019 + !! response.success
2020 + || 'success' === response.status
2021 + || '1' === String( response.ajx_after_action_result || '' )
2022 + || ( response.ajx_data && '1' === String( response.ajx_data.ajx_after_action_result || '' ) )
2023 + || ( response.data && response.data.setup_step_saved )
2024 + );
2025 + }
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 +
2073 + function wpbcSetupWizardRegisterSavedEvent( eventName ) {
2074 + eventName = ( eventName || '' ).replace( /^\s+|\s+$/g, '' );
2075 + if ( ! eventName ) {
2076 + return;
2077 + }
2078 +
2079 + document.addEventListener( eventName, wpbcSetupWizardHandleSavedEvent, true );
2080 + jQuery( document ).on( eventName + '.wpbc_setup_wizard', wpbcSetupWizardHandleSavedEvent );
2081 + }
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 +
2126 + if ( 'manual_save_required' === saveBehavior ) {
2127 + window.wpbc_setup_wizard_set_current_step_saved = wpbcSetupWizardSetSaved;
2128 + window.wpbc_setup_wizard_mark_current_step_saved = wpbcSetupWizardMarkSaved;
2129 +
2130 + document.addEventListener( 'wpbc:bfb:form:before_save_payload', function( event ) {
2131 + if ( ! event || ! event.detail || ! event.detail.payload || ! step ) {
2132 + return;
2133 + }
2134 + wpbcSetupWizardSaveStarted();
2135 + event.detail.payload.wpbc_setup = '1';
2136 + event.detail.payload.wpbc_setup_step = step;
2137 + if ( saveAndContinueRequested ) {
2138 + event.detail.payload.wpbc_setup_continue_after_save = '1';
2139 + }
2140 + }, true );
2141 +
2142 + saveEvents.forEach( wpbcSetupWizardRegisterSavedEvent );
2143 +
2144 + if ( formSelector ) {
2145 + jQuery( formSelector ).each( function() {
2146 + var $form = jQuery( this );
2147 + if ( ! $form.is( 'form' ) ) {
2148 + return;
2149 + }
2150 + if ( ! $form.find( 'input[name="wpbc_setup_saved_step"]' ).length ) {
2151 + $form.append( '<input type="hidden" name="wpbc_setup_saved_step" value="" />' );
2152 + }
2153 + if ( ! $form.find( 'input[name="wpbc_setup_step"]' ).length ) {
2154 + $form.append( '<input type="hidden" name="wpbc_setup_step" value="" />' );
2155 + }
2156 + if ( ! $form.find( 'input[name="wpbc_setup"]' ).length ) {
2157 + $form.append( '<input type="hidden" name="wpbc_setup" value="" />' );
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 + }
2162 + $form.find( 'input[name="wpbc_setup_saved_step"]' ).val( step );
2163 + $form.find( 'input[name="wpbc_setup_step"]' ).val( step );
2164 + $form.find( 'input[name="wpbc_setup"]' ).val( '1' );
2165 + $form.find( 'input[name="wpbc_setup_continue_after_save"]' ).val( '0' );
2166 + $form
2167 + .off( 'change.wpbc_setup_wizard input.wpbc_setup_wizard', ':input' )
2168 + .on( 'change.wpbc_setup_wizard input.wpbc_setup_wizard', ':input', function() {
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"]' ) ) {
2170 + return;
2171 + }
2172 + wpbcSetupWizardSetUnsaved();
2173 + } );
2174 + $form
2175 + .off( 'submit.wpbc_setup_wizard' )
2176 + .on( 'submit.wpbc_setup_wizard', function() {
2177 + wpbcSetupWizardSaveStarted();
2178 + $form.find( 'input[name="wpbc_setup_saved_step"]' ).val( step );
2179 + $form.find( 'input[name="wpbc_setup_step"]' ).val( step );
2180 + $form.find( 'input[name="wpbc_setup"]' ).val( '1' );
2181 + $form.find( 'input[name="wpbc_setup_continue_after_save"]' ).val( saveAndContinueRequested ? '1' : '0' );
2182 + } );
2183 + } );
2184 + }
2185 +
2186 + $continueButton.on( 'click', function( event ) {
2187 + if ( '1' !== $bar.attr( 'data-wpbc-setup-is-saved' ) ) {
2188 + event.preventDefault();
2189 + if ( saveSelector ) {
2190 + wpbcSetupWizardTriggerSaveAndContinue();
2191 + return;
2192 + }
2193 + if ( typeof wpbc_admin_show_message === 'function' ) {
2194 + wpbc_admin_show_message( '<?php echo esc_js( __( 'Please save changes on this page before continuing setup.', 'booking' ) ); ?>', 'warning', 4000, false );
2195 + }
2196 + wpbcSetupWizardPulseSaveRequiredMessage();
2197 + }
2198 + } );
2199 +
2200 + if ( saveSelector ) {
2201 + jQuery( document )
2202 + .on( 'mousedown.wpbc_setup_wizard click.wpbc_setup_wizard', saveSelector, wpbcSetupWizardSaveStarted )
2203 + .on( 'keydown.wpbc_setup_wizard', saveSelector, function( event ) {
2204 + if ( 13 === event.which || 32 === event.which ) {
2205 + wpbcSetupWizardSaveStarted();
2206 + }
2207 + } );
2208 + }
2209 +
2210 + jQuery( document ).ajaxComplete( function( _event, xhr, ajaxSettings ) {
2211 + var response;
2212 + if ( ! saveClicked ) {
2213 + return;
2214 + }
2215 + if ( ! wpbcSetupWizardIsExpectedSaveAjax( ajaxSettings ) ) {
2216 + return;
2217 + }
2218 + saveClicked = false;
2219 +
2220 + response = xhr && xhr.responseJSON ? xhr.responseJSON : null;
2221 + if ( ! response && xhr && xhr.responseText ) {
2222 + try {
2223 + response = JSON.parse( xhr.responseText );
2224 + } catch ( _e ) {}
2225 + }
2226 + if ( response && response.data && response.data.setup_step_saved ) {
2227 + wpbcSetupWizardSetSaved();
2228 + if ( saveAndContinueRequested ) {
2229 + wpbcSetupWizardContinueAfterSave();
2230 + }
2231 + } else if ( wpbcSetupWizardLooksSuccessfulResponse( response ) ) {
2232 + if ( saveAndContinueRequested ) {
2233 + wpbcSetupWizardMarkSaved( wpbcSetupWizardContinueAfterSave );
2234 + } else {
2235 + wpbcSetupWizardMarkSaved();
2236 + }
2237 + } else if ( saveAndContinueRequested ) {
2238 + wpbcSetupWizardSetSaveAndContinueBusy( false );
2239 + saveAndContinueRequested = false;
2240 + }
2241 + } );
2242 + }
2243 +
2244 + if ( highlightDisabled ) {
2245 + highlightSelector = '';
2246 + }
2247 +
2248 + if ( ! selector && ! scrollSelector && ! highlightSelector ) {
2249 + return;
2250 + }
2251 +
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 );
2265 + }
2266 +
2267 + $target = $highlightTargets.first();
2268 +
2269 + setTimeout( function() {
2270 + var $scrollTarget = wpbcSetupWizardGetFirstElement( scrollSelector || ( highlightDisabled ? selector : highlightSelector ) || selector );
2271 + if ( ! $scrollTarget.length ) {
2272 + $scrollTarget = $target;
2273 + }
2274 + wpbcSetupWizardScrollToElement( $scrollTarget );
2275 + }, 250 );
2276 + } );
2277 + </script><?php
491 2278 }
492 2279 }
493 2280
494 2281 }
@@ -510,5 +2297,5 @@
510 2297 $is_completed = true;
511 2298 $setup_steps->db__set_all_steps_as( $is_completed );
512 2299 }
513 2300 }
514 -add_bk_action( 'wpbc_other_versions_activation', 'wpbc_booking_activate_plugin__wizard' );
2301 +add_bk_action( 'wpbc_other_versions_activation', 'wpbc_booking_activate_plugin__wizard' );