PluginProbe
Booking Calendar / 11.4
Booking Calendar v11.4
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.4, at includes/page-setup/setup_steps.php

2,099 lines 70.9 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 $highlight_disabled = $this->get_step_meta_value( $current_step, 'highlight_disabled' );
851 $form_selector = $this->get_step_meta_value( $current_step, 'form_selector' );
852 $save_selector = $this->get_step_meta_value( $current_step, 'save_selector' );
853 $save_ajax_action = $this->get_step_meta_value( $current_step, 'save_ajax_action' );
854 $save_events = $this->get_step_meta_value( $current_step, 'save_events' );
855 $open_action = $this->get_step_meta_value( $current_step, 'open_action' );
856 $can_save_from_bar = ( 'manual_save_required' === $save_behavior && ! empty( $save_selector ) );
857 $continue_title = ( 'complete' === $save_behavior ) ? __( 'Finish Setup', 'booking' ) : __( 'Continue', 'booking' );
858 if ( $can_save_from_bar ) {
859 $continue_title = __( 'Save and Continue', 'booking' );
860 }
861 $is_step_saved = $this->db__is_step_saved( $current_step );
862 $is_step_unsaved = ( 'manual_save_required' === $save_behavior && ! $is_step_saved );
863 $is_continue_disabled = ( $is_step_unsaved && ! $can_save_from_bar );
864 $continue_href = $is_step_unsaved ? '#wpbc_setup_save_required' : $continue_url;
865 $mark_saved_nonce = wp_create_nonce( 'wpbc_setup_wizard_mark_step_saved' );
866 $step_target_url = $this->get_step_target_url( $current_step );
867 $skip_wizard_url = add_query_arg( 'wpbc_setup_wizard', 'completed', wpbc_get_bookings_url() );
868 $reset_wizard_url = add_query_arg( 'wpbc_setup_wizard', 'reset', wpbc_get_setup_wizard_page_url() );
869 $save_required_note = sprintf(
870 /* translators: %s: setup target page title. */
871 __( 'Save changes on the %s page before continuing.', 'booking' ),
872 '<a href="' . esc_url( $step_target_url ) . '">' . esc_html( $step_save_page_title ) . '</a>'
873 );
874
875 // FixIn: 10.12.1.1.
876 ?><style type="text/css">
877 @media screen and (max-width: 782px) {
878 .ui_element.wpbc_page_top__wizard_button {
879 /*top: 49px !important;*/
880 }
881 }
882 .wp-admin.wpbc_admin_full_screen .wpbc_header_news {
883 display: none !important;
884 }
885 .wpbc_page_top__wizard_button {
886 width: auto;
887 min-width: 330px;
888 max-width: min(420px, calc(100vw - 30px));
889 position: fixed;
890 z-index: 150000;
891 box-shadow: 0 0 10px #c1c1c1;
892 border-radius: 9px;
893 background: transparent;
894 right: 15px;
895 top: auto !important;
896 bottom: 15px !important;
897 }
898 .wpbc_page_top__wizard_button.wpbc_setup_wizard_bar_is_moved {
899 left: var(--wpbc-setup-bar-left, auto) !important;
900 top: auto !important;
901 right: auto !important;
902 bottom: var(--wpbc-setup-bar-bottom, auto) !important;
903 }
904 .wpbc_page_top__wizard_button.wpbc_setup_wizard_bar_auto_shifted {
905 left: auto !important;
906 top: auto !important;
907 right: var(--wpbc-setup-bar-auto-right, 15px) !important;
908 bottom: 15px !important;
909 }
910 .wpbc_page_top__wizard_button.wpbc_setup_wizard_bar_auto_top {
911 left: auto !important;
912 top: var(--wpbc-setup-bar-auto-top, 15px) !important;
913 right: var(--wpbc-setup-bar-auto-right, 15px) !important;
914 bottom: auto !important;
915 }
916 .wpbc_page_top__wizard_button.wpbc_setup_wizard_bar_is_dragging {
917 user-select: none;
918 }
919 .wpbc_page_top__wizard_button.wpbc_setup_wizard_bar_collapsed {
920 min-width: 260px;
921 }
922 .wpbc_page_top__wizard_button.wpbc_setup_wizard_bar_collapsed .wpbc_setup_wizard_bar_expandable {
923 display: none !important;
924 }
925 div .wpbc_admin_page__tab__builder_booking_form .wpbc_page_top__wizard_button {
926 top: calc(var(--wpbc_ui_top_nav__wp_top_menu_height) + var(--wpbc_ui_top_nav__height) + 10px) !important;
927 top: auto !important;
928 }
929 .ui_element.wpbc_page_top__wizard_button .wpbc_page_top__wizard_button_content,
930 .ui_element.wpbc_page_top__wizard_button .wpbc_page_top__wizard_button_content:hover {
931 border-radius: 5px;
932 border: none;
933 background: #535353; /* #6c9e00 #0b9300;*/
934 box-shadow: 0 0 10px #dbdbdb;
935 text-shadow: none;
936 color: #fff;
937 font-weight: 600;
938 padding: 8px 10px 8px 15px;
939 display: flex;
940 flex-flow: column nowrap;
941 justify-content: flex-start;
942 align-items: stretch;
943 gap: 8px;
944 }
945 .wpbc_setup_wizard_bar_title_row {
946 display: flex;
947 flex-flow: row nowrap;
948 justify-content: flex-start;
949 align-items: center;
950 gap: 8px;
951 width: 100%;
952 border-bottom: 2px solid #686868;
953 padding-bottom: 8px;
954 margin-bottom: 10px;
955 }
956 .wpbc_setup_wizard_bar_title {
957 flex: 1 1 auto;
958 min-width: 0;
959 white-space: nowrap;
960 overflow: hidden;
961 text-overflow: ellipsis;
962 margin-top: 0;
963 padding: 0;
964 }
965 .wpbc_setup_wizard_bar_header_actions {
966 display: flex;
967 flex: 0 0 auto;
968 flex-flow: row nowrap;
969 align-items: center;
970 gap: 2px;
971 margin-left: auto;
972 }
973 .wpbc_setup_wizard_bar_icon_button {
974 display: inline-flex;
975 align-items: center;
976 justify-content: center;
977 width: 24px;
978 height: 24px;
979 min-width: 24px;
980 min-height: 24px;
981 border: 0;
982 border-radius: 4px;
983 background: transparent;
984 color: #fff;
985 cursor: pointer;
986 padding: 0;
987 margin: 0;
988 }
989 .wpbc_setup_wizard_bar_icon_button:hover,
990 .wpbc_setup_wizard_bar_icon_button:focus {
991 background: rgba(255,255,255,0.16);
992 color: #fff;
993 outline: none;
994 box-shadow: none;
995 }
996 .wpbc_setup_wizard_bar_drag_handle {
997 cursor: move;
998 }
999 .wpbc_page_top__wizard_button_actions {
1000 display: flex;
1001 flex-flow: row nowrap;
1002 justify-content: flex-end;
1003 align-items: center;
1004 gap: 8px;
1005 }
1006 .wpbc_page_top__wizard_button_actions .button {
1007 font-size: 11px;
1008 min-height: 10px;
1009 line-height: 1.8;
1010 margin: 0;
1011 }
1012 .wpbc_page_top__wizard_button_actions .button.button-secondary {
1013 background-color: #e4e4e4;
1014 }
1015 .wpbc_page_top__wizard_button_actions .button.disabled,
1016 .wpbc_page_top__wizard_button_actions .button[aria-disabled="true"] {
1017 cursor: not-allowed;
1018 opacity: 0.55;
1019 pointer-events: auto;
1020 }
1021 .wpbc_page_top__wizard_button_links {
1022 display: flex;
1023 flex-flow: row wrap;
1024 justify-content: flex-start;
1025 align-items: center;
1026 gap: 1.5em;
1027 font-size: 10px;
1028 font-weight: 400;
1029 line-height: 1.4;
1030 margin-top: -2px;
1031 }
1032 .wpbc_page_top__wizard_button_links a {
1033 color: #e6e6e6;
1034 text-decoration: underline;
1035 text-underline-offset: 2px;
1036 }
1037 .wpbc_page_top__wizard_button_links a:hover,
1038 .wpbc_page_top__wizard_button_links a:focus {
1039 color: #fff;
1040 }
1041 .wpbc_page_top__wizard_button_links a.wpbc_setup_wizard_bar_danger_link {
1042 /*color: #ff9b00;*/
1043 }
1044 .wpbc_page_top__wizard_button_links a.wpbc_setup_wizard_bar_danger_link:hover,
1045 .wpbc_page_top__wizard_button_links a.wpbc_setup_wizard_bar_danger_link:focus {
1046 color: #fff;
1047 }
1048 .wpbc_page_top__wizard_button_note {
1049 font-size: 12px;
1050 font-weight: 400;
1051 line-height: 1.35;
1052 color: #fff;
1053 background: rgb(160, 160, 95);
1054 background: rgb(160, 132, 95);
1055 background: rgb(160, 116, 95);
1056 border-radius: 4px;
1057 padding: 10px 14px;
1058 margin: 8px 0 5px;
1059 }
1060 .wpbc_page_top__wizard_button_note a {
1061 color: #fff;
1062 text-decoration: underline;
1063 text-underline-offset: 2px;
1064 }
1065 .wpbc_page_top__wizard_button_note.wpbc_setup_wizard_bar_note_saved {
1066 background: #4f8f16;
1067 }
1068 .wpbc_setup_wizard_attention_pulse {
1069 animation: wpbc_setup_wizard_attention_pulse 0.62s ease-in-out 3;
1070 }
1071 @keyframes wpbc_setup_wizard_attention_pulse {
1072 0% {
1073 box-shadow: 0 0 0 0 rgba(255, 196, 0, 0.82);
1074 transform: scale(1);
1075 }
1076 50% {
1077 box-shadow: 0 0 0 7px rgba(255, 196, 0, 0.2);
1078 transform: scale(1.025);
1079 }
1080 100% {
1081 box-shadow: 0 0 0 0 rgba(255, 196, 0, 0);
1082 transform: scale(1);
1083 }
1084 }
1085 .wpbc_setup_wizard__target_highlight {
1086 outline: 2px solid #8ECE01 !important;
1087 outline-offset: 3px !important;
1088 box-shadow: 0 0 0 5px rgba(142, 206, 1, 0.16) !important;
1089 transition: outline-color 0.2s ease, box-shadow 0.2s ease;
1090 }
1091 @media screen and (max-width: 782px) {
1092 .wpbc_page_top__wizard_button {
1093 left: 10px !important;
1094 right: 10px !important;
1095 bottom: 10px !important;
1096 top: auto !important;
1097 min-width: 0;
1098 max-width: none;
1099 }
1100 .wpbc_setup_wizard_bar_drag_handle,
1101 .wpbc_setup_wizard_bar_reset_button {
1102 display: none;
1103 }
1104 }
1105 </style>
1106 <div style="top: 35px;font-size: 15px;"
1107 class="ui_element wpbc_page_top__wizard_button"
1108 data-wpbc-setup-step="<?php echo esc_attr( $current_step ); ?>"
1109 data-wpbc-setup-save-behavior="<?php echo esc_attr( $save_behavior ); ?>"
1110 data-wpbc-setup-is-saved="<?php echo esc_attr( $is_step_saved ? '1' : '0' ); ?>"
1111 data-wpbc-setup-ajax-url="<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>"
1112 data-wpbc-setup-mark-saved-nonce="<?php echo esc_attr( $mark_saved_nonce ); ?>"
1113 data-wpbc-setup-target-selector="<?php echo esc_attr( $target_selector ); ?>"
1114 data-wpbc-setup-scroll-selector="<?php echo esc_attr( $scroll_selector ); ?>"
1115 data-wpbc-setup-highlight-selector="<?php echo esc_attr( $highlight_selector ); ?>"
1116 data-wpbc-setup-highlight-disabled="<?php echo esc_attr( $highlight_disabled ); ?>"
1117 data-wpbc-setup-form-selector="<?php echo esc_attr( $form_selector ); ?>"
1118 data-wpbc-setup-save-selector="<?php echo esc_attr( $save_selector ); ?>"
1119 data-wpbc-setup-save-ajax-action="<?php echo esc_attr( $save_ajax_action ); ?>"
1120 data-wpbc-setup-save-events="<?php echo esc_attr( $save_events ); ?>"
1121 data-wpbc-setup-open-action="<?php echo esc_attr( $open_action ); ?>">
1122 <div class="wpbc_ui_control wpbc_page_top__wizard_button_content">
1123 <div class="in-button-text"
1124 style="width: 100%;margin: 0;display: flex;flex-flow: column nowrap;justify-content: flex-start;align-items: stretch;gap:8px;">
1125 <div class="setup_wizard_page_container"
1126 style="display: flex;flex-flow: row wrap;justify-content: flex-start;align-items: center;color: #fff;overflow: visible;flex: 1 1 auto;">
1127 <div class="wpbc_setup_wizard_bar_title_row">
1128 <div class="wpbc_setup_wizard_bar_header_actions">
1129 <button type="button"
1130 style="margin: -1px 5px 0 -7px;"
1131 class="wpbc_setup_wizard_bar_icon_button wpbc_setup_wizard_bar_drag_handle"
1132 title="<?php esc_attr_e( 'Move setup bar', 'booking' ); ?>"
1133 aria-label="<?php esc_attr_e( 'Move setup bar', 'booking' ); ?>">
1134 <i class="menu_icon icon-1x wpbc_icn_drag_indicator"></i>
1135 </button>
1136 </div>
1137
1138 <div class="name_item wpbc_setup_wizard_bar_title">
1139 <i style="margin-right: 4px;" class="menu_icon icon-1x wpbc_icn_donut_large wpbc_icn_adjust0"></i> <?php echo esc_html( $step_title ); ?>
1140 </div>
1141 <div class="wpbc_setup_wizard_bar_header_actions">
1142 <button type="button"
1143 class="wpbc_setup_wizard_bar_icon_button wpbc_setup_wizard_bar_reset_button"
1144 title="<?php esc_attr_e( 'Reset setup bar position', 'booking' ); ?>"
1145 aria-label="<?php esc_attr_e( 'Reset setup bar position', 'booking' ); ?>">
1146 <i class="menu_icon icon-1x wpbc_icn_refresh"></i>
1147 </button>
1148 <button type="button"
1149 class="wpbc_setup_wizard_bar_icon_button wpbc_setup_wizard_bar_toggle_button"
1150 title="<?php esc_attr_e( 'Collapse setup bar', 'booking' ); ?>"
1151 aria-label="<?php esc_attr_e( 'Collapse setup bar', 'booking' ); ?>"
1152 aria-expanded="true">
1153 <i class="menu_icon icon-1x wpbc_icn_expand_less"></i>
1154 </button>
1155 </div>
1156 </div>
1157 <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;">
1158 <?php echo esc_html( $step_heading ); ?>
1159 </div>
1160 <?php if ( ! empty( $description ) ) { ?>
1161 <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;">
1162 <?php echo esc_html( $description ); ?>
1163 </div>
1164 <?php } ?>
1165 <div
1166 style="margin:2px 0px 0 9px;font-size: 9px;background: #3e3e3e;height: auto;border-radius: 5px;padding: 0px 7px 0px;margin-left: auto;"
1167 class="wpbc_badge_count name_item update-plugins">
1168 <span class="update-count"
1169 style="white-space: nowrap;word-wrap: normal;"><?php echo esc_html( $this->get_active_step_num( $current_step ) . ' / ' . $this->get_total_steps_count() ); ?></span>
1170 </div>
1171
1172 <div class="progress_line_container"
1173 style="width: 100%;border: 0px solid #757575;height: 3px;border-radius: 6px;margin: 7px 0 0 0;overflow: hidden;background: #202020;">
1174 <div class="progress_line"
1175 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>
1176 </div>
1177 </div>
1178 <?php if ( 'manual_save_required' === $save_behavior ) { ?>
1179 <div class="wpbc_page_top__wizard_button_note wpbc_setup_wizard_bar_expandable<?php echo $is_step_saved ? ' wpbc_setup_wizard_bar_note_saved' : ''; ?>">
1180 <?php
1181 if ( $is_step_saved ) {
1182 esc_html_e( 'Changes saved. You can continue.', 'booking' );
1183 } else {
1184 echo wp_kses_post( $save_required_note );
1185 }
1186 ?>
1187 </div>
1188 <?php } ?>
1189 <div class="wpbc_page_top__wizard_button_actions wpbc_setup_wizard_bar_expandable">
1190 <?php if ( ! empty( $prior_url ) ) { ?>
1191 <a href="<?php echo esc_url( $prior_url ); ?>" class="button button-secondary"><?php esc_html_e( 'Back', 'booking' ); ?></a>
1192 <?php } ?>
1193 <a href="<?php echo esc_url( $continue_href ); ?>"
1194 class="button button-primary wpbc_setup_wizard_continue_button<?php echo $is_continue_disabled ? ' disabled' : ''; ?>"
1195 data-wpbc-setup-continue-url="<?php echo esc_url( $continue_url ); ?>"
1196 <?php echo $is_continue_disabled ? 'aria-disabled="true"' : ''; ?>><?php echo esc_html( $continue_title ); ?></a>
1197 </div>
1198 <div class="wpbc_page_top__wizard_button_links wpbc_setup_wizard_bar_expandable">
1199 <a href="<?php echo esc_url( $skip_wizard_url ); ?>"
1200 title="<?php esc_attr_e( 'Exit and skip the setup wizard', 'booking' ); ?>">
1201 <?php esc_html_e( 'Exit and skip the setup wizard', 'booking' ); ?>
1202 </a>
1203 <a href="<?php echo esc_url( $reset_wizard_url ); ?>"
1204 class="wpbc_setup_wizard_bar_danger_link"
1205 title="<?php esc_attr_e( 'Start Setup from Beginning', 'booking' ); ?>">
1206 <?php esc_html_e( 'Reset Wizard', 'booking' ); ?>
1207 </a>
1208 </div>
1209 </div>
1210 </div>
1211 </div>
1212 <script type="text/javascript">
1213 jQuery( document ).ready( function() {
1214 var $bar = jQuery( '.wpbc_page_top__wizard_button[data-wpbc-setup-step]' ).first();
1215 var step = $bar.attr( 'data-wpbc-setup-step' ) || '';
1216 var saveBehavior = $bar.attr( 'data-wpbc-setup-save-behavior' ) || '';
1217 var selector = $bar.attr( 'data-wpbc-setup-target-selector' ) || '';
1218 var scrollSelector = $bar.attr( 'data-wpbc-setup-scroll-selector' ) || selector;
1219 var highlightSelector = $bar.attr( 'data-wpbc-setup-highlight-selector' ) || selector;
1220 var highlightDisabled = ( '1' === ( $bar.attr( 'data-wpbc-setup-highlight-disabled' ) || '' ) );
1221 var formSelector = $bar.attr( 'data-wpbc-setup-form-selector' ) || '';
1222 var saveSelector = $bar.attr( 'data-wpbc-setup-save-selector' ) || '';
1223 var saveAjaxAction = $bar.attr( 'data-wpbc-setup-save-ajax-action' ) || '';
1224 var saveEvents = ( $bar.attr( 'data-wpbc-setup-save-events' ) || '' ).split( ',' );
1225 var openAction = $bar.attr( 'data-wpbc-setup-open-action' ) || '';
1226 var ajaxUrl = $bar.attr( 'data-wpbc-setup-ajax-url' ) || '';
1227 var nonce = $bar.attr( 'data-wpbc-setup-mark-saved-nonce' ) || '';
1228 var $continueButton = $bar.find( '.wpbc_setup_wizard_continue_button' ).first();
1229 var $note = $bar.find( '.wpbc_page_top__wizard_button_note' ).first();
1230 var savedNote = '<?php echo esc_js( __( 'Changes saved. You can continue.', 'booking' ) ); ?>';
1231 var saveRequiredNote = <?php echo wp_json_encode( wp_kses_post( $save_required_note ) ); ?>;
1232 var continueTitle = <?php echo wp_json_encode( ( 'complete' === $save_behavior ) ? __( 'Finish Setup', 'booking' ) : __( 'Continue', 'booking' ) ); ?>;
1233 var saveAndContinueTitle = <?php echo wp_json_encode( __( 'Save and Continue', 'booking' ) ); ?>;
1234 var savingTitle = <?php echo wp_json_encode( __( 'Saving', 'booking' ) . '...' ); ?>;
1235 var $toggleButton = $bar.find( '.wpbc_setup_wizard_bar_toggle_button' ).first();
1236 var $toggleIcon = $toggleButton.find( 'i' ).first();
1237 var $resetButton = $bar.find( '.wpbc_setup_wizard_bar_reset_button' ).first();
1238 var $dragHandle = $bar.find( '.wpbc_setup_wizard_bar_drag_handle' ).first();
1239 var positionStorageKey = 'wpbc_setup_wizard_bar_position';
1240 var collapsedStorageKey = 'wpbc_setup_wizard_bar_collapsed';
1241 var collapseLabel = <?php echo wp_json_encode( __( 'Collapse setup bar', 'booking' ) ); ?>;
1242 var expandLabel = <?php echo wp_json_encode( __( 'Expand setup bar', 'booking' ) ); ?>;
1243 var $target;
1244 var saveClicked = false;
1245 var saveAndContinueRequested = false;
1246 var saveAndContinueRedirecting = false;
1247
1248 function wpbcSetupWizardStorageGet( key ) {
1249 try {
1250 return window.localStorage.getItem( key );
1251 } catch ( _e ) {
1252 return null;
1253 }
1254 }
1255
1256 function wpbcSetupWizardStorageSet( key, value ) {
1257 try {
1258 window.localStorage.setItem( key, value );
1259 } catch ( _e ) {}
1260 }
1261
1262 function wpbcSetupWizardStorageRemove( key ) {
1263 try {
1264 window.localStorage.removeItem( key );
1265 } catch ( _e ) {}
1266 }
1267
1268 function wpbcSetupWizardIsSmallViewport() {
1269 return window.matchMedia && window.matchMedia( '(max-width: 782px)' ).matches;
1270 }
1271
1272 function wpbcSetupWizardClampPosition( left, bottom ) {
1273 var margin = 10;
1274 var barWidth = $bar.outerWidth() || 330;
1275 var barHeight = $bar.outerHeight() || 120;
1276 var maxLeft = Math.max( margin, jQuery( window ).width() - barWidth - margin );
1277 var maxBottom = Math.max( margin, jQuery( window ).height() - barHeight - margin );
1278
1279 return {
1280 left: Math.min( Math.max( margin, left ), maxLeft ),
1281 bottom: Math.min( Math.max( margin, bottom ), maxBottom )
1282 };
1283 }
1284
1285 function wpbcSetupWizardApplyPosition( position ) {
1286 var clampedPosition;
1287 var positionBottom;
1288
1289 if ( wpbcSetupWizardIsSmallViewport() || ! position ) {
1290 $bar
1291 .removeClass( 'wpbc_setup_wizard_bar_is_moved' )
1292 .removeClass( 'wpbc_setup_wizard_bar_auto_shifted' )
1293 .removeClass( 'wpbc_setup_wizard_bar_auto_top' )
1294 .css( {
1295 '--wpbc-setup-bar-left': '',
1296 '--wpbc-setup-bar-bottom': '',
1297 '--wpbc-setup-bar-auto-right': '',
1298 '--wpbc-setup-bar-auto-top': ''
1299 } );
1300 return;
1301 }
1302
1303 positionBottom = parseFloat( position.bottom );
1304 if ( isNaN( positionBottom ) && ! isNaN( parseFloat( position.top ) ) ) {
1305 positionBottom = jQuery( window ).height() - parseFloat( position.top ) - ( $bar.outerHeight() || 120 );
1306 }
1307
1308 clampedPosition = wpbcSetupWizardClampPosition( parseFloat( position.left ) || 15, isNaN( positionBottom ) ? 15 : positionBottom );
1309 $bar
1310 .addClass( 'wpbc_setup_wizard_bar_is_moved' )
1311 .removeClass( 'wpbc_setup_wizard_bar_auto_shifted' )
1312 .removeClass( 'wpbc_setup_wizard_bar_auto_top' )
1313 .css( {
1314 '--wpbc-setup-bar-left': clampedPosition.left + 'px',
1315 '--wpbc-setup-bar-bottom': clampedPosition.bottom + 'px',
1316 '--wpbc-setup-bar-auto-right': '',
1317 '--wpbc-setup-bar-auto-top': ''
1318 } );
1319 }
1320
1321 function wpbcSetupWizardShouldUseTopDefault() {
1322 return -1 !== jQuery.inArray( step, [
1323 'date_selection',
1324 'changeover_days',
1325 'working_time',
1326 'time_slots_availability'
1327 ] );
1328 }
1329
1330 function wpbcSetupWizardGetRightSidebarOffset() {
1331 var viewportWidth = jQuery( window ).width();
1332 var viewportHeight = jQuery( window ).height();
1333 var $sidebar = jQuery();
1334 var sidebarSelectors = [
1335 '.wpbc_ui_el__vert_right_bar__wrapper',
1336 '.wpbc_ui_el__vert_right_bar',
1337 '.wpbc_ui_el__vert_right_bar__content',
1338 '.wpbc_ui_el__vert_right_bar__content .simplebar-content-wrapper'
1339 ].join( ',' );
1340
1341 jQuery( sidebarSelectors ).filter( ':visible' ).each( function() {
1342 var rect = this.getBoundingClientRect();
1343
1344 if (
1345 rect.width >= 140
1346 && rect.left > ( viewportWidth * 0.45 )
1347 && rect.right > ( viewportWidth - 80 )
1348 && rect.top < ( viewportHeight - 90 )
1349 && rect.bottom > ( viewportHeight * 0.35 )
1350 ) {
1351 $sidebar = jQuery( this );
1352 return false;
1353 }
1354 } );
1355
1356 if ( ! $sidebar.length ) {
1357 return 0;
1358 }
1359
1360 return Math.max( 0, viewportWidth - $sidebar[0].getBoundingClientRect().left + 15 );
1361 }
1362
1363 function wpbcSetupWizardApplyDefaultPosition() {
1364 var rightOffset;
1365 var maxRight;
1366 var barWidth = $bar.outerWidth() || 330;
1367
1368 if ( wpbcSetupWizardIsSmallViewport() ) {
1369 wpbcSetupWizardApplyPosition( null );
1370 return;
1371 }
1372
1373 rightOffset = wpbcSetupWizardGetRightSidebarOffset();
1374 maxRight = Math.max( 15, jQuery( window ).width() - barWidth - 10 );
1375
1376 if ( wpbcSetupWizardShouldUseTopDefault() ) {
1377 $bar
1378 .removeClass( 'wpbc_setup_wizard_bar_is_moved' )
1379 .addClass( 'wpbc_setup_wizard_bar_auto_shifted' )
1380 .addClass( 'wpbc_setup_wizard_bar_auto_top' )
1381 .css( {
1382 '--wpbc-setup-bar-left': '',
1383 '--wpbc-setup-bar-bottom': '',
1384 '--wpbc-setup-bar-auto-right': Math.min( Math.max( rightOffset, 15 ), maxRight ) + 'px',
1385 '--wpbc-setup-bar-auto-top': '15px'
1386 } );
1387 return;
1388 }
1389
1390 if ( rightOffset > 15 ) {
1391 $bar
1392 .removeClass( 'wpbc_setup_wizard_bar_is_moved' )
1393 .removeClass( 'wpbc_setup_wizard_bar_auto_top' )
1394 .addClass( 'wpbc_setup_wizard_bar_auto_shifted' )
1395 .css( {
1396 '--wpbc-setup-bar-left': '',
1397 '--wpbc-setup-bar-bottom': '',
1398 '--wpbc-setup-bar-auto-right': Math.min( rightOffset, maxRight ) + 'px',
1399 '--wpbc-setup-bar-auto-top': ''
1400 } );
1401 return;
1402 }
1403
1404 wpbcSetupWizardApplyPosition( null );
1405 }
1406
1407 function wpbcSetupWizardSavePosition( left, bottom ) {
1408 var clampedPosition = wpbcSetupWizardClampPosition( left, bottom );
1409
1410 wpbcSetupWizardStorageSet( positionStorageKey, JSON.stringify( clampedPosition ) );
1411 wpbcSetupWizardApplyPosition( clampedPosition );
1412 }
1413
1414 function wpbcSetupWizardApplySavedPosition() {
1415 var savedPosition = wpbcSetupWizardStorageGet( positionStorageKey );
1416
1417 if ( ! savedPosition ) {
1418 wpbcSetupWizardApplyDefaultPosition();
1419 return;
1420 }
1421
1422 try {
1423 wpbcSetupWizardApplyPosition( JSON.parse( savedPosition ) );
1424 } catch ( _e ) {
1425 wpbcSetupWizardStorageRemove( positionStorageKey );
1426 wpbcSetupWizardApplyDefaultPosition();
1427 }
1428 }
1429
1430 function wpbcSetupWizardResetPosition() {
1431 wpbcSetupWizardStorageRemove( positionStorageKey );
1432 wpbcSetupWizardApplyDefaultPosition();
1433 }
1434
1435 function wpbcSetupWizardSetCollapsed( isCollapsed ) {
1436 $bar.toggleClass( 'wpbc_setup_wizard_bar_collapsed', !! isCollapsed );
1437 $toggleButton
1438 .attr( 'aria-expanded', isCollapsed ? 'false' : 'true' )
1439 .attr( 'title', isCollapsed ? expandLabel : collapseLabel )
1440 .attr( 'aria-label', isCollapsed ? expandLabel : collapseLabel );
1441 $toggleIcon
1442 .toggleClass( 'wpbc_icn_expand_less', ! isCollapsed )
1443 .toggleClass( 'wpbc_icn_expand_more', !! isCollapsed );
1444 wpbcSetupWizardStorageSet( collapsedStorageKey, isCollapsed ? '1' : '0' );
1445 wpbcSetupWizardApplySavedPosition();
1446 }
1447
1448 $toggleButton.on( 'click', function() {
1449 wpbcSetupWizardSetCollapsed( ! $bar.hasClass( 'wpbc_setup_wizard_bar_collapsed' ) );
1450 } );
1451
1452 $resetButton.on( 'click', function() {
1453 wpbcSetupWizardResetPosition();
1454 } );
1455
1456 $dragHandle.on( 'mousedown', function( event ) {
1457 var startX;
1458 var startY;
1459 var startLeft;
1460 var startBottom;
1461 var rect;
1462 var barHeight;
1463
1464 if ( wpbcSetupWizardIsSmallViewport() || ( event.which && 1 !== event.which ) ) {
1465 return;
1466 }
1467
1468 event.preventDefault();
1469 rect = $bar[0].getBoundingClientRect();
1470 startX = event.clientX;
1471 startY = event.clientY;
1472 startLeft = rect.left;
1473 barHeight = $bar.outerHeight() || rect.height || 120;
1474 startBottom = jQuery( window ).height() - rect.top - barHeight;
1475 $bar.addClass( 'wpbc_setup_wizard_bar_is_dragging' );
1476
1477 jQuery( document )
1478 .off( '.wpbc_setup_wizard_bar_drag' )
1479 .on( 'mousemove.wpbc_setup_wizard_bar_drag', function( moveEvent ) {
1480 wpbcSetupWizardApplyPosition( {
1481 left: startLeft + moveEvent.clientX - startX,
1482 bottom: startBottom - moveEvent.clientY + startY
1483 } );
1484 } )
1485 .on( 'mouseup.wpbc_setup_wizard_bar_drag', function( upEvent ) {
1486 var movedRect = $bar[0].getBoundingClientRect();
1487 var movedBottom = jQuery( window ).height() - movedRect.top - ( $bar.outerHeight() || movedRect.height || 120 );
1488
1489 wpbcSetupWizardSavePosition( movedRect.left, movedBottom );
1490 $bar.removeClass( 'wpbc_setup_wizard_bar_is_dragging' );
1491 jQuery( document ).off( '.wpbc_setup_wizard_bar_drag' );
1492 } );
1493 } );
1494
1495 wpbcSetupWizardSetCollapsed( '1' === wpbcSetupWizardStorageGet( collapsedStorageKey ) );
1496 wpbcSetupWizardApplySavedPosition();
1497 setTimeout( wpbcSetupWizardApplySavedPosition, 400 );
1498 setTimeout( wpbcSetupWizardApplySavedPosition, 1000 );
1499 jQuery( window ).on( 'resize.wpbc_setup_wizard_bar', wpbcSetupWizardApplySavedPosition );
1500
1501 function wpbcSetupWizardOpenPublishArea() {
1502 var isResourcesPage = -1 !== window.location.href.indexOf( 'page=wpbc-resources' );
1503 var publishTabSelectors = [
1504 '.wpdvlp-sub-tabs .nav-tab',
1505 '.wpdvlp-top-tabs .nav-tab',
1506 '.wpbc_settings_navigation_item a',
1507 '.wpbc_ui_el__vert_nav_item a',
1508 '[role="tab"]',
1509 '[data-tab]',
1510 '[data-subtab]'
1511 ].join( ',' );
1512 var publishToggleSelectors = [
1513 '.wpbc_resource_field__switchable a',
1514 '.wpbc_resource_field__switchable button',
1515 '.wpbc_ajx_toolbar a',
1516 '.wpbc_ajx_toolbar button',
1517 'a.button',
1518 'button.button'
1519 ].join( ',' );
1520 var publishTargetSelector = [
1521 '.wpbc_resources_table .ui_group__publish_btn:visible',
1522 '.wpbc_resource_field__switchable.wpbc_resource_field__publish:visible',
1523 '.wpbc_resource_field__publish:visible',
1524 '.wpbc_resource_publish:visible',
1525 '.wpbc_publish_resources:visible',
1526 '.wpbc_resource_shortcode:visible',
1527 '[data-wpbc-resource-publish]:visible',
1528 '#wpbc_booking_resource_table:visible'
1529 ].join( ',' );
1530 var $publishTab;
1531 var $publishToggle;
1532
1533 if ( ( 'wizard_publish' !== step && 'publish_area' !== openAction ) || ! isResourcesPage ) {
1534 return;
1535 }
1536
1537 $publishTab = jQuery( publishTabSelectors ).filter( ':visible' ).filter( function() {
1538 var $element = jQuery( this );
1539 var text = $element.text() || '';
1540 var href = $element.attr( 'href' ) || '';
1541 var dataTab = $element.attr( 'data-tab' ) || '';
1542 var dataSubtab = $element.attr( 'data-subtab' ) || '';
1543 var haystack = ( text + ' ' + href + ' ' + dataTab + ' ' + dataSubtab ).toLowerCase();
1544
1545 if ( $element.closest( '.wpbc_page_top__wizard_button' ).length ) {
1546 return false;
1547 }
1548
1549 return (
1550 -1 !== haystack.indexOf( 'publish' )
1551 || -1 !== haystack.indexOf( 'shortcode' )
1552 || -1 !== haystack.indexOf( 'embed' )
1553 );
1554 } ).first();
1555
1556 if ( $publishTab.length && ! $publishTab.hasClass( 'nav-tab-active' ) && ! $publishTab.parent().hasClass( 'active' ) ) {
1557 $publishTab.trigger( 'click' );
1558 }
1559
1560 if ( ! $publishTab.length ) {
1561 $publishToggle = jQuery( publishToggleSelectors ).filter( ':visible' ).filter( function() {
1562 var $element = jQuery( this );
1563 var text = $element.text() || '';
1564 var title = $element.attr( 'title' ) || $element.attr( 'data-original-title' ) || '';
1565 var onclick = $element.attr( 'onclick' ) || '';
1566 var className = $element.attr( 'class' ) || '';
1567 var haystack = ( text + ' ' + title + ' ' + className ).toLowerCase();
1568
1569 if ( $element.closest( '.wpbc_page_top__wizard_button' ).length ) {
1570 return false;
1571 }
1572
1573 if ( -1 !== onclick.indexOf( 'wpbc_modal_dialog__show__resource_publish' ) ) {
1574 return false;
1575 }
1576
1577 return (
1578 -1 !== haystack.indexOf( 'show publish' )
1579 || -1 !== haystack.indexOf( 'publish option' )
1580 || -1 !== haystack.indexOf( 'shortcode' )
1581 || -1 !== haystack.indexOf( 'resource_field__publish' )
1582 );
1583 } ).first();
1584
1585 if ( $publishToggle.length ) {
1586 $publishToggle.trigger( 'click' );
1587 }
1588 }
1589
1590 setTimeout( function() {
1591 var $publishTarget = jQuery( publishTargetSelector ).first();
1592
1593 if ( ! $publishTarget.length ) {
1594 $publishTarget = jQuery( selector ).filter( ':visible' ).first();
1595 }
1596
1597 if ( ! $publishTarget.length ) {
1598 return;
1599 }
1600
1601 if ( typeof wpbc_scroll_to === 'function' ) {
1602 wpbc_scroll_to( $publishTarget );
1603 } else if ( $publishTarget.offset() ) {
1604 jQuery( 'html, body' ).animate( { scrollTop: $publishTarget.offset().top - 80 }, 300 );
1605 }
1606
1607 if ( typeof wpbc_blink_element === 'function' ) {
1608 wpbc_blink_element( $publishTarget, 3, 300 );
1609 }
1610 }, 450 );
1611 }
1612
1613 wpbcSetupWizardOpenPublishArea();
1614
1615 function wpbcSetupWizardGetFirstElement( selectors ) {
1616 var $element = jQuery();
1617
1618 if ( ! selectors ) {
1619 return $element;
1620 }
1621
1622 try {
1623 $element = jQuery( selectors ).filter( ':visible' ).first();
1624 if ( $element.length ) {
1625 return $element;
1626 }
1627 return jQuery( selectors ).first();
1628 } catch ( _e ) {
1629 return jQuery();
1630 }
1631 }
1632
1633 function wpbcSetupWizardGetScrollableParent( $element ) {
1634 var $scrollParent;
1635
1636 if ( ! $element || ! $element.length ) {
1637 return jQuery();
1638 }
1639
1640 $scrollParent = $element.parents().filter( function() {
1641 var $parent = jQuery( this );
1642 var overflowY = $parent.css( 'overflow-y' );
1643
1644 return (
1645 /(auto|scroll)/.test( overflowY )
1646 && this.scrollHeight > Math.ceil( $parent.innerHeight() ) + 5
1647 );
1648 } ).first();
1649
1650 return $scrollParent;
1651 }
1652
1653 function wpbcSetupWizardScrollToElement( $element ) {
1654 var $scrollParent;
1655 var targetTop;
1656
1657 if ( ! $element || ! $element.length || ! $element.offset() ) {
1658 return;
1659 }
1660
1661 $scrollParent = wpbcSetupWizardGetScrollableParent( $element );
1662 if ( $scrollParent.length && ! $scrollParent.is( 'html, body' ) ) {
1663 targetTop = $element.offset().top - $scrollParent.offset().top + $scrollParent.scrollTop() - 40;
1664 $scrollParent.stop().animate( {
1665 scrollTop: Math.max( 0, targetTop )
1666 }, 350 );
1667 return;
1668 }
1669
1670 if ( typeof wpbc_scroll_to === 'function' ) {
1671 wpbc_scroll_to( $element );
1672 } else {
1673 jQuery( 'html, body' ).stop().animate( {
1674 scrollTop: Math.max( 0, $element.offset().top - 90 )
1675 }, 350 );
1676 }
1677 }
1678
1679 function wpbcSetupWizardHighlightElement( $element ) {
1680 if ( ! $element || ! $element.length ) {
1681 return;
1682 }
1683
1684 $element.addClass( 'wpbc_setup_wizard__target_highlight' );
1685 if ( typeof wpbc_blink_element === 'function' ) {
1686 wpbc_blink_element( $element, 3, 300 );
1687 }
1688 }
1689
1690 function wpbcSetupWizardPulseElement( $element ) {
1691 if ( ! $element || ! $element.length ) {
1692 return;
1693 }
1694
1695 $element
1696 .removeClass( 'wpbc_setup_wizard_attention_pulse' )
1697 .each( function() {
1698 // Restart the CSS animation when the user clicks Continue repeatedly.
1699 void this.offsetWidth;
1700 } )
1701 .addClass( 'wpbc_setup_wizard_attention_pulse' );
1702
1703 setTimeout( function() {
1704 $element.removeClass( 'wpbc_setup_wizard_attention_pulse' );
1705 }, 2100 );
1706 }
1707
1708 function wpbcSetupWizardPulseSaveRequiredMessage() {
1709 if ( $bar.hasClass( 'wpbc_setup_wizard_bar_collapsed' ) ) {
1710 wpbcSetupWizardSetCollapsed( false );
1711 }
1712
1713 if ( $note.length ) {
1714 wpbcSetupWizardPulseElement( $note );
1715 }
1716
1717 setTimeout( function() {
1718 wpbcSetupWizardPulseElement( jQuery( '#ajax_working .wpbc_inner_message.notice-warning' ).last() );
1719 }, 50 );
1720 }
1721
1722 function wpbcSetupWizardSetSaved() {
1723 $bar.attr( 'data-wpbc-setup-is-saved', '1' );
1724 $continueButton
1725 .removeClass( 'disabled' )
1726 .removeAttr( 'aria-disabled' )
1727 .attr( 'href', $continueButton.attr( 'data-wpbc-setup-continue-url' ) || '#' )
1728 .text( continueTitle );
1729 if ( $note.length ) {
1730 $note
1731 .addClass( 'wpbc_setup_wizard_bar_note_saved' )
1732 .text( savedNote );
1733 }
1734 }
1735
1736 function wpbcSetupWizardSetUnsaved() {
1737 $bar.attr( 'data-wpbc-setup-is-saved', '0' );
1738 $continueButton.attr( 'href', '#wpbc_setup_save_required' ).text( saveSelector ? saveAndContinueTitle : continueTitle );
1739 if ( saveSelector ) {
1740 $continueButton.removeClass( 'disabled' ).removeAttr( 'aria-disabled' );
1741 } else {
1742 $continueButton.addClass( 'disabled' ).attr( 'aria-disabled', 'true' );
1743 }
1744 if ( $note.length ) {
1745 $note
1746 .removeClass( 'wpbc_setup_wizard_bar_note_saved' )
1747 .html( saveRequiredNote );
1748 }
1749 }
1750
1751 function wpbcSetupWizardSetSaveAndContinueBusy( isBusy ) {
1752 if ( ! saveSelector ) {
1753 return;
1754 }
1755
1756 $continueButton.toggleClass( 'disabled', !! isBusy ).text( isBusy ? savingTitle : saveAndContinueTitle );
1757 if ( isBusy ) {
1758 $continueButton.attr( 'aria-disabled', 'true' );
1759 } else {
1760 $continueButton.removeAttr( 'aria-disabled' );
1761 }
1762 }
1763
1764 function wpbcSetupWizardGetContinueUrl() {
1765 return $continueButton.attr( 'data-wpbc-setup-continue-url' ) || $continueButton.attr( 'href' ) || '';
1766 }
1767
1768 function wpbcSetupWizardContinueAfterSave() {
1769 var continueUrl;
1770
1771 if ( saveAndContinueRedirecting ) {
1772 return;
1773 }
1774
1775 continueUrl = wpbcSetupWizardGetContinueUrl();
1776 if ( ! continueUrl || '#wpbc_setup_save_required' === continueUrl ) {
1777 wpbcSetupWizardSetSaveAndContinueBusy( false );
1778 return;
1779 }
1780
1781 saveAndContinueRedirecting = true;
1782 window.location.href = continueUrl;
1783 }
1784
1785 function wpbcSetupWizardMarkSaved( afterSavedCallback ) {
1786 if ( ! step || ! ajaxUrl || ! nonce ) {
1787 wpbcSetupWizardSetSaved();
1788 if ( 'function' === typeof afterSavedCallback ) {
1789 afterSavedCallback();
1790 }
1791 return;
1792 }
1793
1794 jQuery.post( ajaxUrl, {
1795 action: 'WPBC_AJX_SETUP_WIZARD_MARK_STEP_SAVED',
1796 nonce: nonce,
1797 wpbc_setup_step: step
1798 } ).done( function( response ) {
1799 if ( 'string' === typeof response ) {
1800 try {
1801 response = JSON.parse( response );
1802 } catch ( _e ) {}
1803 }
1804 if ( response && response.success ) {
1805 wpbcSetupWizardSetSaved();
1806 if ( 'function' === typeof afterSavedCallback ) {
1807 afterSavedCallback();
1808 }
1809 }
1810 } ).fail( function() {
1811 if ( saveAndContinueRequested ) {
1812 wpbcSetupWizardSetSaveAndContinueBusy( false );
1813 saveAndContinueRequested = false;
1814 }
1815 } );
1816 }
1817
1818 function wpbcSetupWizardSaveStarted() {
1819 saveClicked = true;
1820 }
1821
1822 function wpbcSetupWizardLooksSuccessfulResponse( response ) {
1823 if ( ! response ) {
1824 return false;
1825 }
1826
1827 return (
1828 !! response.success
1829 || 'success' === response.status
1830 || '1' === String( response.ajx_after_action_result || '' )
1831 || ( response.ajx_data && '1' === String( response.ajx_data.ajx_after_action_result || '' ) )
1832 || ( response.data && response.data.setup_step_saved )
1833 );
1834 }
1835
1836 function wpbcSetupWizardGetAjaxAction( ajaxSettings ) {
1837 var data = ajaxSettings && ajaxSettings.data ? ajaxSettings.data : '';
1838 var matches;
1839
1840 if ( ! data ) {
1841 return '';
1842 }
1843
1844 if ( 'string' === typeof data ) {
1845 matches = data.match( /(?:^|&)action=([^&]+)/ );
1846 return matches && matches[1] ? decodeURIComponent( matches[1].replace( /\+/g, ' ' ) ) : '';
1847 }
1848
1849 if ( window.FormData && data instanceof window.FormData && 'function' === typeof data.get ) {
1850 return data.get( 'action' ) || '';
1851 }
1852
1853 if ( 'object' === typeof data && data.action ) {
1854 return data.action;
1855 }
1856
1857 return '';
1858 }
1859
1860 function wpbcSetupWizardIsExpectedSaveAjax( ajaxSettings ) {
1861 var ajaxAction;
1862
1863 if ( ! saveAjaxAction ) {
1864 return true;
1865 }
1866
1867 ajaxAction = wpbcSetupWizardGetAjaxAction( ajaxSettings );
1868
1869 return saveAjaxAction === ajaxAction;
1870 }
1871
1872 function wpbcSetupWizardHandleSavedEvent() {
1873 saveClicked = false;
1874 wpbcSetupWizardSetSaved();
1875 if ( saveAndContinueRequested ) {
1876 wpbcSetupWizardMarkSaved( wpbcSetupWizardContinueAfterSave );
1877 return;
1878 }
1879 wpbcSetupWizardMarkSaved();
1880 }
1881
1882 function wpbcSetupWizardRegisterSavedEvent( eventName ) {
1883 eventName = ( eventName || '' ).replace( /^\s+|\s+$/g, '' );
1884 if ( ! eventName ) {
1885 return;
1886 }
1887
1888 document.addEventListener( eventName, wpbcSetupWizardHandleSavedEvent, true );
1889 jQuery( document ).on( eventName + '.wpbc_setup_wizard', wpbcSetupWizardHandleSavedEvent );
1890 }
1891
1892 function wpbcSetupWizardFindSaveControl() {
1893 var $saveControl = wpbcSetupWizardGetFirstElement( saveSelector );
1894
1895 if ( $saveControl.length ) {
1896 return $saveControl;
1897 }
1898
1899 if ( ! formSelector ) {
1900 return jQuery();
1901 }
1902
1903 return wpbcSetupWizardGetFirstElement(
1904 formSelector + ' button[type="submit"],' +
1905 formSelector + ' input[type="submit"],' +
1906 formSelector + ' .wpbc_submit_button_trigger,' +
1907 formSelector + ' .wpbc_submit_button'
1908 );
1909 }
1910
1911 function wpbcSetupWizardTriggerSaveAndContinue() {
1912 var $saveControl = wpbcSetupWizardFindSaveControl();
1913
1914 if ( saveAndContinueRequested ) {
1915 return;
1916 }
1917
1918 if ( ! $saveControl.length || $saveControl.hasClass( 'disabled' ) || 'true' === $saveControl.attr( 'aria-disabled' ) ) {
1919 if ( typeof wpbc_admin_show_message === 'function' ) {
1920 wpbc_admin_show_message( '<?php echo esc_js( __( 'Please save changes on this page before continuing setup.', 'booking' ) ); ?>', 'warning', 4000, false );
1921 }
1922 wpbcSetupWizardPulseSaveRequiredMessage();
1923 return;
1924 }
1925
1926 saveAndContinueRequested = true;
1927 wpbcSetupWizardSaveStarted();
1928 wpbcSetupWizardSetSaveAndContinueBusy( true );
1929 if ( formSelector ) {
1930 jQuery( formSelector ).find( 'input[name="wpbc_setup_continue_after_save"]' ).val( '1' );
1931 }
1932 $saveControl.trigger( 'click' );
1933 }
1934
1935 if ( 'manual_save_required' === saveBehavior ) {
1936 window.wpbc_setup_wizard_set_current_step_saved = wpbcSetupWizardSetSaved;
1937 window.wpbc_setup_wizard_mark_current_step_saved = wpbcSetupWizardMarkSaved;
1938
1939 document.addEventListener( 'wpbc:bfb:form:before_save_payload', function( event ) {
1940 if ( ! event || ! event.detail || ! event.detail.payload || ! step ) {
1941 return;
1942 }
1943 wpbcSetupWizardSaveStarted();
1944 event.detail.payload.wpbc_setup = '1';
1945 event.detail.payload.wpbc_setup_step = step;
1946 if ( saveAndContinueRequested ) {
1947 event.detail.payload.wpbc_setup_continue_after_save = '1';
1948 }
1949 }, true );
1950
1951 saveEvents.forEach( wpbcSetupWizardRegisterSavedEvent );
1952
1953 if ( formSelector ) {
1954 jQuery( formSelector ).each( function() {
1955 var $form = jQuery( this );
1956 if ( ! $form.is( 'form' ) ) {
1957 return;
1958 }
1959 if ( ! $form.find( 'input[name="wpbc_setup_saved_step"]' ).length ) {
1960 $form.append( '<input type="hidden" name="wpbc_setup_saved_step" value="" />' );
1961 }
1962 if ( ! $form.find( 'input[name="wpbc_setup_step"]' ).length ) {
1963 $form.append( '<input type="hidden" name="wpbc_setup_step" value="" />' );
1964 }
1965 if ( ! $form.find( 'input[name="wpbc_setup"]' ).length ) {
1966 $form.append( '<input type="hidden" name="wpbc_setup" value="" />' );
1967 }
1968 if ( ! $form.find( 'input[name="wpbc_setup_continue_after_save"]' ).length ) {
1969 $form.append( '<input type="hidden" name="wpbc_setup_continue_after_save" value="" />' );
1970 }
1971 $form.find( 'input[name="wpbc_setup_saved_step"]' ).val( step );
1972 $form.find( 'input[name="wpbc_setup_step"]' ).val( step );
1973 $form.find( 'input[name="wpbc_setup"]' ).val( '1' );
1974 $form.find( 'input[name="wpbc_setup_continue_after_save"]' ).val( '0' );
1975 $form
1976 .off( 'change.wpbc_setup_wizard input.wpbc_setup_wizard', ':input' )
1977 .on( 'change.wpbc_setup_wizard input.wpbc_setup_wizard', ':input', function() {
1978 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"]' ) ) {
1979 return;
1980 }
1981 wpbcSetupWizardSetUnsaved();
1982 } );
1983 $form
1984 .off( 'submit.wpbc_setup_wizard' )
1985 .on( 'submit.wpbc_setup_wizard', function() {
1986 wpbcSetupWizardSaveStarted();
1987 $form.find( 'input[name="wpbc_setup_saved_step"]' ).val( step );
1988 $form.find( 'input[name="wpbc_setup_step"]' ).val( step );
1989 $form.find( 'input[name="wpbc_setup"]' ).val( '1' );
1990 $form.find( 'input[name="wpbc_setup_continue_after_save"]' ).val( saveAndContinueRequested ? '1' : '0' );
1991 } );
1992 } );
1993 }
1994
1995 $continueButton.on( 'click', function( event ) {
1996 if ( '1' !== $bar.attr( 'data-wpbc-setup-is-saved' ) ) {
1997 event.preventDefault();
1998 if ( saveSelector ) {
1999 wpbcSetupWizardTriggerSaveAndContinue();
2000 return;
2001 }
2002 if ( typeof wpbc_admin_show_message === 'function' ) {
2003 wpbc_admin_show_message( '<?php echo esc_js( __( 'Please save changes on this page before continuing setup.', 'booking' ) ); ?>', 'warning', 4000, false );
2004 }
2005 wpbcSetupWizardPulseSaveRequiredMessage();
2006 }
2007 } );
2008
2009 if ( saveSelector ) {
2010 jQuery( document )
2011 .on( 'mousedown.wpbc_setup_wizard click.wpbc_setup_wizard', saveSelector, wpbcSetupWizardSaveStarted )
2012 .on( 'keydown.wpbc_setup_wizard', saveSelector, function( event ) {
2013 if ( 13 === event.which || 32 === event.which ) {
2014 wpbcSetupWizardSaveStarted();
2015 }
2016 } );
2017 }
2018
2019 jQuery( document ).ajaxComplete( function( _event, xhr, ajaxSettings ) {
2020 var response;
2021 if ( ! saveClicked ) {
2022 return;
2023 }
2024 if ( ! wpbcSetupWizardIsExpectedSaveAjax( ajaxSettings ) ) {
2025 return;
2026 }
2027 saveClicked = false;
2028
2029 response = xhr && xhr.responseJSON ? xhr.responseJSON : null;
2030 if ( ! response && xhr && xhr.responseText ) {
2031 try {
2032 response = JSON.parse( xhr.responseText );
2033 } catch ( _e ) {}
2034 }
2035 if ( response && response.data && response.data.setup_step_saved ) {
2036 wpbcSetupWizardSetSaved();
2037 if ( saveAndContinueRequested ) {
2038 wpbcSetupWizardContinueAfterSave();
2039 }
2040 } else if ( wpbcSetupWizardLooksSuccessfulResponse( response ) ) {
2041 if ( saveAndContinueRequested ) {
2042 wpbcSetupWizardMarkSaved( wpbcSetupWizardContinueAfterSave );
2043 } else {
2044 wpbcSetupWizardMarkSaved();
2045 }
2046 } else if ( saveAndContinueRequested ) {
2047 wpbcSetupWizardSetSaveAndContinueBusy( false );
2048 saveAndContinueRequested = false;
2049 }
2050 } );
2051 }
2052
2053 if ( highlightDisabled ) {
2054 highlightSelector = '';
2055 }
2056
2057 if ( ! selector && ! scrollSelector && ! highlightSelector ) {
2058 return;
2059 }
2060
2061 $target = highlightDisabled ? jQuery() : wpbcSetupWizardGetFirstElement( highlightSelector || selector );
2062 if ( ! highlightDisabled && $target.length ) {
2063 wpbcSetupWizardHighlightElement( $target );
2064 }
2065
2066 setTimeout( function() {
2067 var $scrollTarget = wpbcSetupWizardGetFirstElement( scrollSelector || ( highlightDisabled ? selector : highlightSelector ) || selector );
2068 if ( ! $scrollTarget.length ) {
2069 $scrollTarget = $target;
2070 }
2071 wpbcSetupWizardScrollToElement( $scrollTarget );
2072 }, 250 );
2073 } );
2074 </script><?php
2075 }
2076 }
2077
2078 }
2079 function wpbc_init_setup_wizard(){
2080 $setup_steps = new WPBC_SETUP_WIZARD_STEPS();
2081 }
2082 // $setup_steps = new WPBC_SETUP_WIZARD_STEPS();
2083 add_action( 'init', 'wpbc_init_setup_wizard' );
2084
2085
2086
2087 /**
2088 * On plugin activation set all steps as completed in Live Demos
2089 * @return void
2090 */
2091 function wpbc_booking_activate_plugin__wizard() {
2092 if ( wpbc_is_this_demo() ) {
2093 $setup_steps = new WPBC_SETUP_WIZARD_STEPS();
2094 $is_completed = true;
2095 $setup_steps->db__set_all_steps_as( $is_completed );
2096 }
2097 }
2098 add_bk_action( 'wpbc_other_versions_activation', 'wpbc_booking_activate_plugin__wizard' );
2099