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