PluginProbe
Booking Calendar / 11.6.1
Booking Calendar v11.6.1
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_profiles.php

setup_profiles.php in Booking Calendar 11.6.1, at includes/page-setup/setup_profiles.php

1,198 lines 43.2 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 Booking profile helpers for Setup Wizard.
4 * @category Setup Wizard
5 */
6
7 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly.
8
9 /**
10 * Store the WPBC admin fullscreen preference for the current user.
11 *
12 * The top navigation fullscreen button stores this value through WPBC_User_Custom_Data_Saver as
13 * "booking_custom_is_full_screen" => array( 'value' => 'On|Off' ). Setup routing happens before redirects, so the
14 * wizard updates the same preference and its immediate browser cookie when it moves between internal and external
15 * setup screens. Synchronizing both values prevents an older cookie from overriding the active wizard state.
16 * This sends a response cookie when headers remain available and always updates the cookie value for the current
17 * request.
18 *
19 * @param bool $is_full_screen Whether WPBC admin pages should open in fullscreen mode.
20 *
21 * @return bool True when the saved user option changed; otherwise false.
22 */
23 function wpbc_setup_wizard__set_full_screen_mode_for_current_user( $is_full_screen ) {
24
25 $user_id = wpbc_get_current_user_id();
26
27 if ( empty( $user_id ) ) {
28 return false;
29 }
30
31 $full_screen_value = $is_full_screen ? 'On' : 'Off';
32 $cookie_path = ( defined( 'COOKIEPATH' ) && COOKIEPATH ) ? COOKIEPATH : '/';
33 $cookie_domain = defined( 'COOKIE_DOMAIN' ) ? COOKIE_DOMAIN : '';
34
35 if ( ! headers_sent() ) {
36 setcookie(
37 'wpbc_admin_full_screen',
38 $full_screen_value,
39 time() + YEAR_IN_SECONDS,
40 $cookie_path,
41 $cookie_domain,
42 is_ssl(),
43 false
44 );
45 }
46
47 // Keep cookie-aware page rendering deterministic during the current request.
48 $_COOKIE['wpbc_admin_full_screen'] = $full_screen_value;
49
50 return update_user_option(
51 $user_id,
52 'booking_custom_is_full_screen',
53 array( 'value' => $full_screen_value )
54 );
55 }
56
57 /**
58 * Get persisted wizard choices.
59 *
60 * @return array
61 */
62 function wpbc_setup_wizard__get_booking_wizard_data() {
63
64 $wizard_data = get_bk_option( 'booking_wizard_data' );
65
66 return ( empty( $wizard_data ) || ( ! is_array( $wizard_data ) ) ) ? array() : $wizard_data;
67 }
68
69 /**
70 * Get selected booking type from wizard history or current options.
71 *
72 * @param array|null $wizard_data Wizard data.
73 *
74 * @return string
75 */
76 function wpbc_setup_wizard__get_selected_booking_type( $wizard_data = null ) {
77
78 if ( null === $wizard_data ) {
79 $wizard_data = wpbc_setup_wizard__get_booking_wizard_data();
80 }
81
82 if (
83 isset( $wizard_data['save_and_continue__bookings_types']['wpbc_swp_booking_types'] )
84 && ( ! empty( $wizard_data['save_and_continue__bookings_types']['wpbc_swp_booking_types'] ) )
85 ) {
86 return (string) $wizard_data['save_and_continue__bookings_types']['wpbc_swp_booking_types'];
87 }
88
89 if ( 'On' === get_bk_option( 'booking_range_selection_time_is_active' ) ) {
90 return 'changeover_multi_dates_bookings';
91 }
92
93 if ( 'single' === get_bk_option( 'booking_type_of_day_selections' ) ) {
94 return 'time_slots_appointments';
95 }
96
97 return 'full_days_bookings';
98 }
99
100 /**
101 * Get selected appointment mode from wizard history or current options.
102 *
103 * @param array|null $wizard_data Wizard data.
104 *
105 * @return string
106 */
107 function wpbc_setup_wizard__get_selected_appointments_type( $wizard_data = null ) {
108
109 if ( null === $wizard_data ) {
110 $wizard_data = wpbc_setup_wizard__get_booking_wizard_data();
111 }
112
113 // Appointment mode always uses the Service duration and start-time flow.
114 if ( 'appointment' === wpbc_setup_wizard__get_selected_mode_id( $wizard_data ) ) {
115 return 'durationtime';
116 }
117
118 if (
119 isset( $wizard_data['save_and_continue__bookings_types']['wpbc_swp_booking_appointments_type'] )
120 && ( ! empty( $wizard_data['save_and_continue__bookings_types']['wpbc_swp_booking_appointments_type'] ) )
121 ) {
122 return (string) $wizard_data['save_and_continue__bookings_types']['wpbc_swp_booking_appointments_type'];
123 }
124
125 return 'rangetime';
126 }
127
128 /**
129 * Check whether Booking Modes can resolve the current owner safely.
130 *
131 * Setup progress can be inspected while active plugins are still loading.
132 * Before `init`, WordPress has not guaranteed that current-user pluggable
133 * functions or just-in-time translation loading are ready. Mode registries
134 * must therefore remain untouched until this boundary is reached.
135 *
136 * @return bool True when current-user and translation-dependent mode APIs can
137 * be used safely.
138 */
139 function wpbc_setup_wizard__is_booking_modes_runtime_ready() {
140
141 return did_action( 'init' ) && function_exists( 'wp_get_current_user' );
142 }
143
144 /**
145 * Get the presentation mode selected in wizard history or owner settings.
146 *
147 * Missing historical mode data is expected on upgrades. In that case the
148 * owner-scoped Booking Modes setting remains authoritative, with Classic as a
149 * compatibility fallback when the feature module is unavailable.
150 *
151 * @param array|null $wizard_data Wizard data.
152 *
153 * @return string Allowed Booking Modes identifier.
154 */
155 function wpbc_setup_wizard__get_selected_mode_id( $wizard_data = null ) {
156
157 if ( null === $wizard_data ) {
158 $wizard_data = wpbc_setup_wizard__get_booking_wizard_data();
159 }
160
161 $saved_mode_id = isset( $wizard_data['save_and_continue__bookings_types']['wpbc_swp_booking_mode'] )
162 ? sanitize_key( (string) $wizard_data['save_and_continue__bookings_types']['wpbc_swp_booking_mode'] )
163 : '';
164 $standard_mode_ids = array( 'classic', 'appointment', 'rental' );
165
166 if ( ! wpbc_setup_wizard__is_booking_modes_runtime_ready() ) {
167 return in_array( $saved_mode_id, $standard_mode_ids, true ) ? $saved_mode_id : 'classic';
168 }
169
170 if ( function_exists( 'wpbc_booking_modes_get_allowed_mode_ids' ) ) {
171 $allowed_mode_ids = wpbc_booking_modes_get_allowed_mode_ids();
172 if ( in_array( $saved_mode_id, $allowed_mode_ids, true ) ) {
173 return $saved_mode_id;
174 }
175
176 return wpbc_booking_modes_get_selected_mode_id();
177 }
178
179 return 'classic';
180 }
181
182 /**
183 * Convert selected booking type to a setup profile.
184 *
185 * @param array|null $wizard_data Wizard data.
186 *
187 * @return string
188 */
189 function wpbc_setup_wizard__get_selected_profile( $wizard_data = null ) {
190
191 $booking_type = wpbc_setup_wizard__get_selected_booking_type( $wizard_data );
192
193 if ( 'time_slots_appointments' === $booking_type ) {
194 return ( 'durationtime' === wpbc_setup_wizard__get_selected_appointments_type( $wizard_data ) ) ? 'duration_appointments' : 'time_slots';
195 }
196
197 if ( 'changeover_multi_dates_bookings' === $booking_type ) {
198 return 'changeover';
199 }
200
201 return 'full_day';
202 }
203
204 /**
205 * Check whether profile uses booking times.
206 *
207 * @param string|null $profile Profile.
208 *
209 * @return bool
210 */
211 function wpbc_setup_wizard__is_time_based_profile( $profile = null ) {
212
213 $profile = ( null === $profile ) ? wpbc_setup_wizard__get_selected_profile() : $profile;
214
215 return in_array( $profile, array( 'time_slots', 'duration_appointments' ), true );
216 }
217
218 /**
219 * Check whether profile uses changeover mode.
220 *
221 * @param string|null $profile Profile.
222 *
223 * @return bool
224 */
225 function wpbc_setup_wizard__is_changeover_profile( $profile = null ) {
226
227 $profile = ( null === $profile ) ? wpbc_setup_wizard__get_selected_profile() : $profile;
228
229 return ( 'changeover' === $profile );
230 }
231
232 /**
233 * Get the internal setup wizard route before profile-specific external pages.
234 *
235 * @return array
236 */
237 function wpbc_setup_wizard__get_intro_route() {
238
239 $route = array( 'welcome' );
240 if ( ! wpbc_is_this_demo() ) {
241 $route[] = 'general_info';
242 }
243 $route[] = 'date_time_formats';
244 $route[] = 'bookings_types';
245
246 return $route;
247 }
248
249 /**
250 * Get profile-specific setup route matrix after "Booking Type".
251 *
252 * Steps 1-4 stay inside the setup wizard. These compatibility routes remain
253 * behavior-based; `wpbc_setup_wizard__get_profile_route()` can replace their
254 * order for a presentation mode while reusing the same canonical controllers.
255 *
256 * @return array
257 */
258 function wpbc_setup_wizard__get_profile_route_map() {
259
260 $full_day_route = array(
261 'form_structure',
262 'date_selection',
263 'date_availability',
264 'color_theme',
265 'wizard_publish',
266 'get_started',
267 );
268
269 $changeover_route = array(
270 'form_structure',
271 'date_selection',
272 'changeover_days',
273 'date_availability',
274 'color_theme',
275 'wizard_publish',
276 'get_started',
277 );
278
279 $time_based_route = array(
280 'form_structure',
281 'date_selection',
282 'working_time',
283 'time_slots_availability',
284 'color_theme',
285 'wizard_publish',
286 'get_started',
287 );
288
289 return array(
290 'full_day' => $full_day_route,
291 'changeover' => $changeover_route,
292 'time_slots' => $time_based_route,
293 'duration_appointments' => $time_based_route,
294 );
295 }
296
297 /**
298 * Get profile-specific setup route after "Booking Type".
299 *
300 * @param string|null $profile Profile.
301 * @param bool|null $is_bfb_enabled Deprecated. Kept for backward-compatible calls.
302 *
303 * @return array
304 */
305 function wpbc_setup_wizard__get_profile_route( $profile = null, $is_bfb_enabled = null ) {
306
307 $profile = ( null === $profile ) ? wpbc_setup_wizard__get_selected_profile() : $profile;
308 $mode_id = wpbc_setup_wizard__get_selected_mode_id();
309 $route_map = wpbc_setup_wizard__get_profile_route_map();
310
311 if ( 'appointment' === $mode_id ) {
312 $route = array(
313 'service_provider',
314 'working_time',
315 'date_availability',
316 'time_slots_availability',
317 'form_structure',
318 'color_theme',
319 'wizard_publish',
320 'get_started',
321 );
322 } else {
323 $route = isset( $route_map[ $profile ] ) ? $route_map[ $profile ] : $route_map['full_day'];
324 }
325
326 /**
327 * Filter the mode-aware Setup Wizard route after Step 4.
328 *
329 * @param array $route Ordered external setup steps.
330 * @param string $mode_id Active Booking Modes identifier.
331 * @param string $profile Booking behavior profile.
332 */
333 $route = apply_filters( 'wpbc_setup_wizard_profile_route', $route, $mode_id, $profile );
334
335 return is_array( $route ) ? array_values( $route ) : array();
336 }
337
338 /**
339 * Get the next setup step from the current profile route.
340 *
341 * @param string $current_step Current step name.
342 *
343 * @return string
344 */
345 function wpbc_setup_wizard__get_next_step_name( $current_step ) {
346
347 $route = array_merge( wpbc_setup_wizard__get_intro_route(), wpbc_setup_wizard__get_profile_route() );
348
349 $current_step_index = array_search( $current_step, $route, true );
350
351 if ( false === $current_step_index ) {
352 return '';
353 }
354
355 return isset( $route[ $current_step_index + 1 ] ) ? $route[ $current_step_index + 1 ] : '';
356 }
357
358 /**
359 * Check whether the step is rendered inside the setup wizard page.
360 *
361 * @param string $step_name Step name.
362 *
363 * @return bool
364 */
365 function wpbc_setup_wizard__is_internal_step( $step_name ) {
366
367 return in_array( $step_name, array( 'welcome', 'general_info', 'date_time_formats', 'bookings_types' ), true );
368 }
369
370 /**
371 * Detect the external setup step from the current WPBC admin page request.
372 *
373 * @return string
374 */
375 function wpbc_setup_wizard__detect_step_from_admin_request() {
376
377 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
378 $page = isset( $_GET['page'] ) ? sanitize_key( wp_unslash( $_GET['page'] ) ) : '';
379 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
380 $tab = isset( $_GET['tab'] ) ? sanitize_key( wp_unslash( $_GET['tab'] ) ) : '';
381 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
382 $scroll_to_section = isset( $_GET['scroll_to_section'] ) ? sanitize_key( wp_unslash( $_GET['scroll_to_section'] ) ) : '';
383 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
384 $wpbc_ag_open = isset( $_GET['wpbc_ag_open'] ) ? sanitize_key( wp_unslash( $_GET['wpbc_ag_open'] ) ) : '';
385 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
386 $wpbc_calendar_section = isset( $_GET['wpbc_calendar_section'] ) ? sanitize_key( wp_unslash( $_GET['wpbc_calendar_section'] ) ) : '';
387 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
388 $wpbc_setup_step = isset( $_GET['wpbc_setup_step'] ) ? sanitize_key( wp_unslash( $_GET['wpbc_setup_step'] ) ) : '';
389
390 if ( '' !== $wpbc_setup_step ) {
391 return $wpbc_setup_step;
392 }
393
394 if ( 'wpbc-settings' === $page ) {
395 if ( 'builder_booking_form' === $tab ) {
396 return 'form_structure';
397 }
398
399 if ( 'form' === $tab ) {
400 return 'form_structure';
401 }
402
403 if ( 'calendar_settings' === $tab ) {
404 if ( 'changeover_times' === $wpbc_calendar_section ) {
405 return 'changeover_days';
406 }
407 return 'date_selection';
408 }
409
410 if ( 'wpbc_general_settings_calendar_tab' === $scroll_to_section ) {
411 return 'date_selection';
412 }
413
414 if ( 'themes' === $tab ) {
415 return 'color_theme';
416 }
417 }
418
419 if ( 'wpbc-availability' === $page ) {
420 if ( 'time_slots_availability' === $tab ) {
421 return 'time_slots_availability';
422 }
423
424 if ( 'working_time' === $wpbc_ag_open ) {
425 return 'working_time';
426 }
427
428 return 'date_availability';
429 }
430
431 if ( 'wpbc-resources' === $page ) {
432 return 'wizard_publish';
433 }
434
435 if ( 'wpbc-services' === $page && 'appointment_services' === $tab ) {
436 return 'service_provider';
437 }
438
439 return '';
440 }
441
442 /**
443 * Detect an external setup step from an admin URL.
444 *
445 * @param string $url URL.
446 *
447 * @return string
448 */
449 function wpbc_setup_wizard__detect_step_from_admin_url( $url ) {
450
451 if ( empty( $url ) ) {
452 return '';
453 }
454
455 $url_parts = wp_parse_url( $url );
456 if ( empty( $url_parts['query'] ) ) {
457 return '';
458 }
459
460 $query_args = array();
461 wp_parse_str( $url_parts['query'], $query_args );
462
463 $page = isset( $query_args['page'] ) ? sanitize_key( $query_args['page'] ) : '';
464 $tab = isset( $query_args['tab'] ) ? sanitize_key( $query_args['tab'] ) : '';
465 $scroll_to_section = isset( $query_args['scroll_to_section'] ) ? sanitize_key( $query_args['scroll_to_section'] ) : '';
466 $wpbc_ag_open = isset( $query_args['wpbc_ag_open'] ) ? sanitize_key( $query_args['wpbc_ag_open'] ) : '';
467 $wpbc_calendar_section = isset( $query_args['wpbc_calendar_section'] ) ? sanitize_key( $query_args['wpbc_calendar_section'] ) : '';
468 $wpbc_setup_step = isset( $query_args['wpbc_setup_step'] ) ? sanitize_key( $query_args['wpbc_setup_step'] ) : '';
469
470 if ( '' !== $wpbc_setup_step ) {
471 return $wpbc_setup_step;
472 }
473
474 if ( 'wpbc-settings' === $page ) {
475 if ( 'builder_booking_form' === $tab ) {
476 return 'form_structure';
477 }
478
479 if ( 'form' === $tab ) {
480 return 'form_structure';
481 }
482
483 if ( 'calendar_settings' === $tab ) {
484 if ( 'changeover_times' === $wpbc_calendar_section ) {
485 return 'changeover_days';
486 }
487 return 'date_selection';
488 }
489
490 if ( 'wpbc_general_settings_calendar_tab' === $scroll_to_section ) {
491 return 'date_selection';
492 }
493
494 if ( 'themes' === $tab ) {
495 return 'color_theme';
496 }
497 }
498
499 if ( 'wpbc-availability' === $page ) {
500 if ( 'time_slots_availability' === $tab ) {
501 return 'time_slots_availability';
502 }
503
504 if ( 'working_time' === $wpbc_ag_open ) {
505 return 'working_time';
506 }
507
508 return 'date_availability';
509 }
510
511 if ( 'wpbc-resources' === $page ) {
512 return 'wizard_publish';
513 }
514
515 if ( 'wpbc-services' === $page && 'appointment_services' === $tab ) {
516 return 'service_provider';
517 }
518
519 return '';
520 }
521
522 /**
523 * Get human-readable setup step title.
524 *
525 * @param string $step_name Step name.
526 *
527 * @return string
528 */
529 function wpbc_setup_wizard__get_step_title( $step_name ) {
530 $mode_id = wpbc_setup_wizard__get_selected_mode_id();
531
532 if ( 'wizard_publish' === $step_name && 'appointment' === $mode_id ) {
533 return __( 'Appointment Page', 'booking' );
534 }
535
536 if ( 'wizard_publish' === $step_name && 'rental' === $mode_id ) {
537 return __( 'Rental Page', 'booking' );
538 }
539
540 if ( 'date_availability' === $step_name && 'appointment' === $mode_id ) {
541 return __( 'Days Off', 'booking' );
542 }
543
544 $step_titles = array(
545 'welcome' => __( 'Welcome', 'booking' ),
546 'general_info' => __( 'General Info', 'booking' ),
547 'date_time_formats' => __( 'Dates and Times', 'booking' ),
548 'bookings_types' => __( 'Booking Type', 'booking' ),
549 'service_provider' => __( 'Service and Provider', 'booking' ),
550 'date_selection' => __( 'Date Selection', 'booking' ),
551 'changeover_days' => __( 'Changeover Days', 'booking' ),
552 'working_time' => __( 'Working Time', 'booking' ),
553 'time_slots_availability' => __( 'Time Slots', 'booking' ),
554 'date_availability' => __( 'Date Availability', 'booking' ),
555 'form_structure' => __( 'Booking Form', 'booking' ),
556 'color_theme' => __( 'Color Theme', 'booking' ),
557 'wizard_publish' => __( 'Publish', 'booking' ),
558 'get_started' => __( 'Get Started', 'booking' ),
559 );
560
561 return isset( $step_titles[ $step_name ] ) ? $step_titles[ $step_name ] : $step_name;
562 }
563
564 /**
565 * Get action-oriented setup step heading shown in the floating setup bar.
566 *
567 * @param string $step_name Step name.
568 *
569 * @return string
570 */
571 function wpbc_setup_wizard__get_step_heading( $step_name ) {
572 $mode_id = wpbc_setup_wizard__get_selected_mode_id();
573
574 if ( 'wizard_publish' === $step_name && 'appointment' === $mode_id ) {
575 return __( 'Review and test the Appointment page', 'booking' );
576 }
577
578 if ( 'wizard_publish' === $step_name && 'rental' === $mode_id ) {
579 return __( 'Review and test the Rental page', 'booking' );
580 }
581
582 if ( 'date_availability' === $step_name && 'appointment' === $mode_id ) {
583 return __( 'Block Provider days off and exceptions', 'booking' );
584 }
585
586 $step_headings = array(
587 'welcome' => __( 'Start the initial setup', 'booking' ),
588 'general_info' => __( 'Confirm your business details', 'booking' ),
589 'date_time_formats' => __( 'Choose date and time formats', 'booking' ),
590 'bookings_types' => __( 'Choose the main booking workflow', 'booking' ),
591 'service_provider' => __( 'Review your first Service and Provider', 'booking' ),
592 'form_structure' => __( 'Select and save the booking form template', 'booking' ),
593 'date_selection' => __( 'Set how visitors select dates', 'booking' ),
594 'changeover_days' => __( 'Configure changeover days', 'booking' ),
595 'working_time' => __( 'Define when bookings can start and end', 'booking' ),
596 'time_slots_availability' => __( 'Review availability for appointment slots', 'booking' ),
597 'date_availability' => __( 'Set date availability rules', 'booking' ),
598 'color_theme' => __( 'Choose the calendar appearance', 'booking' ),
599 'wizard_publish' => __( 'Publish the booking form on your site', 'booking' ),
600 'get_started' => __( 'Complete setup and manage bookings', 'booking' ),
601 );
602
603 return isset( $step_headings[ $step_name ] ) ? $step_headings[ $step_name ] : wpbc_setup_wizard__get_step_title( $step_name );
604 }
605
606 /**
607 * Get setup step guidance shown in the floating setup bar.
608 *
609 * @param string $step_name Step name.
610 *
611 * @return string
612 */
613 function wpbc_setup_wizard__get_step_description( $step_name ) {
614 $mode_id = wpbc_setup_wizard__get_selected_mode_id();
615
616 if ( 'wizard_publish' === $step_name && 'appointment' === $mode_id ) {
617 return __( 'Open a published Appointment page to test the Service, Provider, date, and time flow. If no page is listed, run Appointment QuickStart or publish the shortcode first.', 'booking' );
618 }
619
620 if ( 'wizard_publish' === $step_name && 'rental' === $mode_id ) {
621 return __( 'Open a published Property booking page to test the Rental flow. If no page is listed, run Rental QuickStart or publish the booking form first.', 'booking' );
622 }
623
624 if ( 'date_availability' === $step_name && 'appointment' === $mode_id ) {
625 return __( 'Use the canonical Days Availability calendar to block holidays, leave, and other Provider-specific exceptions.', 'booking' );
626 }
627
628 $step_descriptions = array(
629 'welcome' => __( 'Begin the guided setup. You can leave the wizard at any time and continue later from the setup bar.', 'booking' ),
630 'general_info' => __( 'Review the business name, contact details, and basic information used while preparing the booking configuration.', 'booking' ),
631 'date_time_formats' => __( 'Pick the date and time display formats that should be used in the admin panel, booking form, and customer-facing messages.', 'booking' ),
632 'bookings_types' => __( 'Select whether bookings use full days, appointment time slots, or changeover-style date ranges. This choice controls the next configuration steps.', 'booking' ),
633 'service_provider' => __( 'QuickStart created a starter Service assigned to an existing booking resource. Review its duration, buffers, price, Booking Form, and Provider assignment.', 'booking' ),
634 'form_structure' => __( 'Open the form template chooser, select the template that matches your booking type, and save the Booking Form page before continuing.', 'booking' ),
635 'date_selection' => __( 'Choose whether visitors can select one day, multiple individual days, or an available date range in the calendar. Save the General Settings page after changing this option.', 'booking' ),
636 'changeover_days' => __( 'Enable and review check-in/check-out changeover days, including diagonal or vertical markings and related changeover options.', 'booking' ),
637 'working_time' => __( 'Set the daily working hours that should be available for bookings. These hours are used as the base schedule for time-based availability.', 'booking' ),
638 'time_slots_availability' => __( 'Check the generated appointment slots and adjust any slot-specific availability rules before choosing the calendar appearance.', 'booking' ),
639 'date_availability' => __( 'Set which weekdays, dates, booking windows, and buffer rules should be available or unavailable for visitors.', 'booking' ),
640 'color_theme' => __( 'Choose the calendar skin and visual style so the booking form fits your site before you publish it.', 'booking' ),
641 'wizard_publish' => __( 'Use the Publish buttons for each booking resource to insert the booking form into an existing page, create a new page, or copy the shortcode.', 'booking' ),
642 'get_started' => __( 'Finish the setup wizard. After this, the setup bar will disappear and you can start managing bookings normally.', 'booking' ),
643 );
644
645 return isset( $step_descriptions[ $step_name ] ) ? $step_descriptions[ $step_name ] : '';
646 }
647
648 /**
649 * Get external setup step UI integration matrix.
650 *
651 * Each entry describes how the floating setup bar should connect a wizard step
652 * to an existing WPBC admin page: what to open, what to scroll/highlight, which
653 * form/save control belongs to this step, and which JS events mean the external
654 * page has saved successfully.
655 *
656 * @return array
657 */
658 function wpbc_setup_wizard__get_step_ui_matrix() {
659 $publish_step_ui = wpbc_setup_wizard__get_publish_step_ui();
660 $time_slots_step_ui = array(
661 'save_behavior' => 'link_only',
662 'target_selector' => '.wpbc_admin_page__tab__time_slots_availability, .wpbc_ts_page',
663 'scroll_selector' => '.wpbc_admin_page__tab__time_slots_availability:visible, .wpbc_ts_page:visible',
664 'highlight_disabled' => '1',
665 );
666 $date_availability_step_ui = array(
667 'save_behavior' => 'link_only',
668 'target_selector' => '.wpbc_admin_page__tab__availability, .wpbc_ajx_availability_container',
669 'scroll_selector' => '.wpbc_ajx_availability_container:visible, .wpbc_admin_page__tab__availability:visible',
670 'highlight_disabled' => '1',
671 );
672
673 if ( 'rental' === wpbc_setup_wizard__get_selected_mode_id() ) {
674 $date_availability_step_ui = array(
675 'save_behavior' => 'manual_save_required',
676 'target_selector' => '.wpbc_admin_page__tab__general_availability, [data-wpbc-ag-settings-form="1"]',
677 'scroll_selector' => '[data-wpbc-ag-settings-form="1"]:visible, .wpbc_admin_page__tab__general_availability:visible',
678 'highlight_disabled' => '1',
679 'form_selector' => '[data-wpbc-ag-settings-form="1"]',
680 'save_selector' => '[data-wpbc-ag-save="1"]',
681 'save_ajax_action' => 'WPBC_AJX_AVAILABILITY_GENERAL_SAVE',
682 'save_events' => 'wpbc:availability-general:settings-saved,wpbc:setup-wizard:step-saved',
683 );
684 }
685
686 if ( 'appointment' === wpbc_setup_wizard__get_selected_mode_id() ) {
687 $form_builder_url = wpbc_get_settings_url() . '&tab=builder_booking_form';
688 $form_builder_url = add_query_arg(
689 array(
690 'wpbc_bfb_panel' => 'add_fields',
691 'wpbc_bfb_group' => 'fields-times',
692 'wpbc_bfb_focus' => 'weekday_starttime',
693 ),
694 $form_builder_url
695 );
696
697 $time_slots_step_ui['secondary_action_url'] = wpbc_setup_wizard__add_setup_context_to_url( $form_builder_url, 'time_slots_availability' );
698 $time_slots_step_ui['secondary_action_label'] = __( 'Adjust slot-specific availability rules', 'booking' );
699 }
700
701 return array(
702 'service_provider' => array(
703 'save_behavior' => 'link_only',
704 'target_selector' => '.wpbc_appointment_services_page',
705 'scroll_selector' => '.wpbc_appointment_services_page:visible',
706 'highlight_disabled' => '1',
707 ),
708 'form_structure' => array(
709 'save_behavior' => 'manual_save_required',
710 'target_selector' => '.wpbc_admin_page__tab__builder_booking_form, #wpbc_form_field_free',
711 'scroll_selector' => '.wpbc_bfb_popup_modal__forms_loading_section:visible, #wpbc_form_field_free:visible, .wpbc_admin_page__tab__builder_booking_form:visible',
712 'highlight_disabled' => '1',
713 'form_selector' => '#wpbc_form_field_free',
714 'save_selector' => '#wpbc_form_field_free .wpbc_submit_button_trigger, #wpbc_form_field_free .wpbc_submit_button, [onclick*="wpbc_bfb__ajax_save_current_form"], [data-wpbc-bfb-save-source]',
715 'save_events' => 'wpbc:bfb:form:ajax_saved,wpbc:bfb:form:saved,wpbc:bfb:save:done,wpbc:bfb:ajax_saved,wpbc:setup-wizard:step-saved',
716 ),
717 'date_selection' => array(
718 'save_behavior' => 'manual_save_required',
719 'target_selector' => '.wpbc_admin_page__tab__calendar_settings, [data-wpbc-calendar-page="1"], [data-group="settings-calendar-days-selection"], [data-wpbc-calendar-settings-form="1"]',
720 'scroll_selector' => '[data-group="settings-calendar-days-selection"]:visible, .wpbc_calendar__inspector_settings:visible, [data-wpbc-calendar-settings-form="1"]:visible',
721 'highlight_selector' => '[data-group="settings-calendar-days-selection"]:visible, .wpbc_calendar__inspector_settings:visible, [data-wpbc-calendar-settings-form="1"]:visible',
722 'form_selector' => '[data-wpbc-calendar-settings-form="1"], #wpbc_general_settings_form',
723 'save_selector' => '[data-wpbc-calendar-save="1"], #wpbc_general_settings_form .wpbc_submit_button_trigger, #wpbc_general_settings_form .wpbc_submit_button',
724 'save_ajax_action' => 'WPBC_AJX_SETTINGS_CALENDAR_SAVE',
725 'save_events' => 'wpbc:setup-wizard:step-saved',
726 ),
727 'changeover_days' => array(
728 'save_behavior' => 'manual_save_required',
729 'target_selector' => '[data-group="settings-calendar-time"], [data-wpbc-calendar-changeover-settings="1"], [name="booking_range_selection_time_is_active"], [data-wpbc-calendar-page="1"]',
730 'scroll_selector' => '[data-group="settings-calendar-time"]:visible, [data-wpbc-calendar-changeover-settings="1"]:visible, [name="booking_range_selection_time_is_active"]:visible, [data-wpbc-calendar-page="1"]:visible',
731 'highlight_selector' => '[data-group="settings-calendar-time"]:visible, [data-wpbc-calendar-changeover-settings="1"]:visible, [name="booking_range_selection_time_is_active"]:visible',
732 'form_selector' => '[data-wpbc-calendar-settings-form="1"]',
733 'save_selector' => '[data-wpbc-calendar-save="1"]',
734 'save_ajax_action' => 'WPBC_AJX_SETTINGS_CALENDAR_SAVE',
735 'save_events' => 'wpbc:setup-wizard:step-saved',
736 ),
737 'working_time' => array(
738 'save_behavior' => 'manual_save_required',
739 'target_selector' => '[data-group="general-availability-working-time"], .wpbc_ag_working_time_block, .wpbc_admin_page__tab__general_availability',
740 'scroll_selector' => '[data-group="general-availability-working-time"]:visible, .wpbc_ag_working_time_block:visible, [data-wpbc-ag-settings-form="1"]:visible',
741 'highlight_selector' => '[data-group="general-availability-working-time"]:visible, .wpbc_ag_working_time_block:visible',
742 'form_selector' => '[data-wpbc-ag-settings-form="1"]',
743 'save_selector' => '[data-wpbc-ag-save="1"]',
744 'save_ajax_action' => 'WPBC_AJX_AVAILABILITY_GENERAL_SAVE',
745 'save_events' => 'wpbc:availability-general:settings-saved,wpbc:setup-wizard:step-saved',
746 'open_action' => 'availability_section',
747 ),
748 'time_slots_availability' => $time_slots_step_ui,
749 'date_availability' => $date_availability_step_ui,
750 'color_theme' => array(
751 'save_behavior' => 'manual_save_required',
752 'target_selector' => '.wpbc_admin_page__tab__themes, [data-wpbc-theme-page="1"]',
753 'scroll_selector' => '.wpbc_theme__inspector_settings:visible, [data-wpbc-theme-settings-form="1"]:visible, .wpbc_theme_rightbar_panels:visible',
754 'highlight_selector' => '.wpbc_theme__inspector_settings:visible, [data-wpbc-theme-settings-form="1"]:visible, .wpbc_theme_rightbar_panels:visible',
755 'form_selector' => '[data-wpbc-theme-settings-form="1"]',
756 'save_selector' => '[data-wpbc-theme-save="1"]',
757 'save_ajax_action' => 'WPBC_AJX_SETTINGS_THEMES_SAVE',
758 'save_events' => 'wpbc:setup-wizard:step-saved',
759 ),
760 'wizard_publish' => $publish_step_ui,
761 'get_started' => array(
762 'save_behavior' => 'complete',
763 'target_selector' => '.wpbc_admin_page',
764 'scroll_selector' => '.wpbc_admin_page:visible',
765 'highlight_disabled' => '1',
766 ),
767 );
768 }
769
770 /**
771 * Determine whether Setup Wizard publishing should use the shared Resource catalog.
772 *
773 * The compatibility resolver remains authoritative so an older paid edition,
774 * the temporary legacy preference, or the support rollback constant keeps the
775 * wizard connected to the released legacy Resources renderer.
776 *
777 * @return bool True when the new Resource catalog is the effective renderer.
778 */
779 function wpbc_setup_wizard__uses_new_resources_catalog() {
780 return function_exists( 'wpbc_booking_resources_catalog_should_use_new_renderer' )
781 && wpbc_booking_resources_catalog_should_use_new_renderer();
782 }
783
784 /**
785 * Get the renderer-aware Setup Wizard publishing integration.
786 *
787 * The new catalog is opened through its domain action event after the initial
788 * AJAX response. The legacy selectors are intentionally retained unchanged
789 * while the compatibility renderer remains available in Booking Calendar 11.6.
790 *
791 * @param bool|null $use_new_catalog Optional renderer override for deterministic tests. Null uses the effective compatibility resolver.
792 *
793 * @return array<string,string> Setup bar selector and action configuration.
794 */
795 function wpbc_setup_wizard__get_publish_step_ui( $use_new_catalog = null ) {
796 if ( null === $use_new_catalog ) {
797 $use_new_catalog = wpbc_setup_wizard__uses_new_resources_catalog();
798 }
799
800 if ( true === $use_new_catalog ) {
801 return array(
802 'save_behavior' => 'link_only',
803 'target_selector' => '#wpbc_catalog_booking_resources',
804 'scroll_selector' => '#wpbc_catalog_booking_resources:visible',
805 'highlight_disabled' => '1',
806 'open_action' => 'catalog_publish',
807 );
808 }
809
810 return array(
811 'save_behavior' => 'link_only',
812 'target_selector' => '.ui_group__publish_btn, .wpbc_resource_field__publish, .wpbc_resource_publish, .wpbc_publish_resources, [data-wpbc-resource-publish]',
813 'scroll_selector' => '.ui_group__publish_btn:visible, .wpbc_resource_field__publish:visible, .wpbc_resource_publish:visible, .wpbc_publish_resources:visible, [data-wpbc-resource-publish]:visible',
814 'highlight_selector' => '.ui_group__publish_btn:visible, .wpbc_resource_field__publish:visible, .wpbc_resource_publish:visible, .wpbc_publish_resources:visible, [data-wpbc-resource-publish]:visible',
815 'highlight_all' => '1',
816 'open_action' => 'publish_area',
817 );
818 }
819
820 /**
821 * Get one UI integration value from the external setup step matrix.
822 *
823 * @param string $step_name Step name.
824 * @param string $key Matrix key.
825 *
826 * @return string
827 */
828 function wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, $key ) {
829
830 $ui_matrix = wpbc_setup_wizard__get_step_ui_matrix();
831
832 return ( isset( $ui_matrix[ $step_name ][ $key ] ) ) ? (string) $ui_matrix[ $step_name ][ $key ] : '';
833 }
834
835 /**
836 * Get save behavior for external setup step.
837 *
838 * @param string $step_name Step name.
839 *
840 * @return string
841 */
842 function wpbc_setup_wizard__get_step_save_behavior( $step_name ) {
843
844 $save_behavior = wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'save_behavior' );
845
846 return ( ! empty( $save_behavior ) ) ? $save_behavior : 'link_only';
847 }
848
849 /**
850 * Get DOM selector to highlight/scroll on external setup pages.
851 *
852 * @param string $step_name Step name.
853 *
854 * @return string
855 */
856 function wpbc_setup_wizard__get_step_target_selector( $step_name ) {
857
858 return wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'target_selector' );
859 }
860
861 /**
862 * Get DOM selector to scroll on external setup pages.
863 *
864 * @param string $step_name Step name.
865 *
866 * @return string
867 */
868 function wpbc_setup_wizard__get_step_scroll_selector( $step_name ) {
869
870 $scroll_selector = wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'scroll_selector' );
871
872 return ( ! empty( $scroll_selector ) ) ? $scroll_selector : wpbc_setup_wizard__get_step_target_selector( $step_name );
873 }
874
875 /**
876 * Get DOM selector to highlight on external setup pages.
877 *
878 * @param string $step_name Step name.
879 *
880 * @return string
881 */
882 function wpbc_setup_wizard__get_step_highlight_selector( $step_name ) {
883
884 if ( wpbc_setup_wizard__is_step_highlight_disabled( $step_name ) ) {
885 return '';
886 }
887
888 $highlight_selector = wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'highlight_selector' );
889
890 return ( ! empty( $highlight_selector ) ) ? $highlight_selector : wpbc_setup_wizard__get_step_target_selector( $step_name );
891 }
892
893 /**
894 * Check if external setup page highlighting is disabled for a step.
895 *
896 * @param string $step_name Step name.
897 *
898 * @return bool
899 */
900 function wpbc_setup_wizard__is_step_highlight_disabled( $step_name ) {
901
902 return '1' === wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'highlight_disabled' );
903 }
904
905 /**
906 * Get page open action for external setup pages.
907 *
908 * @param string $step_name Step name.
909 *
910 * @return string
911 */
912 function wpbc_setup_wizard__get_step_open_action( $step_name ) {
913
914 return wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'open_action' );
915 }
916
917 /**
918 * Get browser events that confirm an external setup page save.
919 *
920 * @param string $step_name Step name.
921 *
922 * @return string
923 */
924 function wpbc_setup_wizard__get_step_save_events( $step_name ) {
925
926 return wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'save_events' );
927 }
928
929 /**
930 * Get AJAX action name used by the existing page save button related to the setup step.
931 *
932 * @param string $step_name Step name.
933 *
934 * @return string
935 */
936 function wpbc_setup_wizard__get_step_save_ajax_action( $step_name ) {
937
938 return wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'save_ajax_action' );
939 }
940
941 /**
942 * Get DOM selector for the existing page form related to the setup step.
943 *
944 * @param string $step_name Step name.
945 *
946 * @return string
947 */
948 function wpbc_setup_wizard__get_step_form_selector( $step_name ) {
949
950 return wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'form_selector' );
951 }
952
953 /**
954 * Get selector for the existing page save button related to the setup step.
955 *
956 * @param string $step_name Step name.
957 *
958 * @return string
959 */
960 function wpbc_setup_wizard__get_step_save_selector( $step_name ) {
961
962 return wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'save_selector' );
963 }
964
965 /**
966 * Add setup guide context to a target URL.
967 *
968 * @param string $url URL.
969 * @param string $step_name Step name.
970 *
971 * @return string
972 */
973 function wpbc_setup_wizard__add_setup_context_to_url( $url, $step_name ) {
974
975 return add_query_arg(
976 array(
977 'wpbc_setup' => '1',
978 'wpbc_setup_step' => $step_name,
979 ),
980 $url
981 );
982 }
983
984 /**
985 * Get the Form Builder template search key for the selected booking type.
986 *
987 * @return string
988 */
989 function wpbc_setup_wizard__get_bfb_template_search_key() {
990
991 $booking_wizard_data_arr = get_bk_option( 'booking_wizard_data' );
992 if (
993 empty( $booking_wizard_data_arr )
994 || ! is_array( $booking_wizard_data_arr )
995 || empty( $booking_wizard_data_arr['save_and_continue__bookings_types'] )
996 || ! is_array( $booking_wizard_data_arr['save_and_continue__bookings_types'] )
997 ) {
998 return '';
999 }
1000
1001 $booking_type = isset( $booking_wizard_data_arr['save_and_continue__bookings_types']['wpbc_swp_booking_types'] )
1002 ? $booking_wizard_data_arr['save_and_continue__bookings_types']['wpbc_swp_booking_types']
1003 : '';
1004 $url_sep = defined( 'WPBC_BFB_TEMPLATE_SEARCH_OR_SEPARATOR_URL' ) ? WPBC_BFB_TEMPLATE_SEARCH_OR_SEPARATOR_URL : '^';
1005
1006 if ( 'full_days_bookings' === $booking_type ) {
1007 return 'full-days' . $url_sep . 'dates_form';
1008 }
1009
1010 if ( 'time_slots_appointments' === $booking_type ) {
1011 if ( 'rangetime' === wpbc_setup_wizard__get_selected_appointments_type( $booking_wizard_data_arr ) ) {
1012 return 'times' . $url_sep . 'time slots';
1013 }
1014
1015 return 'appointments' . $url_sep . 'service';
1016 }
1017
1018 if ( 'changeover_multi_dates_bookings' === $booking_type ) {
1019 return 'changeover' . $url_sep . 'triangles';
1020 }
1021
1022 return '';
1023 }
1024
1025 /**
1026 * Get the existing admin page URL that should handle a setup step.
1027 *
1028 * @param string $step_name Step name.
1029 *
1030 * @return string
1031 */
1032 function wpbc_setup_wizard__get_step_target_url( $step_name ) {
1033 $target_fragment = '';
1034
1035 if ( wpbc_setup_wizard__is_internal_step( $step_name ) ) {
1036 return add_query_arg( 'current_step', $step_name, wpbc_get_setup_wizard_page_url() );
1037 }
1038
1039 switch ( $step_name ) {
1040 case 'service_provider':
1041 $url = function_exists( 'wpbc_booking_modes_get_canonical_page_url' )
1042 ? wpbc_booking_modes_get_canonical_page_url( 'wpbc-services__appointment_services' )
1043 : admin_url( 'admin.php?page=wpbc-services&tab=appointment_services' );
1044 break;
1045
1046 case 'date_selection':
1047 $url = function_exists( 'wpbc_get_settings_calendar_url' )
1048 ? wpbc_get_settings_calendar_url()
1049 : wpbc_get_settings_url() . '&tab=calendar_settings';
1050 $url = add_query_arg( 'wpbc_calendar_section', 'days_selection', $url );
1051 break;
1052
1053 case 'changeover_days':
1054 $url = function_exists( 'wpbc_get_settings_calendar_url' )
1055 ? wpbc_get_settings_calendar_url()
1056 : wpbc_get_settings_url() . '&tab=calendar_settings';
1057 $url = add_query_arg( 'wpbc_calendar_section', 'changeover_times', $url );
1058 break;
1059
1060 case 'working_time':
1061 $url = function_exists( 'wpbc_get_general_availability_url' )
1062 ? wpbc_get_general_availability_url()
1063 : admin_url( 'admin.php?page=wpbc-availability&tab=general_availability' );
1064 $url = add_query_arg( 'wpbc_ag_open', 'working_time', $url );
1065 break;
1066
1067 case 'time_slots_availability':
1068 $url = function_exists( 'wpbc_get_time_slots_availability_url' )
1069 ? wpbc_get_time_slots_availability_url()
1070 : admin_url( 'admin.php?page=wpbc-availability&tab=time_slots_availability' );
1071 break;
1072
1073 case 'date_availability':
1074 if ( 'rental' === wpbc_setup_wizard__get_selected_mode_id() ) {
1075 $url = function_exists( 'wpbc_get_general_availability_url' )
1076 ? wpbc_get_general_availability_url()
1077 : admin_url( 'admin.php?page=wpbc-availability&tab=general_availability' );
1078 break;
1079 }
1080
1081 $canonical_url = function_exists( 'wpbc_booking_modes_get_canonical_page_url' )
1082 ? wpbc_booking_modes_get_canonical_page_url( 'wpbc-availability__availability' )
1083 : '';
1084 $url = ! empty( $canonical_url ) ? $canonical_url : admin_url( 'admin.php?page=wpbc-availability&tab=availability' );
1085 break;
1086
1087 case 'form_structure':
1088 $url = wpbc_get_settings_url() . '&tab=builder_booking_form';
1089
1090 $template_search_key = wpbc_setup_wizard__get_bfb_template_search_key();
1091 if ( ! empty( $template_search_key ) ) {
1092 $url = add_query_arg( 'auto_open_template', $template_search_key, $url );
1093 }
1094 break;
1095
1096 case 'color_theme':
1097 $url = function_exists( 'wpbc_get_settings_themes_url' )
1098 ? wpbc_get_settings_themes_url()
1099 : wpbc_get_settings_url() . '&tab=themes';
1100 break;
1101
1102 case 'wizard_publish':
1103 $url = function_exists( 'wpbc_booking_modes_get_canonical_page_url' )
1104 ? wpbc_booking_modes_get_canonical_page_url( 'wpbc-resources__resources' )
1105 : '';
1106 if ( empty( $url ) ) {
1107 $url = wpbc_get_resources_url();
1108 }
1109 $url = add_query_arg( 'tab', 'resources', $url );
1110 $target_fragment = wpbc_setup_wizard__uses_new_resources_catalog()
1111 ? 'wpbc_catalog_booking_resources'
1112 : 'wpbc_booking_resource_table';
1113 break;
1114
1115 case 'get_started':
1116 $url = wpbc_get_bookings_url() . '&tab=vm_booking_listing';
1117 break;
1118
1119 default:
1120 $url = wpbc_get_setup_wizard_page_url();
1121 break;
1122 }
1123
1124 $url = wpbc_setup_wizard__add_setup_context_to_url( $url, $step_name );
1125
1126 if ( ! empty( $target_fragment ) ) {
1127 $url .= '#' . $target_fragment;
1128 }
1129
1130 return $url;
1131 }
1132
1133 /**
1134 * Get URL that completes an external setup step and redirects to the next mapped step.
1135 *
1136 * @param string $step_name Step name.
1137 *
1138 * @return string
1139 */
1140 function wpbc_setup_wizard__get_step_continue_url( $step_name ) {
1141
1142 if ( wpbc_setup_wizard__is_internal_step( $step_name ) ) {
1143 return wpbc_setup_wizard__get_step_target_url( $step_name );
1144 }
1145
1146 return add_query_arg(
1147 array(
1148 'wpbc_setup_wizard' => 'continue',
1149 'wpbc_setup_step' => $step_name,
1150 'wpbc_setup_from_page_step' => $step_name,
1151 '_wpnonce' => wp_create_nonce( 'wpbc_settings_url_nonce' ),
1152 ),
1153 wpbc_get_setup_wizard_page_url()
1154 );
1155 }
1156
1157 /**
1158 * Get setup step metadata for routing and UI.
1159 *
1160 * @param string $step_name Step name.
1161 *
1162 * @return array
1163 */
1164 function wpbc_setup_wizard__get_step_route_metadata( $step_name ) {
1165
1166 return array(
1167 'is_external' => ! wpbc_setup_wizard__is_internal_step( $step_name ),
1168 'target_url' => wpbc_setup_wizard__get_step_target_url( $step_name ),
1169 'title' => wpbc_setup_wizard__get_step_title( $step_name ),
1170 'heading' => wpbc_setup_wizard__get_step_heading( $step_name ),
1171 'description' => wpbc_setup_wizard__get_step_description( $step_name ),
1172 'save_behavior' => wpbc_setup_wizard__get_step_save_behavior( $step_name ),
1173 'target_selector' => wpbc_setup_wizard__get_step_target_selector( $step_name ),
1174 'scroll_selector' => wpbc_setup_wizard__get_step_scroll_selector( $step_name ),
1175 'highlight_selector' => wpbc_setup_wizard__get_step_highlight_selector( $step_name ),
1176 'highlight_disabled' => wpbc_setup_wizard__is_step_highlight_disabled( $step_name ) ? '1' : '0',
1177 'form_selector' => wpbc_setup_wizard__get_step_form_selector( $step_name ),
1178 'save_selector' => wpbc_setup_wizard__get_step_save_selector( $step_name ),
1179 'save_ajax_action' => wpbc_setup_wizard__get_step_save_ajax_action( $step_name ),
1180 'save_events' => wpbc_setup_wizard__get_step_save_events( $step_name ),
1181 'open_action' => wpbc_setup_wizard__get_step_open_action( $step_name ),
1182 'secondary_action_url' => wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'secondary_action_url' ),
1183 'secondary_action_label' => wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'secondary_action_label' ),
1184 );
1185 }
1186
1187 /**
1188 * Get first step after "Booking Type" for current profile.
1189 *
1190 * @return string
1191 */
1192 function wpbc_setup_wizard__get_first_profile_step() {
1193
1194 $route = wpbc_setup_wizard__get_profile_route();
1195
1196 return ( empty( $route ) ) ? 'color_theme' : $route[0];
1197 }
1198