PluginProbe
Booking Calendar / 11.3
Booking Calendar v11.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
booking / includes / page-setup / setup_steps.php

setup_steps.php in Booking Calendar 11.3, at includes/page-setup/setup_steps.php

1,919 lines 64.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php /**
2 * @version 1.0
3 * @description Steps Structure for Setup Wizard Page
4 * @category Setup Class
5 * @author wpdevelop
6 *
7 * @web-site http://oplugins.com/
8 * @email info@oplugins.com
9 *
10 * @modified 2024-09-06
11 */
12
13 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
14
15
16 class WPBC_SETUP_WIZARD_STEPS {
17
18 private $steps_arr = array();
19
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 /**
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 public function __construct() {
48
49 if ( WPBC()->is_wp_inited() || did_action( 'init' ) ) {
50 $this->init_steps_data();
51 } else {
52 add_action( 'init', array( $this, 'init_steps_data' ) );
53 }
54
55 if ( ! self::$is_top_bar_hook_registered ) {
56 add_action( 'wpbc_after_wpbc_page_top__header_tabs', array( $this, 'show_top_right_wizard_button' ), 10, 3 );
57 self::$is_top_bar_hook_registered = true;
58 }
59
60 }
61
62 /**
63 * Check whether translated strings can be loaded without triggering WordPress just-in-time translation notices.
64 *
65 * @return bool
66 */
67 private function is_i18n_ready() {
68
69 return ( WPBC()->is_wp_inited() || did_action( 'init' ) );
70 }
71
72
73 /**
74 * Define Steps Data Structure - Init
75 *
76 * @return void
77 */
78 public function init_steps_data(){
79
80 $is_i18n_ready = $this->is_i18n_ready();
81
82 $step_default_params = array(
83 'show_section_left' => false,
84 'show_section_right' => false,
85 'is_done' => false,
86 'do_action' => 'none',
87 'prior' => '',
88 'next' => '',
89 'prior_title' => $is_i18n_ready ? __( 'Go Back', 'booking' ) : 'Go Back',
90 'next_title' => $is_i18n_ready ? __( 'Save and Continue', 'booking' ) : 'Save and Continue'
91 );
92 $steps_arr = array();
93
94 if ( function_exists( 'wpbc_setup_wizard__get_intro_route' ) ) {
95 $route = wpbc_setup_wizard__get_intro_route();
96 } else {
97 $route = array( 'welcome' );
98 if ( ! wpbc_is_this_demo() ) {
99 $route[] = 'general_info';
100 }
101 $route[] = 'date_time_formats';
102 $route[] = 'bookings_types';
103 }
104 $route = array_merge( $route, wpbc_setup_wizard__get_profile_route() );
105
106 foreach ( $route as $step_index => $step_name ) {
107 $steps_arr[ $step_name ] = $step_default_params;
108 $steps_arr[ $step_name ]['do_action'] = 'save_and_continue__' . $step_name;
109 $steps_arr[ $step_name ]['prior'] = ( 0 === $step_index ) ? '' : $route[ $step_index - 1 ];
110 $steps_arr[ $step_name ]['next'] = isset( $route[ $step_index + 1 ] ) ? $route[ $step_index + 1 ] : 'welcome';
111
112 if ( $is_i18n_ready && function_exists( 'wpbc_setup_wizard__get_step_route_metadata' ) ) {
113 $steps_arr[ $step_name ] = array_merge(
114 $steps_arr[ $step_name ],
115 wpbc_setup_wizard__get_step_route_metadata( $step_name )
116 );
117 }
118 }
119
120 foreach ( array( 'date_selection', 'changeover_days', 'working_time', 'time_slots_availability', 'date_availability', 'form_structure', 'color_theme', 'wizard_publish' ) as $continue_step_name ) {
121 if ( isset( $steps_arr[ $continue_step_name ] ) ) {
122 $steps_arr[ $continue_step_name ]['next_title'] = $is_i18n_ready ? __( 'Continue', 'booking' ) : 'Continue';
123 }
124 }
125
126 $this->steps_arr = $steps_arr;
127 $this->is_steps_data_initialized = true;
128 }
129
130 /**
131 * Ensure setup route data is available before this instance reads or normalizes step state.
132 *
133 * @return void
134 */
135 private function ensure_steps_data_initialized() {
136
137 if ( ! $this->is_steps_data_initialized ) {
138 $this->init_steps_data();
139 }
140 }
141
142 /**
143 * Get Steps Data Structure
144 * @return array
145 */
146 public function get_steps_arr(){
147 $this->ensure_steps_data_initialized();
148
149 return $this->steps_arr;
150 }
151
152
153 // =================================================================================================================
154 // == Steps STRUCTURE ==
155 // =================================================================================================================
156
157 /**
158 * Actual Step Number -> 'general_info' or 'date_availability'
159 *
160 * @return int
161 */
162 public function get_active_step_name() {
163
164 $steps_arr = $this->db__get_steps_is_done();
165
166 $first_step_name = '';
167 foreach ( $steps_arr as $step_name => $step ) {
168
169 $first_step_name = (empty($first_step_name)) ? $step_name : $first_step_name;
170
171 if ( empty( $step ) ) {
172 return $step_name;
173 }
174 }
175 return $first_step_name;
176 }
177
178
179 /**
180 * Actual Step Number -> 2
181 *
182 * @return int
183 */
184 public function get_active_step_num( $current_step = '' ) {
185
186 if ( ! empty( $current_step ) ) {
187 return $this->get_step_num_by_name( $current_step );
188 }
189
190 $steps_arr = $this->db__get_steps_is_done();
191 $total_steps = count( $steps_arr );
192 $completed_steps = 0;
193
194 foreach ( $steps_arr as $step ) {
195 if ( ! empty( $step ) ) {
196 $completed_steps++;
197 }
198 }
199
200 if ( $completed_steps >= $total_steps ) {
201 return $total_steps;
202 }
203
204 return min( $completed_steps + 1, $total_steps );
205 }
206
207 /**
208 * Get Step Number by step name.
209 *
210 * @param string $current_step Step name.
211 *
212 * @return int
213 */
214 public function get_step_num_by_name( $current_step ) {
215
216 $step_num = 1;
217
218 foreach ( array_keys( $this->get_steps_arr() ) as $step_name ) {
219 if ( $step_name === $current_step ) {
220 return $step_num;
221 }
222 $step_num++;
223 }
224
225 return 1;
226 }
227
228 /**
229 * Get the last wizard step saved in the setup wizard request history.
230 *
231 * @return string
232 */
233 public function get_saved_current_step_name() {
234
235 $steps_arr = $this->get_steps_arr();
236 $current_step = $this->get_active_step_name();
237
238 if ( function_exists( 'wpbc_setup_wizard_page__get_cleaned_params__saved_request_default' ) ) {
239 $saved_request_params = wpbc_setup_wizard_page__get_cleaned_params__saved_request_default();
240
241 if (
242 is_array( $saved_request_params )
243 && ( ! empty( $saved_request_params['current_step'] ) )
244 && isset( $steps_arr[ $saved_request_params['current_step'] ] )
245 ) {
246 $current_step = $saved_request_params['current_step'];
247 }
248 }
249
250 return $current_step;
251 }
252
253 /**
254 * Get target URL for a setup step.
255 *
256 * @param string $step_name Step name.
257 *
258 * @return string
259 */
260 public function get_step_target_url( $step_name ) {
261
262 $steps_arr = $this->get_steps_arr();
263
264 if ( isset( $steps_arr[ $step_name ]['target_url'] ) && ( ! empty( $steps_arr[ $step_name ]['target_url'] ) ) ) {
265 return $steps_arr[ $step_name ]['target_url'];
266 }
267
268 return function_exists( 'wpbc_setup_wizard__get_step_target_url' )
269 ? wpbc_setup_wizard__get_step_target_url( $step_name )
270 : wpbc_get_setup_wizard_page_url();
271 }
272
273 /**
274 * Get Continue URL for the floating setup bar.
275 *
276 * @param string $step_name Step name.
277 *
278 * @return string
279 */
280 public function get_step_continue_url( $step_name ) {
281
282 return function_exists( 'wpbc_setup_wizard__get_step_continue_url' )
283 ? wpbc_setup_wizard__get_step_continue_url( $step_name )
284 : $this->get_step_target_url( $step_name );
285 }
286
287 /**
288 * Get step name from setup URL context or first incomplete setup step.
289 *
290 * @return string
291 */
292 public function get_context_step_name() {
293
294 $steps_arr = $this->get_steps_arr();
295 $current_step = $this->get_saved_current_step_name();
296
297 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
298 if ( isset( $_REQUEST['wpbc_setup_step'] ) ) {
299 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
300 $request_step = sanitize_key( wp_unslash( $_REQUEST['wpbc_setup_step'] ) );
301 if ( isset( $steps_arr[ $request_step ] ) ) {
302 $current_step = $request_step;
303 $this->db__save_current_step_name( $current_step );
304 return $current_step;
305 }
306 }
307
308 if ( $this->db__is_step_completed( 'bookings_types' ) && function_exists( 'wpbc_setup_wizard__detect_step_from_admin_request' ) ) {
309 $detected_step = wpbc_setup_wizard__detect_step_from_admin_request();
310 if ( ! empty( $detected_step ) && isset( $steps_arr[ $detected_step ] ) ) {
311 $current_step = $detected_step;
312 $this->db__save_current_step_name( $current_step );
313 return $current_step;
314 }
315 }
316
317 return $current_step;
318 }
319
320 /**
321 * Save the current setup step into the per-user wizard request state.
322 *
323 * @param string $step_name Step name.
324 *
325 * @return bool
326 */
327 public function db__save_current_step_name( $step_name ) {
328
329 $steps_arr = $this->get_steps_arr();
330 if ( empty( $step_name ) || ! isset( $steps_arr[ $step_name ] ) || ! function_exists( 'wpbc_setup_wizard_page__request_rules_structure' ) ) {
331 return false;
332 }
333
334 $request_params_to_save = function_exists( 'wpbc_setup_wizard_page__get_cleaned_params__saved_request_default' )
335 ? wpbc_setup_wizard_page__get_cleaned_params__saved_request_default()
336 : array();
337
338 if ( ! is_array( $request_params_to_save ) || empty( $request_params_to_save ) ) {
339 $request_params_to_save = function_exists( 'wpbc_setup_wizard_page__get__request_values__default' )
340 ? wpbc_setup_wizard_page__get__request_values__default()
341 : array();
342 }
343
344 $request_params_to_save['current_step'] = $step_name;
345
346 $user_request = new WPBC_AJX__REQUEST( array(
347 'db_option_name' => 'booking_setup_wizard_page_request_params',
348 'user_id' => wpbc_get_current_user_id(),
349 'request_rules_structure' => wpbc_setup_wizard_page__request_rules_structure()
350 )
351 );
352
353 return (bool) $user_request->user_request_params__db_save( $request_params_to_save );
354 }
355
356 /**
357 * Get target URL for prior setup step.
358 *
359 * @param string $step_name Step name.
360 *
361 * @return string
362 */
363 public function get_step_prior_url( $step_name ) {
364
365 $steps_arr = $this->get_steps_arr();
366 $prior = isset( $steps_arr[ $step_name ]['prior'] ) ? $steps_arr[ $step_name ]['prior'] : '';
367
368 return ( empty( $prior ) ) ? '' : $this->get_step_target_url( $prior );
369 }
370
371 /**
372 * Get step title for setup bar.
373 *
374 * @param string $step_name Step name.
375 *
376 * @return string
377 */
378 public function get_step_title( $step_name ) {
379
380 $steps_arr = $this->get_steps_arr();
381
382 if ( isset( $steps_arr[ $step_name ]['title'] ) ) {
383 return $steps_arr[ $step_name ]['title'];
384 }
385
386 return function_exists( 'wpbc_setup_wizard__get_step_title' )
387 ? wpbc_setup_wizard__get_step_title( $step_name )
388 : $step_name;
389 }
390
391 /**
392 * Get action-oriented setup step heading.
393 *
394 * @param string $step_name Step name.
395 *
396 * @return string
397 */
398 public function get_step_heading( $step_name ) {
399
400 $steps_arr = $this->get_steps_arr();
401
402 if ( isset( $steps_arr[ $step_name ]['heading'] ) ) {
403 return $steps_arr[ $step_name ]['heading'];
404 }
405
406 return function_exists( 'wpbc_setup_wizard__get_step_heading' )
407 ? wpbc_setup_wizard__get_step_heading( $step_name )
408 : $this->get_step_title( $step_name );
409 }
410
411 /**
412 * Get setup step description.
413 *
414 * @param string $step_name Step name.
415 *
416 * @return string
417 */
418 public function get_step_description( $step_name ) {
419
420 $steps_arr = $this->get_steps_arr();
421
422 if ( isset( $steps_arr[ $step_name ]['description'] ) ) {
423 return $steps_arr[ $step_name ]['description'];
424 }
425
426 return function_exists( 'wpbc_setup_wizard__get_step_description' )
427 ? wpbc_setup_wizard__get_step_description( $step_name )
428 : '';
429 }
430
431 /**
432 * Get setup step save behavior.
433 *
434 * @param string $step_name Step name.
435 *
436 * @return string
437 */
438 public function get_step_save_behavior( $step_name ) {
439
440 $steps_arr = $this->get_steps_arr();
441
442 if ( isset( $steps_arr[ $step_name ]['save_behavior'] ) ) {
443 return $steps_arr[ $step_name ]['save_behavior'];
444 }
445
446 return function_exists( 'wpbc_setup_wizard__get_step_save_behavior' )
447 ? wpbc_setup_wizard__get_step_save_behavior( $step_name )
448 : 'link_only';
449 }
450
451 /**
452 * Get route metadata value.
453 *
454 * @param string $step_name Step name.
455 * @param string $key Metadata key.
456 *
457 * @return string
458 */
459 public function get_step_meta_value( $step_name, $key ) {
460
461 $steps_arr = $this->get_steps_arr();
462
463 return ( isset( $steps_arr[ $step_name ][ $key ] ) ) ? (string) $steps_arr[ $step_name ][ $key ] : '';
464 }
465
466
467 /**
468 * Get Steps Count -> 9
469 *
470 * @return int
471 */
472 public function get_total_steps_count(){
473
474 $steps_arr = $this->db__get_steps_is_done();
475
476 return count($steps_arr);
477 }
478
479
480 /**
481 * Get % Progress for Setup Steps -> 30
482 * @return int
483 */
484 public function get_progess_value( $current_step = '' ) {
485
486 $total_steps = $this->get_total_steps_count();
487 if ( $total_steps <= 0 ) {
488 return 0;
489 }
490
491 $progess_value = ( $this->get_active_step_num( $current_step ) * 100 ) / $total_steps;
492 $progess_value = intval( $progess_value );
493
494 return $progess_value;
495 }
496
497
498 // =================================================================================================================
499 // == DB :: "Set Wizard Steps as Done" ==
500 // =================================================================================================================
501
502 /**
503 * Get all Steps from DB and from Structure,
504 *
505 * If not saved yet to DB, then get default structure
506 *
507 * And if later Wizard structure ->init_steps_data() was extended, then system get such steps as uncompleted.
508 *
509 * @return array|mixed
510 */
511 public function db__get_steps_is_done() {
512
513 $steps_is_done = get_bk_option( 'booking_setup_wizard_page_steps_is_done' );
514 $is_completed = ( 'On' === get_bk_option( 'booking_setup_wizard_page_is_completed' ) );
515
516 $active_steps_names = array_keys( $this->get_steps_arr() );
517 $normalized_steps = array();
518
519 if ( empty( $active_steps_names ) ) {
520 return is_array( $steps_is_done ) ? $steps_is_done : array();
521 }
522
523 foreach ( $active_steps_names as $step_name ) {
524 $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 );
525 }
526
527 if ( $steps_is_done !== $normalized_steps ) {
528 $this->db__save_steps_is_done( $normalized_steps );
529 }
530
531 return $normalized_steps;
532 }
533
534
535 /**
536 * Save statuses to all steps
537 *
538 * @param $steps_arr
539 *
540 * @return void
541 */
542 public function db__save_steps_is_done( $steps_arr ) {
543 update_bk_option( 'booking_setup_wizard_page_steps_is_done', $steps_arr );
544 }
545
546 /**
547 * Set specific step as Completed
548 *
549 * @param $step_name
550 *
551 * @return void
552 */
553 public function db__set_step_as_completed( $step_name ) {
554
555 $steps_arr = $this->db__get_steps_is_done();
556
557 $steps_arr[ $step_name ] = true;
558
559 $this->db__save_steps_is_done( $steps_arr );
560 $this->db__set_step_as_saved( $step_name, true );
561
562 if ( ! in_array( false, $steps_arr, true ) ) {
563 update_bk_option( 'booking_setup_wizard_page_is_completed', 'On' );
564 }
565 }
566
567 /**
568 * Set specific step as Uncompleted
569 *
570 * @param $step_name
571 *
572 * @return void
573 */
574 public function db__set_step_as_uncompleted( $step_name ) {
575
576 $steps_arr = $this->db__get_steps_is_done();
577
578 $steps_arr[ $step_name ] = false;
579
580 delete_bk_option( 'booking_setup_wizard_page_is_completed' );
581
582 $this->db__save_steps_is_done( $steps_arr );
583 }
584
585 /**
586 * Reset a step and all following steps in the active route.
587 *
588 * Older wizard versions could leave later steps marked as completed, which made the continue handler think setup
589 * was finished too early after Step 5.
590 *
591 * @param string $first_step_name First step to reset.
592 *
593 * @return bool
594 */
595 public function db__reset_steps_from( $first_step_name ) {
596
597 $steps_is_done = $this->db__get_steps_is_done();
598 $steps_is_saved = $this->db__get_steps_is_saved();
599 $should_reset = false;
600
601 if ( ! array_key_exists( $first_step_name, $steps_is_done ) ) {
602 return false;
603 }
604
605 foreach ( array_keys( $steps_is_done ) as $step_name ) {
606 if ( $first_step_name === $step_name ) {
607 $should_reset = true;
608 }
609
610 if ( $should_reset ) {
611 $steps_is_done[ $step_name ] = false;
612 if ( array_key_exists( $step_name, $steps_is_saved ) ) {
613 $steps_is_saved[ $step_name ] = false;
614 }
615 }
616 }
617
618 delete_bk_option( 'booking_setup_wizard_page_is_completed' );
619 $this->db__save_steps_is_done( $steps_is_done );
620 $this->db__save_steps_is_saved( $steps_is_saved );
621
622 return true;
623 }
624
625 /**
626 * Check if specific step 'Is completed' ?
627 *
628 * @param string $step_name
629 *
630 * @return bool
631 */
632 public function db__is_step_completed( $step_name ) {
633
634 $steps_arr = $this->db__get_steps_is_done();
635
636 if ( empty( $steps_arr[ $step_name ] ) ) {
637 return false;
638 } else {
639 return true;
640 }
641 }
642
643
644 /**
645 * Mark All Steps as Completed or Uncompleted
646 *
647 * @param $is_completed bool (default true)
648 *
649 * @return void
650 */
651 public function db__set_all_steps_as( $is_completed = true ) {
652
653 if ( false === $is_completed ) {
654 delete_bk_option( 'booking_setup_wizard_page_steps_is_done' );
655 delete_bk_option( 'booking_setup_wizard_page_is_completed' );
656 } else {
657 update_bk_option( 'booking_setup_wizard_page_is_completed', 'On' );
658 }
659
660 $steps_names = $this->db__get_steps_is_done();
661
662 $steps_names = array_keys( $steps_names );
663 $steps_values = array_fill( 0, count( $steps_names ), $is_completed );
664 $steps_is_done = array_combine( $steps_names, $steps_values );
665
666 // Set all steps as not completed
667 $this->db__save_steps_is_done( $steps_is_done );
668 $this->db__save_steps_is_saved( $steps_is_done );
669 }
670
671 /**
672 * Get saved state for setup steps.
673 *
674 * @return array
675 */
676 public function db__get_steps_is_saved() {
677
678 $steps_is_saved = get_bk_option( 'booking_setup_wizard_page_steps_is_saved' );
679 $is_completed = ( 'On' === get_bk_option( 'booking_setup_wizard_page_is_completed' ) );
680 $normalized = array();
681
682 foreach ( array_keys( $this->get_steps_arr() ) as $step_name ) {
683 $normalized[ $step_name ] = $is_completed ? true : ( ( is_array( $steps_is_saved ) && isset( $steps_is_saved[ $step_name ] ) ) ? (bool) $steps_is_saved[ $step_name ] : false );
684 }
685
686 if ( $steps_is_saved !== $normalized ) {
687 $this->db__save_steps_is_saved( $normalized );
688 }
689
690 return $normalized;
691 }
692
693 /**
694 * Save setup step saved states.
695 *
696 * @param array $steps_arr Saved states.
697 *
698 * @return void
699 */
700 public function db__save_steps_is_saved( $steps_arr ) {
701 update_bk_option( 'booking_setup_wizard_page_steps_is_saved', $steps_arr );
702 }
703
704 /**
705 * Mark a setup step as saved or unsaved.
706 *
707 * @param string $step_name Step name.
708 * @param bool $is_saved Saved flag.
709 *
710 * @return bool
711 */
712 public function db__set_step_as_saved( $step_name, $is_saved = true ) {
713
714 $steps_arr = $this->db__get_steps_is_saved();
715 if ( ! array_key_exists( $step_name, $steps_arr ) ) {
716 return false;
717 }
718
719 $steps_arr[ $step_name ] = (bool) $is_saved;
720 $this->db__save_steps_is_saved( $steps_arr );
721
722 return true;
723 }
724
725 /**
726 * Check whether a setup step has been saved.
727 *
728 * @param string $step_name Step name.
729 *
730 * @return bool
731 */
732 public function db__is_step_saved( $step_name ) {
733
734 if ( 'manual_save_required' !== $this->get_step_save_behavior( $step_name ) ) {
735 return true;
736 }
737
738 $steps_arr = $this->db__get_steps_is_saved();
739
740 return ! empty( $steps_arr[ $step_name ] );
741 }
742
743 /**
744 * Check Is all steps Completed
745 * @return bool
746 */
747 public function db__is_all_steps_completed() {
748
749 if ( 'On' === get_bk_option( 'booking_setup_wizard_page_is_completed' ) ) {
750 return true;
751 }
752
753 $steps_arr = $this->db__get_steps_is_done();
754
755 if ( empty( $steps_arr ) ) {
756 return false;
757 }
758
759 foreach ( $steps_arr as $step_name => $steps_val ) {
760 if ( empty( $steps_val ) ) {
761 return false;
762 }
763 }
764
765 return true;
766 }
767
768
769
770 // =================================================================================================================
771 // == C O N T E N T ==
772 // =================================================================================================================
773
774 // ----------------------------------------------------------
775 // == Left Plugin Menu --> "Setup" with Progress Bar ==
776 // ----------------------------------------------------------
777
778 /**
779 * Main Left Menu Title - "Setup" with Progress Bar
780 *
781 * @return false|string
782 */
783 public function get_plugin_menu_title__setup_progress( $current_step = '' ){
784
785
786 $current_step_for_progress = ( ! empty( $current_step ) ) ? $current_step : $this->get_context_step_name();
787
788 ob_start();
789
790 ?><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;">
791 <div class="name_item" style="margin-top: 0;white-space: nowrap;padding: 0 0 0 0;"><?php esc_html_e( 'Setup', 'booking' ); ?></div>
792 <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">
793 <span class="update-count" style="white-space: nowrap;word-wrap: normal;"><?php
794 echo esc_html( $this->get_active_step_num( $current_step_for_progress ) . ' / ' . $this->get_total_steps_count() );
795 ?></span>
796 </div>
797 <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;">
798 <div class="progress_line" style="font-size: 6px;font-weight: 600;word-wrap: normal;border-radius: 6px;white-space: nowrap;background: #8ECE01;width: <?php
799 echo esc_html( $this->get_progess_value( $current_step_for_progress ) ); ?>%;height: 3px;"></div>
800 </div>
801 </div><?php
802
803 return ob_get_clean();
804 }
805
806 // ----------------------------------------------------------
807 // == Content Top Wizard Button ==
808 // ----------------------------------------------------------
809
810 /**
811 * Black Button at Top Right Side in WPBC plugin menu ( except Wizard page )
812 *
813 * Show Continue Setup Wizard Button
814 * @return void
815 */
816 public function show_top_right_wizard_button() {
817
818 if ( ! wpbc_is_setup_wizard_page() ){
819
820 if (
821 ( ! wpbc_is_user_can_access_wizard_page() ) ||
822 ( $this->db__is_all_steps_completed() )
823 ){
824 return false;
825 }
826
827 if ( self::$is_top_bar_rendered ) {
828 return false;
829 }
830 self::$is_top_bar_rendered = true;
831
832 $current_step = $this->get_context_step_name();
833 $is_external_setup_flow_started = $this->db__is_step_completed( 'bookings_types' );
834 $detected_page_step = ( $is_external_setup_flow_started && function_exists( 'wpbc_setup_wizard__detect_step_from_admin_request' ) )
835 ? wpbc_setup_wizard__detect_step_from_admin_request()
836 : '';
837 $continue_url = $this->get_step_continue_url( $current_step );
838 if ( ! empty( $detected_page_step ) && isset( $this->steps_arr[ $detected_page_step ] ) ) {
839 $continue_url = add_query_arg( 'wpbc_setup_from_page_step', $detected_page_step, $continue_url );
840 }
841 $prior_url = $this->get_step_prior_url( $current_step );
842 $step_title = $this->get_step_title( $current_step );
843 $step_heading = $this->get_step_heading( $current_step );
844 $step_save_page_title = ( 'form_structure' === $current_step ) ? __( 'Form Builder', 'booking' ) : $step_title;
845 $description = $this->get_step_description( $current_step );
846 $save_behavior = $this->get_step_save_behavior( $current_step );
847 $target_selector = $this->get_step_meta_value( $current_step, 'target_selector' );
848 $scroll_selector = $this->get_step_meta_value( $current_step, 'scroll_selector' );
849 $highlight_selector = $this->get_step_meta_value( $current_step, 'highlight_selector' );
850 $form_selector = $this->get_step_meta_value( $current_step, 'form_selector' );
851 $save_selector = $this->get_step_meta_value( $current_step, 'save_selector' );
852 $save_events = $this->get_step_meta_value( $current_step, 'save_events' );
853 $open_action = $this->get_step_meta_value( $current_step, 'open_action' );
854 $continue_title = ( 'complete' === $save_behavior ) ? __( 'Finish Setup', 'booking' ) : __( 'Continue', 'booking' );
855 $is_step_saved = $this->db__is_step_saved( $current_step );
856 $is_continue_disabled = ( 'manual_save_required' === $save_behavior && ! $is_step_saved );
857 $continue_href = $is_continue_disabled ? '#wpbc_setup_save_required' : $continue_url;
858 $mark_saved_nonce = wp_create_nonce( 'wpbc_setup_wizard_mark_step_saved' );
859 $step_target_url = $this->get_step_target_url( $current_step );
860 $skip_wizard_url = add_query_arg( 'wpbc_setup_wizard', 'completed', wpbc_get_bookings_url() );
861 $reset_wizard_url = add_query_arg( 'wpbc_setup_wizard', 'reset', wpbc_get_setup_wizard_page_url() );
862 $save_required_note = sprintf(
863 /* translators: %s: setup target page title. */
864 __( 'Save changes on the %s page before continuing.', 'booking' ),
865 '<a href="' . esc_url( $step_target_url ) . '">' . esc_html( $step_save_page_title ) . '</a>'
866 );
867
868 // FixIn: 10.12.1.1.
869 ?><style type="text/css">
870 @media screen and (max-width: 782px) {
871 .ui_element.wpbc_page_top__wizard_button {
872 /*top: 49px !important;*/
873 }
874 }
875 .wp-admin.wpbc_admin_full_screen .wpbc_header_news {
876 display: none !important;
877 }
878 .wpbc_page_top__wizard_button {
879 width: auto;
880 min-width: 330px;
881 max-width: min(420px, calc(100vw - 30px));
882 position: fixed;
883 z-index: 150000;
884 box-shadow: 0 0 10px #c1c1c1;
885 border-radius: 9px;
886 background: transparent;
887 right: 15px;
888 top: auto !important;
889 bottom: 15px !important;
890 }
891 .wpbc_page_top__wizard_button.wpbc_setup_wizard_bar_is_moved {
892 left: var(--wpbc-setup-bar-left, auto) !important;
893 top: auto !important;
894 right: auto !important;
895 bottom: var(--wpbc-setup-bar-bottom, auto) !important;
896 }
897 .wpbc_page_top__wizard_button.wpbc_setup_wizard_bar_auto_shifted {
898 left: auto !important;
899 top: auto !important;
900 right: var(--wpbc-setup-bar-auto-right, 15px) !important;
901 bottom: 15px !important;
902 }
903 .wpbc_page_top__wizard_button.wpbc_setup_wizard_bar_auto_top {
904 left: auto !important;
905 top: var(--wpbc-setup-bar-auto-top, 15px) !important;
906 right: var(--wpbc-setup-bar-auto-right, 15px) !important;
907 bottom: auto !important;
908 }
909 .wpbc_page_top__wizard_button.wpbc_setup_wizard_bar_is_dragging {
910 user-select: none;
911 }
912 .wpbc_page_top__wizard_button.wpbc_setup_wizard_bar_collapsed {
913 min-width: 260px;
914 }
915 .wpbc_page_top__wizard_button.wpbc_setup_wizard_bar_collapsed .wpbc_setup_wizard_bar_expandable {
916 display: none !important;
917 }
918 div .wpbc_admin_page__tab__builder_booking_form .wpbc_page_top__wizard_button {
919 top: calc(var(--wpbc_ui_top_nav__wp_top_menu_height) + var(--wpbc_ui_top_nav__height) + 10px) !important;
920 top: auto !important;
921 }
922 .ui_element.wpbc_page_top__wizard_button .wpbc_page_top__wizard_button_content,
923 .ui_element.wpbc_page_top__wizard_button .wpbc_page_top__wizard_button_content:hover {
924 border-radius: 5px;
925 border: none;
926 background: #535353; /* #6c9e00 #0b9300;*/
927 box-shadow: 0 0 10px #dbdbdb;
928 text-shadow: none;
929 color: #fff;
930 font-weight: 600;
931 padding: 8px 10px 8px 15px;
932 display: flex;
933 flex-flow: column nowrap;
934 justify-content: flex-start;
935 align-items: stretch;
936 gap: 8px;
937 }
938 .wpbc_setup_wizard_bar_title_row {
939 display: flex;
940 flex-flow: row nowrap;
941 justify-content: flex-start;
942 align-items: center;
943 gap: 8px;
944 width: 100%;
945 border-bottom: 2px solid #686868;
946 padding-bottom: 8px;
947 margin-bottom: 10px;
948 }
949 .wpbc_setup_wizard_bar_title {
950 flex: 1 1 auto;
951 min-width: 0;
952 white-space: nowrap;
953 overflow: hidden;
954 text-overflow: ellipsis;
955 margin-top: 0;
956 padding: 0;
957 }
958 .wpbc_setup_wizard_bar_header_actions {
959 display: flex;
960 flex: 0 0 auto;
961 flex-flow: row nowrap;
962 align-items: center;
963 gap: 2px;
964 margin-left: auto;
965 }
966 .wpbc_setup_wizard_bar_icon_button {
967 display: inline-flex;
968 align-items: center;
969 justify-content: center;
970 width: 24px;
971 height: 24px;
972 min-width: 24px;
973 min-height: 24px;
974 border: 0;
975 border-radius: 4px;
976 background: transparent;
977 color: #fff;
978 cursor: pointer;
979 padding: 0;
980 margin: 0;
981 }
982 .wpbc_setup_wizard_bar_icon_button:hover,
983 .wpbc_setup_wizard_bar_icon_button:focus {
984 background: rgba(255,255,255,0.16);
985 color: #fff;
986 outline: none;
987 box-shadow: none;
988 }
989 .wpbc_setup_wizard_bar_drag_handle {
990 cursor: move;
991 }
992 .wpbc_page_top__wizard_button_actions {
993 display: flex;
994 flex-flow: row nowrap;
995 justify-content: flex-end;
996 align-items: center;
997 gap: 8px;
998 }
999 .wpbc_page_top__wizard_button_actions .button {
1000 font-size: 11px;
1001 min-height: 10px;
1002 line-height: 1.8;
1003 margin: 0;
1004 }
1005 .wpbc_page_top__wizard_button_actions .button.button-secondary {
1006 background-color: #e4e4e4;
1007 }
1008 .wpbc_page_top__wizard_button_actions .button.disabled,
1009 .wpbc_page_top__wizard_button_actions .button[aria-disabled="true"] {
1010 cursor: not-allowed;
1011 opacity: 0.55;
1012 pointer-events: auto;
1013 }
1014 .wpbc_page_top__wizard_button_links {
1015 display: flex;
1016 flex-flow: row wrap;
1017 justify-content: flex-start;
1018 align-items: center;
1019 gap: 1.5em;
1020 font-size: 10px;
1021 font-weight: 400;
1022 line-height: 1.4;
1023 margin-top: -2px;
1024 }
1025 .wpbc_page_top__wizard_button_links a {
1026 color: #e6e6e6;
1027 text-decoration: underline;
1028 text-underline-offset: 2px;
1029 }
1030 .wpbc_page_top__wizard_button_links a:hover,
1031 .wpbc_page_top__wizard_button_links a:focus {
1032 color: #fff;
1033 }
1034 .wpbc_page_top__wizard_button_links a.wpbc_setup_wizard_bar_danger_link {
1035 /*color: #ff9b00;*/
1036 }
1037 .wpbc_page_top__wizard_button_links a.wpbc_setup_wizard_bar_danger_link:hover,
1038 .wpbc_page_top__wizard_button_links a.wpbc_setup_wizard_bar_danger_link:focus {
1039 color: #fff;
1040 }
1041 .wpbc_page_top__wizard_button_note {
1042 font-size: 12px;
1043 font-weight: 400;
1044 line-height: 1.35;
1045 color: #fff;
1046 background: rgb(160, 160, 95);
1047 background: rgb(160, 132, 95);
1048 background: rgb(160, 116, 95);
1049 border-radius: 4px;
1050 padding: 10px 14px;
1051 margin: 8px 0 5px;
1052 }
1053 .wpbc_page_top__wizard_button_note a {
1054 color: #fff;
1055 text-decoration: underline;
1056 text-underline-offset: 2px;
1057 }
1058 .wpbc_page_top__wizard_button_note.wpbc_setup_wizard_bar_note_saved {
1059 background: #4f8f16;
1060 }
1061 .wpbc_setup_wizard_attention_pulse {
1062 animation: wpbc_setup_wizard_attention_pulse 0.62s ease-in-out 3;
1063 }
1064 @keyframes wpbc_setup_wizard_attention_pulse {
1065 0% {
1066 box-shadow: 0 0 0 0 rgba(255, 196, 0, 0.82);
1067 transform: scale(1);
1068 }
1069 50% {
1070 box-shadow: 0 0 0 7px rgba(255, 196, 0, 0.2);
1071 transform: scale(1.025);
1072 }
1073 100% {
1074 box-shadow: 0 0 0 0 rgba(255, 196, 0, 0);
1075 transform: scale(1);
1076 }
1077 }
1078 .wpbc_setup_wizard__target_highlight {
1079 outline: 2px solid #8ECE01 !important;
1080 outline-offset: 3px !important;
1081 box-shadow: 0 0 0 5px rgba(142, 206, 1, 0.16) !important;
1082 transition: outline-color 0.2s ease, box-shadow 0.2s ease;
1083 }
1084 @media screen and (max-width: 782px) {
1085 .wpbc_page_top__wizard_button {
1086 left: 10px !important;
1087 right: 10px !important;
1088 bottom: 10px !important;
1089 top: auto !important;
1090 min-width: 0;
1091 max-width: none;
1092 }
1093 .wpbc_setup_wizard_bar_drag_handle,
1094 .wpbc_setup_wizard_bar_reset_button {
1095 display: none;
1096 }
1097 }
1098 </style>
1099 <div style="top: 35px;font-size: 15px;"
1100 class="ui_element wpbc_page_top__wizard_button"
1101 data-wpbc-setup-step="<?php echo esc_attr( $current_step ); ?>"
1102 data-wpbc-setup-save-behavior="<?php echo esc_attr( $save_behavior ); ?>"
1103 data-wpbc-setup-is-saved="<?php echo esc_attr( $is_step_saved ? '1' : '0' ); ?>"
1104 data-wpbc-setup-ajax-url="<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>"
1105 data-wpbc-setup-mark-saved-nonce="<?php echo esc_attr( $mark_saved_nonce ); ?>"
1106 data-wpbc-setup-target-selector="<?php echo esc_attr( $target_selector ); ?>"
1107 data-wpbc-setup-scroll-selector="<?php echo esc_attr( $scroll_selector ); ?>"
1108 data-wpbc-setup-highlight-selector="<?php echo esc_attr( $highlight_selector ); ?>"
1109 data-wpbc-setup-form-selector="<?php echo esc_attr( $form_selector ); ?>"
1110 data-wpbc-setup-save-selector="<?php echo esc_attr( $save_selector ); ?>"
1111 data-wpbc-setup-save-events="<?php echo esc_attr( $save_events ); ?>"
1112 data-wpbc-setup-open-action="<?php echo esc_attr( $open_action ); ?>">
1113 <div class="wpbc_ui_control wpbc_page_top__wizard_button_content">
1114 <div class="in-button-text"
1115 style="width: 100%;margin: 0;display: flex;flex-flow: column nowrap;justify-content: flex-start;align-items: stretch;gap:8px;">
1116 <div class="setup_wizard_page_container"
1117 style="display: flex;flex-flow: row wrap;justify-content: flex-start;align-items: center;color: #fff;overflow: visible;flex: 1 1 auto;">
1118 <div class="wpbc_setup_wizard_bar_title_row">
1119 <div class="wpbc_setup_wizard_bar_header_actions">
1120 <button type="button"
1121 style="margin: -1px 5px 0 -7px;"
1122 class="wpbc_setup_wizard_bar_icon_button wpbc_setup_wizard_bar_drag_handle"
1123 title="<?php esc_attr_e( 'Move setup bar', 'booking' ); ?>"
1124 aria-label="<?php esc_attr_e( 'Move setup bar', 'booking' ); ?>">
1125 <i class="menu_icon icon-1x wpbc_icn_drag_indicator"></i>
1126 </button>
1127 </div>
1128
1129 <div class="name_item wpbc_setup_wizard_bar_title">
1130 <i style="margin-right: 4px;" class="menu_icon icon-1x wpbc_icn_donut_large wpbc_icn_adjust0"></i> <?php echo esc_html( $step_title ); ?>
1131 </div>
1132 <div class="wpbc_setup_wizard_bar_header_actions">
1133 <button type="button"
1134 class="wpbc_setup_wizard_bar_icon_button wpbc_setup_wizard_bar_reset_button"
1135 title="<?php esc_attr_e( 'Reset setup bar position', 'booking' ); ?>"
1136 aria-label="<?php esc_attr_e( 'Reset setup bar position', 'booking' ); ?>">
1137 <i class="menu_icon icon-1x wpbc_icn_refresh"></i>
1138 </button>
1139 <button type="button"
1140 class="wpbc_setup_wizard_bar_icon_button wpbc_setup_wizard_bar_toggle_button"
1141 title="<?php esc_attr_e( 'Collapse setup bar', 'booking' ); ?>"
1142 aria-label="<?php esc_attr_e( 'Collapse setup bar', 'booking' ); ?>"
1143 aria-expanded="true">
1144 <i class="menu_icon icon-1x wpbc_icn_expand_less"></i>
1145 </button>
1146 </div>
1147 </div>
1148 <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;">
1149 <?php echo esc_html( $step_heading ); ?>
1150 </div>
1151 <?php if ( ! empty( $description ) ) { ?>
1152 <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;">
1153 <?php echo esc_html( $description ); ?>
1154 </div>
1155 <?php } ?>
1156 <div
1157 style="margin:2px 0px 0 9px;font-size: 9px;background: #3e3e3e;height: auto;border-radius: 5px;padding: 0px 7px 0px;margin-left: auto;"
1158 class="wpbc_badge_count name_item update-plugins">
1159 <span class="update-count"
1160 style="white-space: nowrap;word-wrap: normal;"><?php echo esc_html( $this->get_active_step_num( $current_step ) . ' / ' . $this->get_total_steps_count() ); ?></span>
1161 </div>
1162
1163 <div class="progress_line_container"
1164 style="width: 100%;border: 0px solid #757575;height: 3px;border-radius: 6px;margin: 7px 0 0 0;overflow: hidden;background: #202020;">
1165 <div class="progress_line"
1166 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>
1167 </div>
1168 </div>
1169 <?php if ( 'manual_save_required' === $save_behavior ) { ?>
1170 <div class="wpbc_page_top__wizard_button_note wpbc_setup_wizard_bar_expandable<?php echo $is_step_saved ? ' wpbc_setup_wizard_bar_note_saved' : ''; ?>">
1171 <?php
1172 if ( $is_step_saved ) {
1173 esc_html_e( 'Changes saved. You can continue.', 'booking' );
1174 } else {
1175 echo wp_kses_post( $save_required_note );
1176 }
1177 ?>
1178 </div>
1179 <?php } ?>
1180 <div class="wpbc_page_top__wizard_button_actions wpbc_setup_wizard_bar_expandable">
1181 <?php if ( ! empty( $prior_url ) ) { ?>
1182 <a href="<?php echo esc_url( $prior_url ); ?>" class="button button-secondary"><?php esc_html_e( 'Back', 'booking' ); ?></a>
1183 <?php } ?>
1184 <a href="<?php echo esc_url( $continue_href ); ?>"
1185 class="button button-primary wpbc_setup_wizard_continue_button<?php echo $is_continue_disabled ? ' disabled' : ''; ?>"
1186 data-wpbc-setup-continue-url="<?php echo esc_url( $continue_url ); ?>"
1187 <?php echo $is_continue_disabled ? 'aria-disabled="true"' : ''; ?>><?php echo esc_html( $continue_title ); ?></a>
1188 </div>
1189 <div class="wpbc_page_top__wizard_button_links wpbc_setup_wizard_bar_expandable">
1190 <a href="<?php echo esc_url( $skip_wizard_url ); ?>"
1191 title="<?php esc_attr_e( 'Exit and skip the setup wizard', 'booking' ); ?>">
1192 <?php esc_html_e( 'Exit and skip the setup wizard', 'booking' ); ?>
1193 </a>
1194 <a href="<?php echo esc_url( $reset_wizard_url ); ?>"
1195 class="wpbc_setup_wizard_bar_danger_link"
1196 title="<?php esc_attr_e( 'Start Setup from Beginning', 'booking' ); ?>">
1197 <?php esc_html_e( 'Reset Wizard', 'booking' ); ?>
1198 </a>
1199 </div>
1200 </div>
1201 </div>
1202 </div>
1203 <script type="text/javascript">
1204 jQuery( document ).ready( function() {
1205 var $bar = jQuery( '.wpbc_page_top__wizard_button[data-wpbc-setup-step]' ).first();
1206 var step = $bar.attr( 'data-wpbc-setup-step' ) || '';
1207 var saveBehavior = $bar.attr( 'data-wpbc-setup-save-behavior' ) || '';
1208 var selector = $bar.attr( 'data-wpbc-setup-target-selector' ) || '';
1209 var scrollSelector = $bar.attr( 'data-wpbc-setup-scroll-selector' ) || selector;
1210 var highlightSelector = $bar.attr( 'data-wpbc-setup-highlight-selector' ) || selector;
1211 var formSelector = $bar.attr( 'data-wpbc-setup-form-selector' ) || '';
1212 var saveSelector = $bar.attr( 'data-wpbc-setup-save-selector' ) || '';
1213 var saveEvents = ( $bar.attr( 'data-wpbc-setup-save-events' ) || '' ).split( ',' );
1214 var openAction = $bar.attr( 'data-wpbc-setup-open-action' ) || '';
1215 var ajaxUrl = $bar.attr( 'data-wpbc-setup-ajax-url' ) || '';
1216 var nonce = $bar.attr( 'data-wpbc-setup-mark-saved-nonce' ) || '';
1217 var $continueButton = $bar.find( '.wpbc_setup_wizard_continue_button' ).first();
1218 var $note = $bar.find( '.wpbc_page_top__wizard_button_note' ).first();
1219 var savedNote = '<?php echo esc_js( __( 'Changes saved. You can continue.', 'booking' ) ); ?>';
1220 var saveRequiredNote = <?php echo wp_json_encode( wp_kses_post( $save_required_note ) ); ?>;
1221 var $toggleButton = $bar.find( '.wpbc_setup_wizard_bar_toggle_button' ).first();
1222 var $toggleIcon = $toggleButton.find( 'i' ).first();
1223 var $resetButton = $bar.find( '.wpbc_setup_wizard_bar_reset_button' ).first();
1224 var $dragHandle = $bar.find( '.wpbc_setup_wizard_bar_drag_handle' ).first();
1225 var positionStorageKey = 'wpbc_setup_wizard_bar_position';
1226 var collapsedStorageKey = 'wpbc_setup_wizard_bar_collapsed';
1227 var collapseLabel = <?php echo wp_json_encode( __( 'Collapse setup bar', 'booking' ) ); ?>;
1228 var expandLabel = <?php echo wp_json_encode( __( 'Expand setup bar', 'booking' ) ); ?>;
1229 var $target;
1230 var saveClicked = false;
1231
1232 function wpbcSetupWizardStorageGet( key ) {
1233 try {
1234 return window.localStorage.getItem( key );
1235 } catch ( _e ) {
1236 return null;
1237 }
1238 }
1239
1240 function wpbcSetupWizardStorageSet( key, value ) {
1241 try {
1242 window.localStorage.setItem( key, value );
1243 } catch ( _e ) {}
1244 }
1245
1246 function wpbcSetupWizardStorageRemove( key ) {
1247 try {
1248 window.localStorage.removeItem( key );
1249 } catch ( _e ) {}
1250 }
1251
1252 function wpbcSetupWizardIsSmallViewport() {
1253 return window.matchMedia && window.matchMedia( '(max-width: 782px)' ).matches;
1254 }
1255
1256 function wpbcSetupWizardClampPosition( left, bottom ) {
1257 var margin = 10;
1258 var barWidth = $bar.outerWidth() || 330;
1259 var barHeight = $bar.outerHeight() || 120;
1260 var maxLeft = Math.max( margin, jQuery( window ).width() - barWidth - margin );
1261 var maxBottom = Math.max( margin, jQuery( window ).height() - barHeight - margin );
1262
1263 return {
1264 left: Math.min( Math.max( margin, left ), maxLeft ),
1265 bottom: Math.min( Math.max( margin, bottom ), maxBottom )
1266 };
1267 }
1268
1269 function wpbcSetupWizardApplyPosition( position ) {
1270 var clampedPosition;
1271 var positionBottom;
1272
1273 if ( wpbcSetupWizardIsSmallViewport() || ! position ) {
1274 $bar
1275 .removeClass( 'wpbc_setup_wizard_bar_is_moved' )
1276 .removeClass( 'wpbc_setup_wizard_bar_auto_shifted' )
1277 .removeClass( 'wpbc_setup_wizard_bar_auto_top' )
1278 .css( {
1279 '--wpbc-setup-bar-left': '',
1280 '--wpbc-setup-bar-bottom': '',
1281 '--wpbc-setup-bar-auto-right': '',
1282 '--wpbc-setup-bar-auto-top': ''
1283 } );
1284 return;
1285 }
1286
1287 positionBottom = parseFloat( position.bottom );
1288 if ( isNaN( positionBottom ) && ! isNaN( parseFloat( position.top ) ) ) {
1289 positionBottom = jQuery( window ).height() - parseFloat( position.top ) - ( $bar.outerHeight() || 120 );
1290 }
1291
1292 clampedPosition = wpbcSetupWizardClampPosition( parseFloat( position.left ) || 15, isNaN( positionBottom ) ? 15 : positionBottom );
1293 $bar
1294 .addClass( 'wpbc_setup_wizard_bar_is_moved' )
1295 .removeClass( 'wpbc_setup_wizard_bar_auto_shifted' )
1296 .removeClass( 'wpbc_setup_wizard_bar_auto_top' )
1297 .css( {
1298 '--wpbc-setup-bar-left': clampedPosition.left + 'px',
1299 '--wpbc-setup-bar-bottom': clampedPosition.bottom + 'px',
1300 '--wpbc-setup-bar-auto-right': '',
1301 '--wpbc-setup-bar-auto-top': ''
1302 } );
1303 }
1304
1305 function wpbcSetupWizardShouldUseTopDefault() {
1306 return -1 !== jQuery.inArray( step, [
1307 'date_selection',
1308 'changeover_days',
1309 'working_time',
1310 'time_slots_availability'
1311 ] );
1312 }
1313
1314 function wpbcSetupWizardGetRightSidebarOffset() {
1315 var viewportWidth = jQuery( window ).width();
1316 var viewportHeight = jQuery( window ).height();
1317 var $sidebar = jQuery();
1318 var sidebarSelectors = [
1319 '.wpbc_ui_el__vert_right_bar__wrapper',
1320 '.wpbc_ui_el__vert_right_bar',
1321 '.wpbc_ui_el__vert_right_bar__content',
1322 '.wpbc_ui_el__vert_right_bar__content .simplebar-content-wrapper'
1323 ].join( ',' );
1324
1325 jQuery( sidebarSelectors ).filter( ':visible' ).each( function() {
1326 var rect = this.getBoundingClientRect();
1327
1328 if (
1329 rect.width >= 140
1330 && rect.left > ( viewportWidth * 0.45 )
1331 && rect.right > ( viewportWidth - 80 )
1332 && rect.top < ( viewportHeight - 90 )
1333 && rect.bottom > ( viewportHeight * 0.35 )
1334 ) {
1335 $sidebar = jQuery( this );
1336 return false;
1337 }
1338 } );
1339
1340 if ( ! $sidebar.length ) {
1341 return 0;
1342 }
1343
1344 return Math.max( 0, viewportWidth - $sidebar[0].getBoundingClientRect().left + 15 );
1345 }
1346
1347 function wpbcSetupWizardApplyDefaultPosition() {
1348 var rightOffset;
1349 var maxRight;
1350 var barWidth = $bar.outerWidth() || 330;
1351
1352 if ( wpbcSetupWizardIsSmallViewport() ) {
1353 wpbcSetupWizardApplyPosition( null );
1354 return;
1355 }
1356
1357 rightOffset = wpbcSetupWizardGetRightSidebarOffset();
1358 maxRight = Math.max( 15, jQuery( window ).width() - barWidth - 10 );
1359
1360 if ( wpbcSetupWizardShouldUseTopDefault() ) {
1361 $bar
1362 .removeClass( 'wpbc_setup_wizard_bar_is_moved' )
1363 .addClass( 'wpbc_setup_wizard_bar_auto_shifted' )
1364 .addClass( 'wpbc_setup_wizard_bar_auto_top' )
1365 .css( {
1366 '--wpbc-setup-bar-left': '',
1367 '--wpbc-setup-bar-bottom': '',
1368 '--wpbc-setup-bar-auto-right': Math.min( Math.max( rightOffset, 15 ), maxRight ) + 'px',
1369 '--wpbc-setup-bar-auto-top': '15px'
1370 } );
1371 return;
1372 }
1373
1374 if ( rightOffset > 15 ) {
1375 $bar
1376 .removeClass( 'wpbc_setup_wizard_bar_is_moved' )
1377 .removeClass( 'wpbc_setup_wizard_bar_auto_top' )
1378 .addClass( 'wpbc_setup_wizard_bar_auto_shifted' )
1379 .css( {
1380 '--wpbc-setup-bar-left': '',
1381 '--wpbc-setup-bar-bottom': '',
1382 '--wpbc-setup-bar-auto-right': Math.min( rightOffset, maxRight ) + 'px',
1383 '--wpbc-setup-bar-auto-top': ''
1384 } );
1385 return;
1386 }
1387
1388 wpbcSetupWizardApplyPosition( null );
1389 }
1390
1391 function wpbcSetupWizardSavePosition( left, bottom ) {
1392 var clampedPosition = wpbcSetupWizardClampPosition( left, bottom );
1393
1394 wpbcSetupWizardStorageSet( positionStorageKey, JSON.stringify( clampedPosition ) );
1395 wpbcSetupWizardApplyPosition( clampedPosition );
1396 }
1397
1398 function wpbcSetupWizardApplySavedPosition() {
1399 var savedPosition = wpbcSetupWizardStorageGet( positionStorageKey );
1400
1401 if ( ! savedPosition ) {
1402 wpbcSetupWizardApplyDefaultPosition();
1403 return;
1404 }
1405
1406 try {
1407 wpbcSetupWizardApplyPosition( JSON.parse( savedPosition ) );
1408 } catch ( _e ) {
1409 wpbcSetupWizardStorageRemove( positionStorageKey );
1410 wpbcSetupWizardApplyDefaultPosition();
1411 }
1412 }
1413
1414 function wpbcSetupWizardResetPosition() {
1415 wpbcSetupWizardStorageRemove( positionStorageKey );
1416 wpbcSetupWizardApplyDefaultPosition();
1417 }
1418
1419 function wpbcSetupWizardSetCollapsed( isCollapsed ) {
1420 $bar.toggleClass( 'wpbc_setup_wizard_bar_collapsed', !! isCollapsed );
1421 $toggleButton
1422 .attr( 'aria-expanded', isCollapsed ? 'false' : 'true' )
1423 .attr( 'title', isCollapsed ? expandLabel : collapseLabel )
1424 .attr( 'aria-label', isCollapsed ? expandLabel : collapseLabel );
1425 $toggleIcon
1426 .toggleClass( 'wpbc_icn_expand_less', ! isCollapsed )
1427 .toggleClass( 'wpbc_icn_expand_more', !! isCollapsed );
1428 wpbcSetupWizardStorageSet( collapsedStorageKey, isCollapsed ? '1' : '0' );
1429 wpbcSetupWizardApplySavedPosition();
1430 }
1431
1432 $toggleButton.on( 'click', function() {
1433 wpbcSetupWizardSetCollapsed( ! $bar.hasClass( 'wpbc_setup_wizard_bar_collapsed' ) );
1434 } );
1435
1436 $resetButton.on( 'click', function() {
1437 wpbcSetupWizardResetPosition();
1438 } );
1439
1440 $dragHandle.on( 'mousedown', function( event ) {
1441 var startX;
1442 var startY;
1443 var startLeft;
1444 var startBottom;
1445 var rect;
1446 var barHeight;
1447
1448 if ( wpbcSetupWizardIsSmallViewport() || ( event.which && 1 !== event.which ) ) {
1449 return;
1450 }
1451
1452 event.preventDefault();
1453 rect = $bar[0].getBoundingClientRect();
1454 startX = event.clientX;
1455 startY = event.clientY;
1456 startLeft = rect.left;
1457 barHeight = $bar.outerHeight() || rect.height || 120;
1458 startBottom = jQuery( window ).height() - rect.top - barHeight;
1459 $bar.addClass( 'wpbc_setup_wizard_bar_is_dragging' );
1460
1461 jQuery( document )
1462 .off( '.wpbc_setup_wizard_bar_drag' )
1463 .on( 'mousemove.wpbc_setup_wizard_bar_drag', function( moveEvent ) {
1464 wpbcSetupWizardApplyPosition( {
1465 left: startLeft + moveEvent.clientX - startX,
1466 bottom: startBottom - moveEvent.clientY + startY
1467 } );
1468 } )
1469 .on( 'mouseup.wpbc_setup_wizard_bar_drag', function( upEvent ) {
1470 var movedRect = $bar[0].getBoundingClientRect();
1471 var movedBottom = jQuery( window ).height() - movedRect.top - ( $bar.outerHeight() || movedRect.height || 120 );
1472
1473 wpbcSetupWizardSavePosition( movedRect.left, movedBottom );
1474 $bar.removeClass( 'wpbc_setup_wizard_bar_is_dragging' );
1475 jQuery( document ).off( '.wpbc_setup_wizard_bar_drag' );
1476 } );
1477 } );
1478
1479 wpbcSetupWizardSetCollapsed( '1' === wpbcSetupWizardStorageGet( collapsedStorageKey ) );
1480 wpbcSetupWizardApplySavedPosition();
1481 setTimeout( wpbcSetupWizardApplySavedPosition, 400 );
1482 setTimeout( wpbcSetupWizardApplySavedPosition, 1000 );
1483 jQuery( window ).on( 'resize.wpbc_setup_wizard_bar', wpbcSetupWizardApplySavedPosition );
1484
1485 function wpbcSetupWizardOpenPublishArea() {
1486 var isResourcesPage = -1 !== window.location.href.indexOf( 'page=wpbc-resources' );
1487 var publishTabSelectors = [
1488 '.wpdvlp-sub-tabs .nav-tab',
1489 '.wpdvlp-top-tabs .nav-tab',
1490 '.wpbc_settings_navigation_item a',
1491 '.wpbc_ui_el__vert_nav_item a',
1492 '[role="tab"]',
1493 '[data-tab]',
1494 '[data-subtab]'
1495 ].join( ',' );
1496 var publishToggleSelectors = [
1497 '.wpbc_resource_field__switchable a',
1498 '.wpbc_resource_field__switchable button',
1499 '.wpbc_ajx_toolbar a',
1500 '.wpbc_ajx_toolbar button',
1501 'a.button',
1502 'button.button'
1503 ].join( ',' );
1504 var publishTargetSelector = [
1505 '.wpbc_resources_table .ui_group__publish_btn:visible',
1506 '.wpbc_resource_field__switchable.wpbc_resource_field__publish:visible',
1507 '.wpbc_resource_field__publish:visible',
1508 '.wpbc_resource_publish:visible',
1509 '.wpbc_publish_resources:visible',
1510 '.wpbc_resource_shortcode:visible',
1511 '[data-wpbc-resource-publish]:visible',
1512 '#wpbc_booking_resource_table:visible'
1513 ].join( ',' );
1514 var $publishTab;
1515 var $publishToggle;
1516
1517 if ( ( 'wizard_publish' !== step && 'publish_area' !== openAction ) || ! isResourcesPage ) {
1518 return;
1519 }
1520
1521 $publishTab = jQuery( publishTabSelectors ).filter( ':visible' ).filter( function() {
1522 var $element = jQuery( this );
1523 var text = $element.text() || '';
1524 var href = $element.attr( 'href' ) || '';
1525 var dataTab = $element.attr( 'data-tab' ) || '';
1526 var dataSubtab = $element.attr( 'data-subtab' ) || '';
1527 var haystack = ( text + ' ' + href + ' ' + dataTab + ' ' + dataSubtab ).toLowerCase();
1528
1529 if ( $element.closest( '.wpbc_page_top__wizard_button' ).length ) {
1530 return false;
1531 }
1532
1533 return (
1534 -1 !== haystack.indexOf( 'publish' )
1535 || -1 !== haystack.indexOf( 'shortcode' )
1536 || -1 !== haystack.indexOf( 'embed' )
1537 );
1538 } ).first();
1539
1540 if ( $publishTab.length && ! $publishTab.hasClass( 'nav-tab-active' ) && ! $publishTab.parent().hasClass( 'active' ) ) {
1541 $publishTab.trigger( 'click' );
1542 }
1543
1544 if ( ! $publishTab.length ) {
1545 $publishToggle = jQuery( publishToggleSelectors ).filter( ':visible' ).filter( function() {
1546 var $element = jQuery( this );
1547 var text = $element.text() || '';
1548 var title = $element.attr( 'title' ) || $element.attr( 'data-original-title' ) || '';
1549 var onclick = $element.attr( 'onclick' ) || '';
1550 var className = $element.attr( 'class' ) || '';
1551 var haystack = ( text + ' ' + title + ' ' + className ).toLowerCase();
1552
1553 if ( $element.closest( '.wpbc_page_top__wizard_button' ).length ) {
1554 return false;
1555 }
1556
1557 if ( -1 !== onclick.indexOf( 'wpbc_modal_dialog__show__resource_publish' ) ) {
1558 return false;
1559 }
1560
1561 return (
1562 -1 !== haystack.indexOf( 'show publish' )
1563 || -1 !== haystack.indexOf( 'publish option' )
1564 || -1 !== haystack.indexOf( 'shortcode' )
1565 || -1 !== haystack.indexOf( 'resource_field__publish' )
1566 );
1567 } ).first();
1568
1569 if ( $publishToggle.length ) {
1570 $publishToggle.trigger( 'click' );
1571 }
1572 }
1573
1574 setTimeout( function() {
1575 var $publishTarget = jQuery( publishTargetSelector ).first();
1576
1577 if ( ! $publishTarget.length ) {
1578 $publishTarget = jQuery( selector ).filter( ':visible' ).first();
1579 }
1580
1581 if ( ! $publishTarget.length ) {
1582 return;
1583 }
1584
1585 if ( typeof wpbc_scroll_to === 'function' ) {
1586 wpbc_scroll_to( $publishTarget );
1587 } else if ( $publishTarget.offset() ) {
1588 jQuery( 'html, body' ).animate( { scrollTop: $publishTarget.offset().top - 80 }, 300 );
1589 }
1590
1591 if ( typeof wpbc_blink_element === 'function' ) {
1592 wpbc_blink_element( $publishTarget, 3, 300 );
1593 }
1594 }, 450 );
1595 }
1596
1597 wpbcSetupWizardOpenPublishArea();
1598
1599 function wpbcSetupWizardGetFirstElement( selectors ) {
1600 var $element = jQuery();
1601
1602 if ( ! selectors ) {
1603 return $element;
1604 }
1605
1606 try {
1607 $element = jQuery( selectors ).filter( ':visible' ).first();
1608 if ( $element.length ) {
1609 return $element;
1610 }
1611 return jQuery( selectors ).first();
1612 } catch ( _e ) {
1613 return jQuery();
1614 }
1615 }
1616
1617 function wpbcSetupWizardGetScrollableParent( $element ) {
1618 var $scrollParent;
1619
1620 if ( ! $element || ! $element.length ) {
1621 return jQuery();
1622 }
1623
1624 $scrollParent = $element.parents().filter( function() {
1625 var $parent = jQuery( this );
1626 var overflowY = $parent.css( 'overflow-y' );
1627
1628 return (
1629 /(auto|scroll)/.test( overflowY )
1630 && this.scrollHeight > Math.ceil( $parent.innerHeight() ) + 5
1631 );
1632 } ).first();
1633
1634 return $scrollParent;
1635 }
1636
1637 function wpbcSetupWizardScrollToElement( $element ) {
1638 var $scrollParent;
1639 var targetTop;
1640
1641 if ( ! $element || ! $element.length || ! $element.offset() ) {
1642 return;
1643 }
1644
1645 $scrollParent = wpbcSetupWizardGetScrollableParent( $element );
1646 if ( $scrollParent.length && ! $scrollParent.is( 'html, body' ) ) {
1647 targetTop = $element.offset().top - $scrollParent.offset().top + $scrollParent.scrollTop() - 40;
1648 $scrollParent.stop().animate( {
1649 scrollTop: Math.max( 0, targetTop )
1650 }, 350 );
1651 return;
1652 }
1653
1654 if ( typeof wpbc_scroll_to === 'function' ) {
1655 wpbc_scroll_to( $element );
1656 } else {
1657 jQuery( 'html, body' ).stop().animate( {
1658 scrollTop: Math.max( 0, $element.offset().top - 90 )
1659 }, 350 );
1660 }
1661 }
1662
1663 function wpbcSetupWizardHighlightElement( $element ) {
1664 if ( ! $element || ! $element.length ) {
1665 return;
1666 }
1667
1668 $element.addClass( 'wpbc_setup_wizard__target_highlight' );
1669 if ( typeof wpbc_blink_element === 'function' ) {
1670 wpbc_blink_element( $element, 3, 300 );
1671 }
1672 }
1673
1674 function wpbcSetupWizardPulseElement( $element ) {
1675 if ( ! $element || ! $element.length ) {
1676 return;
1677 }
1678
1679 $element
1680 .removeClass( 'wpbc_setup_wizard_attention_pulse' )
1681 .each( function() {
1682 // Restart the CSS animation when the user clicks Continue repeatedly.
1683 void this.offsetWidth;
1684 } )
1685 .addClass( 'wpbc_setup_wizard_attention_pulse' );
1686
1687 setTimeout( function() {
1688 $element.removeClass( 'wpbc_setup_wizard_attention_pulse' );
1689 }, 2100 );
1690 }
1691
1692 function wpbcSetupWizardPulseSaveRequiredMessage() {
1693 if ( $bar.hasClass( 'wpbc_setup_wizard_bar_collapsed' ) ) {
1694 wpbcSetupWizardSetCollapsed( false );
1695 }
1696
1697 if ( $note.length ) {
1698 wpbcSetupWizardPulseElement( $note );
1699 }
1700
1701 setTimeout( function() {
1702 wpbcSetupWizardPulseElement( jQuery( '#ajax_working .wpbc_inner_message.notice-warning' ).last() );
1703 }, 50 );
1704 }
1705
1706 function wpbcSetupWizardSetSaved() {
1707 $bar.attr( 'data-wpbc-setup-is-saved', '1' );
1708 $continueButton
1709 .removeClass( 'disabled' )
1710 .removeAttr( 'aria-disabled' )
1711 .attr( 'href', $continueButton.attr( 'data-wpbc-setup-continue-url' ) || '#' );
1712 if ( $note.length ) {
1713 $note
1714 .addClass( 'wpbc_setup_wizard_bar_note_saved' )
1715 .text( savedNote );
1716 }
1717 }
1718
1719 function wpbcSetupWizardSetUnsaved() {
1720 $bar.attr( 'data-wpbc-setup-is-saved', '0' );
1721 $continueButton
1722 .addClass( 'disabled' )
1723 .attr( 'aria-disabled', 'true' )
1724 .attr( 'href', '#wpbc_setup_save_required' );
1725 if ( $note.length ) {
1726 $note
1727 .removeClass( 'wpbc_setup_wizard_bar_note_saved' )
1728 .html( saveRequiredNote );
1729 }
1730 }
1731
1732 function wpbcSetupWizardMarkSaved() {
1733 if ( ! step || ! ajaxUrl || ! nonce ) {
1734 wpbcSetupWizardSetSaved();
1735 return;
1736 }
1737
1738 jQuery.post( ajaxUrl, {
1739 action: 'WPBC_AJX_SETUP_WIZARD_MARK_STEP_SAVED',
1740 nonce: nonce,
1741 wpbc_setup_step: step
1742 } ).done( function( response ) {
1743 if ( 'string' === typeof response ) {
1744 try {
1745 response = JSON.parse( response );
1746 } catch ( _e ) {}
1747 }
1748 if ( response && response.success ) {
1749 wpbcSetupWizardSetSaved();
1750 }
1751 } );
1752 }
1753
1754 function wpbcSetupWizardSaveStarted() {
1755 saveClicked = true;
1756 }
1757
1758 function wpbcSetupWizardLooksSuccessfulResponse( response ) {
1759 if ( ! response ) {
1760 return true;
1761 }
1762
1763 return (
1764 !! response.success
1765 || 'success' === response.status
1766 || '1' === String( response.ajx_after_action_result || '' )
1767 || ( response.ajx_data && '1' === String( response.ajx_data.ajx_after_action_result || '' ) )
1768 || ( response.data && response.data.setup_step_saved )
1769 );
1770 }
1771
1772 function wpbcSetupWizardRegisterSavedEvent( eventName ) {
1773 eventName = ( eventName || '' ).replace( /^\s+|\s+$/g, '' );
1774 if ( ! eventName ) {
1775 return;
1776 }
1777
1778 document.addEventListener( eventName, function() {
1779 wpbcSetupWizardSetSaved();
1780 wpbcSetupWizardMarkSaved();
1781 }, true );
1782 }
1783
1784 if ( 'manual_save_required' === saveBehavior ) {
1785 window.wpbc_setup_wizard_set_current_step_saved = wpbcSetupWizardSetSaved;
1786 window.wpbc_setup_wizard_mark_current_step_saved = wpbcSetupWizardMarkSaved;
1787
1788 document.addEventListener( 'wpbc:bfb:form:before_save_payload', function( event ) {
1789 if ( ! event || ! event.detail || ! event.detail.payload || ! step ) {
1790 return;
1791 }
1792 wpbcSetupWizardSaveStarted();
1793 event.detail.payload.wpbc_setup = '1';
1794 event.detail.payload.wpbc_setup_step = step;
1795 }, true );
1796
1797 saveEvents.forEach( wpbcSetupWizardRegisterSavedEvent );
1798
1799 if ( formSelector ) {
1800 jQuery( formSelector ).each( function() {
1801 var $form = jQuery( this );
1802 if ( ! $form.is( 'form' ) ) {
1803 return;
1804 }
1805 if ( ! $form.find( 'input[name="wpbc_setup_saved_step"]' ).length ) {
1806 $form.append( '<input type="hidden" name="wpbc_setup_saved_step" value="" />' );
1807 }
1808 if ( ! $form.find( 'input[name="wpbc_setup_step"]' ).length ) {
1809 $form.append( '<input type="hidden" name="wpbc_setup_step" value="" />' );
1810 }
1811 if ( ! $form.find( 'input[name="wpbc_setup"]' ).length ) {
1812 $form.append( '<input type="hidden" name="wpbc_setup" value="" />' );
1813 }
1814 $form.find( 'input[name="wpbc_setup_saved_step"]' ).val( step );
1815 $form.find( 'input[name="wpbc_setup_step"]' ).val( step );
1816 $form.find( 'input[name="wpbc_setup"]' ).val( '1' );
1817 $form
1818 .off( 'change.wpbc_setup_wizard input.wpbc_setup_wizard', ':input' )
1819 .on( 'change.wpbc_setup_wizard input.wpbc_setup_wizard', ':input', function() {
1820 if ( jQuery( this ).is( '[name="wpbc_setup_saved_step"],[name="wpbc_setup_step"],[name="wpbc_setup"],[name="form_visible_section"]' ) ) {
1821 return;
1822 }
1823 wpbcSetupWizardSetUnsaved();
1824 } );
1825 $form
1826 .off( 'submit.wpbc_setup_wizard' )
1827 .on( 'submit.wpbc_setup_wizard', function() {
1828 wpbcSetupWizardSaveStarted();
1829 $form.find( 'input[name="wpbc_setup_saved_step"]' ).val( step );
1830 $form.find( 'input[name="wpbc_setup_step"]' ).val( step );
1831 $form.find( 'input[name="wpbc_setup"]' ).val( '1' );
1832 } );
1833 } );
1834 }
1835
1836 $continueButton.on( 'click', function( event ) {
1837 if ( '1' !== $bar.attr( 'data-wpbc-setup-is-saved' ) ) {
1838 event.preventDefault();
1839 if ( typeof wpbc_admin_show_message === 'function' ) {
1840 wpbc_admin_show_message( '<?php echo esc_js( __( 'Please save changes on this page before continuing setup.', 'booking' ) ); ?>', 'warning', 4000, false );
1841 }
1842 wpbcSetupWizardPulseSaveRequiredMessage();
1843 }
1844 } );
1845
1846 if ( saveSelector ) {
1847 jQuery( document )
1848 .on( 'mousedown.wpbc_setup_wizard click.wpbc_setup_wizard', saveSelector, wpbcSetupWizardSaveStarted )
1849 .on( 'keydown.wpbc_setup_wizard', saveSelector, function( event ) {
1850 if ( 13 === event.which || 32 === event.which ) {
1851 wpbcSetupWizardSaveStarted();
1852 }
1853 } );
1854 }
1855
1856 jQuery( document ).ajaxComplete( function( _event, xhr ) {
1857 var response;
1858 if ( ! saveClicked ) {
1859 return;
1860 }
1861 saveClicked = false;
1862
1863 response = xhr && xhr.responseJSON ? xhr.responseJSON : null;
1864 if ( ! response && xhr && xhr.responseText ) {
1865 try {
1866 response = JSON.parse( xhr.responseText );
1867 } catch ( _e ) {}
1868 }
1869 if ( response && response.data && response.data.setup_step_saved ) {
1870 wpbcSetupWizardSetSaved();
1871 } else if ( wpbcSetupWizardLooksSuccessfulResponse( response ) ) {
1872 wpbcSetupWizardMarkSaved();
1873 }
1874 } );
1875 }
1876
1877 if ( ! selector && ! scrollSelector && ! highlightSelector ) {
1878 return;
1879 }
1880
1881 $target = wpbcSetupWizardGetFirstElement( highlightSelector || selector );
1882 if ( $target.length ) {
1883 wpbcSetupWizardHighlightElement( $target );
1884 }
1885
1886 setTimeout( function() {
1887 var $scrollTarget = wpbcSetupWizardGetFirstElement( scrollSelector || highlightSelector || selector );
1888 if ( ! $scrollTarget.length ) {
1889 $scrollTarget = $target;
1890 }
1891 wpbcSetupWizardScrollToElement( $scrollTarget );
1892 }, 250 );
1893 } );
1894 </script><?php
1895 }
1896 }
1897
1898 }
1899 function wpbc_init_setup_wizard(){
1900 $setup_steps = new WPBC_SETUP_WIZARD_STEPS();
1901 }
1902 // $setup_steps = new WPBC_SETUP_WIZARD_STEPS();
1903 add_action( 'init', 'wpbc_init_setup_wizard' );
1904
1905
1906
1907 /**
1908 * On plugin activation set all steps as completed in Live Demos
1909 * @return void
1910 */
1911 function wpbc_booking_activate_plugin__wizard() {
1912 if ( wpbc_is_this_demo() ) {
1913 $setup_steps = new WPBC_SETUP_WIZARD_STEPS();
1914 $is_completed = true;
1915 $setup_steps->db__set_all_steps_as( $is_completed );
1916 }
1917 }
1918 add_bk_action( 'wpbc_other_versions_activation', 'wpbc_booking_activate_plugin__wizard' );
1919