PluginProbe
Booking Calendar / 11.8
Booking Calendar v11.8
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 10.11.3 10.11.4 All 201 releases
booking / includes / page-setup / setup_profiles.php

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

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