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

1,185 lines 42.8 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 if ( 'appointment' === $mode_id ) {
299 $route = array(
300 'service_provider',
301 'working_time',
302 'date_availability',
303 'time_slots_availability',
304 'form_structure',
305 'color_theme',
306 'wizard_publish',
307 'get_started',
308 );
309 } else {
310 $route = isset( $route_map[ $profile ] ) ? $route_map[ $profile ] : $route_map['full_day'];
311 }
312
313 /**
314 * Filter the mode-aware Setup Wizard route after Step 4.
315 *
316 * @param array $route Ordered external setup steps.
317 * @param string $mode_id Active Booking Modes identifier.
318 * @param string $profile Booking behavior profile.
319 */
320 $route = apply_filters( 'wpbc_setup_wizard_profile_route', $route, $mode_id, $profile );
321
322 return is_array( $route ) ? array_values( $route ) : array();
323 }
324
325 /**
326 * Get the next setup step from the current profile route.
327 *
328 * @param string $current_step Current step name.
329 *
330 * @return string
331 */
332 function wpbc_setup_wizard__get_next_step_name( $current_step ) {
333
334 $route = array_merge( wpbc_setup_wizard__get_intro_route(), wpbc_setup_wizard__get_profile_route() );
335
336 $current_step_index = array_search( $current_step, $route, true );
337
338 if ( false === $current_step_index ) {
339 return '';
340 }
341
342 return isset( $route[ $current_step_index + 1 ] ) ? $route[ $current_step_index + 1 ] : '';
343 }
344
345 /**
346 * Check whether the step is rendered inside the setup wizard page.
347 *
348 * @param string $step_name Step name.
349 *
350 * @return bool
351 */
352 function wpbc_setup_wizard__is_internal_step( $step_name ) {
353
354 return in_array( $step_name, array( 'welcome', 'general_info', 'date_time_formats', 'bookings_types' ), true );
355 }
356
357 /**
358 * Detect the external setup step from the current WPBC admin page request.
359 *
360 * @return string
361 */
362 function wpbc_setup_wizard__detect_step_from_admin_request() {
363
364 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
365 $page = isset( $_GET['page'] ) ? sanitize_key( wp_unslash( $_GET['page'] ) ) : '';
366 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
367 $tab = isset( $_GET['tab'] ) ? sanitize_key( wp_unslash( $_GET['tab'] ) ) : '';
368 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
369 $scroll_to_section = isset( $_GET['scroll_to_section'] ) ? sanitize_key( wp_unslash( $_GET['scroll_to_section'] ) ) : '';
370 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
371 $wpbc_ag_open = isset( $_GET['wpbc_ag_open'] ) ? sanitize_key( wp_unslash( $_GET['wpbc_ag_open'] ) ) : '';
372 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
373 $wpbc_calendar_section = isset( $_GET['wpbc_calendar_section'] ) ? sanitize_key( wp_unslash( $_GET['wpbc_calendar_section'] ) ) : '';
374 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
375 $wpbc_setup_step = isset( $_GET['wpbc_setup_step'] ) ? sanitize_key( wp_unslash( $_GET['wpbc_setup_step'] ) ) : '';
376
377 if ( '' !== $wpbc_setup_step ) {
378 return $wpbc_setup_step;
379 }
380
381 if ( 'wpbc-settings' === $page ) {
382 if ( 'builder_booking_form' === $tab ) {
383 return 'form_structure';
384 }
385
386 if ( 'form' === $tab ) {
387 return 'form_structure';
388 }
389
390 if ( 'calendar_settings' === $tab ) {
391 if ( 'changeover_times' === $wpbc_calendar_section ) {
392 return 'changeover_days';
393 }
394 return 'date_selection';
395 }
396
397 if ( 'wpbc_general_settings_calendar_tab' === $scroll_to_section ) {
398 return 'date_selection';
399 }
400
401 if ( 'themes' === $tab ) {
402 return 'color_theme';
403 }
404 }
405
406 if ( 'wpbc-availability' === $page ) {
407 if ( 'time_slots_availability' === $tab ) {
408 return 'time_slots_availability';
409 }
410
411 if ( 'working_time' === $wpbc_ag_open ) {
412 return 'working_time';
413 }
414
415 return 'date_availability';
416 }
417
418 if ( 'wpbc-resources' === $page ) {
419 return 'wizard_publish';
420 }
421
422 if ( 'wpbc-services' === $page && 'appointment_services' === $tab ) {
423 return 'service_provider';
424 }
425
426 return '';
427 }
428
429 /**
430 * Detect an external setup step from an admin URL.
431 *
432 * @param string $url URL.
433 *
434 * @return string
435 */
436 function wpbc_setup_wizard__detect_step_from_admin_url( $url ) {
437
438 if ( empty( $url ) ) {
439 return '';
440 }
441
442 $url_parts = wp_parse_url( $url );
443 if ( empty( $url_parts['query'] ) ) {
444 return '';
445 }
446
447 $query_args = array();
448 wp_parse_str( $url_parts['query'], $query_args );
449
450 $page = isset( $query_args['page'] ) ? sanitize_key( $query_args['page'] ) : '';
451 $tab = isset( $query_args['tab'] ) ? sanitize_key( $query_args['tab'] ) : '';
452 $scroll_to_section = isset( $query_args['scroll_to_section'] ) ? sanitize_key( $query_args['scroll_to_section'] ) : '';
453 $wpbc_ag_open = isset( $query_args['wpbc_ag_open'] ) ? sanitize_key( $query_args['wpbc_ag_open'] ) : '';
454 $wpbc_calendar_section = isset( $query_args['wpbc_calendar_section'] ) ? sanitize_key( $query_args['wpbc_calendar_section'] ) : '';
455 $wpbc_setup_step = isset( $query_args['wpbc_setup_step'] ) ? sanitize_key( $query_args['wpbc_setup_step'] ) : '';
456
457 if ( '' !== $wpbc_setup_step ) {
458 return $wpbc_setup_step;
459 }
460
461 if ( 'wpbc-settings' === $page ) {
462 if ( 'builder_booking_form' === $tab ) {
463 return 'form_structure';
464 }
465
466 if ( 'form' === $tab ) {
467 return 'form_structure';
468 }
469
470 if ( 'calendar_settings' === $tab ) {
471 if ( 'changeover_times' === $wpbc_calendar_section ) {
472 return 'changeover_days';
473 }
474 return 'date_selection';
475 }
476
477 if ( 'wpbc_general_settings_calendar_tab' === $scroll_to_section ) {
478 return 'date_selection';
479 }
480
481 if ( 'themes' === $tab ) {
482 return 'color_theme';
483 }
484 }
485
486 if ( 'wpbc-availability' === $page ) {
487 if ( 'time_slots_availability' === $tab ) {
488 return 'time_slots_availability';
489 }
490
491 if ( 'working_time' === $wpbc_ag_open ) {
492 return 'working_time';
493 }
494
495 return 'date_availability';
496 }
497
498 if ( 'wpbc-resources' === $page ) {
499 return 'wizard_publish';
500 }
501
502 if ( 'wpbc-services' === $page && 'appointment_services' === $tab ) {
503 return 'service_provider';
504 }
505
506 return '';
507 }
508
509 /**
510 * Get human-readable setup step title.
511 *
512 * @param string $step_name Step name.
513 *
514 * @return string
515 */
516 function wpbc_setup_wizard__get_step_title( $step_name ) {
517 $mode_id = wpbc_setup_wizard__get_selected_mode_id();
518
519 if ( 'wizard_publish' === $step_name && 'appointment' === $mode_id ) {
520 return __( 'Appointment Page', 'booking' );
521 }
522
523 if ( 'wizard_publish' === $step_name && 'rental' === $mode_id ) {
524 return __( 'Rental Page', 'booking' );
525 }
526
527 if ( 'date_availability' === $step_name && 'appointment' === $mode_id ) {
528 return __( 'Days Off', 'booking' );
529 }
530
531 $step_titles = array(
532 'welcome' => __( 'Welcome', 'booking' ),
533 'general_info' => __( 'General Info', 'booking' ),
534 'date_time_formats' => __( 'Dates and Times', 'booking' ),
535 'bookings_types' => __( 'Booking Type', 'booking' ),
536 'service_provider' => __( 'Service and Provider', 'booking' ),
537 'date_selection' => __( 'Date Selection', 'booking' ),
538 'changeover_days' => __( 'Changeover Days', 'booking' ),
539 'working_time' => __( 'Working Time', 'booking' ),
540 'time_slots_availability' => __( 'Time Slots', 'booking' ),
541 'date_availability' => __( 'Date Availability', 'booking' ),
542 'form_structure' => __( 'Booking Form', 'booking' ),
543 'color_theme' => __( 'Color Theme', 'booking' ),
544 'wizard_publish' => __( 'Publish', 'booking' ),
545 'get_started' => __( 'Get Started', 'booking' ),
546 );
547
548 return isset( $step_titles[ $step_name ] ) ? $step_titles[ $step_name ] : $step_name;
549 }
550
551 /**
552 * Get action-oriented setup step heading shown in the floating setup bar.
553 *
554 * @param string $step_name Step name.
555 *
556 * @return string
557 */
558 function wpbc_setup_wizard__get_step_heading( $step_name ) {
559 $mode_id = wpbc_setup_wizard__get_selected_mode_id();
560
561 if ( 'wizard_publish' === $step_name && 'appointment' === $mode_id ) {
562 return __( 'Review and test the Appointment page', 'booking' );
563 }
564
565 if ( 'wizard_publish' === $step_name && 'rental' === $mode_id ) {
566 return __( 'Review and test the Rental page', 'booking' );
567 }
568
569 if ( 'date_availability' === $step_name && 'appointment' === $mode_id ) {
570 return __( 'Block Provider days off and exceptions', 'booking' );
571 }
572
573 $step_headings = array(
574 'welcome' => __( 'Start the initial setup', 'booking' ),
575 'general_info' => __( 'Confirm your business details', 'booking' ),
576 'date_time_formats' => __( 'Choose date and time formats', 'booking' ),
577 'bookings_types' => __( 'Choose the main booking workflow', 'booking' ),
578 'service_provider' => __( 'Review your first Service and Provider', 'booking' ),
579 'form_structure' => __( 'Select and save the booking form template', 'booking' ),
580 'date_selection' => __( 'Set how visitors select dates', 'booking' ),
581 'changeover_days' => __( 'Configure changeover days', 'booking' ),
582 'working_time' => __( 'Define when bookings can start and end', 'booking' ),
583 'time_slots_availability' => __( 'Review availability for appointment slots', 'booking' ),
584 'date_availability' => __( 'Set date availability rules', 'booking' ),
585 'color_theme' => __( 'Choose the calendar appearance', 'booking' ),
586 'wizard_publish' => __( 'Publish the booking form on your site', 'booking' ),
587 'get_started' => __( 'Complete setup and manage bookings', 'booking' ),
588 );
589
590 return isset( $step_headings[ $step_name ] ) ? $step_headings[ $step_name ] : wpbc_setup_wizard__get_step_title( $step_name );
591 }
592
593 /**
594 * Get setup step guidance shown in the floating setup bar.
595 *
596 * @param string $step_name Step name.
597 *
598 * @return string
599 */
600 function wpbc_setup_wizard__get_step_description( $step_name ) {
601 $mode_id = wpbc_setup_wizard__get_selected_mode_id();
602
603 if ( 'wizard_publish' === $step_name && 'appointment' === $mode_id ) {
604 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' );
605 }
606
607 if ( 'wizard_publish' === $step_name && 'rental' === $mode_id ) {
608 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' );
609 }
610
611 if ( 'date_availability' === $step_name && 'appointment' === $mode_id ) {
612 return __( 'Use the canonical Days Availability calendar to block holidays, leave, and other Provider-specific exceptions.', 'booking' );
613 }
614
615 $step_descriptions = array(
616 'welcome' => __( 'Begin the guided setup. You can leave the wizard at any time and continue later from the setup bar.', 'booking' ),
617 'general_info' => __( 'Review the business name, contact details, and basic information used while preparing the booking configuration.', 'booking' ),
618 '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' ),
619 'bookings_types' => __( 'Select whether bookings use full days, appointment time slots, or changeover-style date ranges. This choice controls the next configuration steps.', 'booking' ),
620 'service_provider' => __( 'QuickStart created a starter Service assigned to an existing booking resource. Review its duration, buffers, price, Booking Form, and Provider assignment.', 'booking' ),
621 'form_structure' => __( 'Open the form template chooser, select the template that matches your booking type, and save the Booking Form page before continuing.', 'booking' ),
622 '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' ),
623 'changeover_days' => __( 'Enable and review check-in/check-out changeover days, including diagonal or vertical markings and related changeover options.', 'booking' ),
624 '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' ),
625 'time_slots_availability' => __( 'Check the generated appointment slots and adjust any slot-specific availability rules before choosing the calendar appearance.', 'booking' ),
626 'date_availability' => __( 'Set which weekdays, dates, booking windows, and buffer rules should be available or unavailable for visitors.', 'booking' ),
627 'color_theme' => __( 'Choose the calendar skin and visual style so the booking form fits your site before you publish it.', 'booking' ),
628 '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' ),
629 'get_started' => __( 'Finish the setup wizard. After this, the setup bar will disappear and you can start managing bookings normally.', 'booking' ),
630 );
631
632 return isset( $step_descriptions[ $step_name ] ) ? $step_descriptions[ $step_name ] : '';
633 }
634
635 /**
636 * Get external setup step UI integration matrix.
637 *
638 * Each entry describes how the floating setup bar should connect a wizard step
639 * to an existing WPBC admin page: what to open, what to scroll/highlight, which
640 * form/save control belongs to this step, and which JS events mean the external
641 * page has saved successfully.
642 *
643 * @return array
644 */
645 function wpbc_setup_wizard__get_step_ui_matrix() {
646 $publish_step_ui = wpbc_setup_wizard__get_publish_step_ui();
647 $time_slots_step_ui = array(
648 'save_behavior' => 'link_only',
649 'target_selector' => '.wpbc_admin_page__tab__time_slots_availability, .wpbc_ts_page',
650 'scroll_selector' => '.wpbc_admin_page__tab__time_slots_availability:visible, .wpbc_ts_page:visible',
651 'highlight_disabled' => '1',
652 );
653 $date_availability_step_ui = array(
654 'save_behavior' => 'link_only',
655 'target_selector' => '.wpbc_admin_page__tab__availability, .wpbc_ajx_availability_container',
656 'scroll_selector' => '.wpbc_ajx_availability_container:visible, .wpbc_admin_page__tab__availability:visible',
657 'highlight_disabled' => '1',
658 );
659
660 if ( 'rental' === wpbc_setup_wizard__get_selected_mode_id() ) {
661 $date_availability_step_ui = array(
662 'save_behavior' => 'manual_save_required',
663 'target_selector' => '.wpbc_admin_page__tab__general_availability, [data-wpbc-ag-settings-form="1"]',
664 'scroll_selector' => '[data-wpbc-ag-settings-form="1"]:visible, .wpbc_admin_page__tab__general_availability:visible',
665 'highlight_disabled' => '1',
666 'form_selector' => '[data-wpbc-ag-settings-form="1"]',
667 'save_selector' => '[data-wpbc-ag-save="1"]',
668 'save_ajax_action' => 'WPBC_AJX_AVAILABILITY_GENERAL_SAVE',
669 'save_events' => 'wpbc:availability-general:settings-saved,wpbc:setup-wizard:step-saved',
670 );
671 }
672
673 if ( 'appointment' === wpbc_setup_wizard__get_selected_mode_id() ) {
674 $form_builder_url = wpbc_get_settings_url() . '&tab=builder_booking_form';
675 $form_builder_url = add_query_arg(
676 array(
677 'wpbc_bfb_panel' => 'add_fields',
678 'wpbc_bfb_group' => 'fields-times',
679 'wpbc_bfb_focus' => 'weekday_starttime',
680 ),
681 $form_builder_url
682 );
683
684 $time_slots_step_ui['secondary_action_url'] = wpbc_setup_wizard__add_setup_context_to_url( $form_builder_url, 'time_slots_availability' );
685 $time_slots_step_ui['secondary_action_label'] = __( 'Adjust slot-specific availability rules', 'booking' );
686 }
687
688 return array(
689 'service_provider' => array(
690 'save_behavior' => 'link_only',
691 'target_selector' => '.wpbc_appointment_services_page',
692 'scroll_selector' => '.wpbc_appointment_services_page:visible',
693 'highlight_disabled' => '1',
694 ),
695 'form_structure' => array(
696 'save_behavior' => 'manual_save_required',
697 'target_selector' => '.wpbc_admin_page__tab__builder_booking_form, #wpbc_form_field_free',
698 'scroll_selector' => '.wpbc_bfb_popup_modal__forms_loading_section:visible, #wpbc_form_field_free:visible, .wpbc_admin_page__tab__builder_booking_form:visible',
699 'highlight_disabled' => '1',
700 'form_selector' => '#wpbc_form_field_free',
701 '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]',
702 'save_events' => 'wpbc:bfb:form:ajax_saved,wpbc:bfb:form:saved,wpbc:bfb:save:done,wpbc:bfb:ajax_saved,wpbc:setup-wizard:step-saved',
703 ),
704 'date_selection' => array(
705 'save_behavior' => 'manual_save_required',
706 '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"]',
707 'scroll_selector' => '[data-group="settings-calendar-days-selection"]:visible, .wpbc_calendar__inspector_settings:visible, [data-wpbc-calendar-settings-form="1"]:visible',
708 'highlight_selector' => '[data-group="settings-calendar-days-selection"]:visible, .wpbc_calendar__inspector_settings:visible, [data-wpbc-calendar-settings-form="1"]:visible',
709 'form_selector' => '[data-wpbc-calendar-settings-form="1"], #wpbc_general_settings_form',
710 'save_selector' => '[data-wpbc-calendar-save="1"], #wpbc_general_settings_form .wpbc_submit_button_trigger, #wpbc_general_settings_form .wpbc_submit_button',
711 'save_ajax_action' => 'WPBC_AJX_SETTINGS_CALENDAR_SAVE',
712 'save_events' => 'wpbc:setup-wizard:step-saved',
713 ),
714 'changeover_days' => array(
715 'save_behavior' => 'manual_save_required',
716 '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"]',
717 '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',
718 'highlight_selector' => '[data-group="settings-calendar-time"]:visible, [data-wpbc-calendar-changeover-settings="1"]:visible, [name="booking_range_selection_time_is_active"]:visible',
719 'form_selector' => '[data-wpbc-calendar-settings-form="1"]',
720 'save_selector' => '[data-wpbc-calendar-save="1"]',
721 'save_ajax_action' => 'WPBC_AJX_SETTINGS_CALENDAR_SAVE',
722 'save_events' => 'wpbc:setup-wizard:step-saved',
723 ),
724 'working_time' => array(
725 'save_behavior' => 'manual_save_required',
726 'target_selector' => '[data-group="general-availability-working-time"], .wpbc_ag_working_time_block, .wpbc_admin_page__tab__general_availability',
727 'scroll_selector' => '[data-group="general-availability-working-time"]:visible, .wpbc_ag_working_time_block:visible, [data-wpbc-ag-settings-form="1"]:visible',
728 'highlight_selector' => '[data-group="general-availability-working-time"]:visible, .wpbc_ag_working_time_block:visible',
729 'form_selector' => '[data-wpbc-ag-settings-form="1"]',
730 'save_selector' => '[data-wpbc-ag-save="1"]',
731 'save_ajax_action' => 'WPBC_AJX_AVAILABILITY_GENERAL_SAVE',
732 'save_events' => 'wpbc:availability-general:settings-saved,wpbc:setup-wizard:step-saved',
733 'open_action' => 'availability_section',
734 ),
735 'time_slots_availability' => $time_slots_step_ui,
736 'date_availability' => $date_availability_step_ui,
737 'color_theme' => array(
738 'save_behavior' => 'manual_save_required',
739 'target_selector' => '.wpbc_admin_page__tab__themes, [data-wpbc-theme-page="1"]',
740 'scroll_selector' => '.wpbc_theme__inspector_settings:visible, [data-wpbc-theme-settings-form="1"]:visible, .wpbc_theme_rightbar_panels:visible',
741 'highlight_selector' => '.wpbc_theme__inspector_settings:visible, [data-wpbc-theme-settings-form="1"]:visible, .wpbc_theme_rightbar_panels:visible',
742 'form_selector' => '[data-wpbc-theme-settings-form="1"]',
743 'save_selector' => '[data-wpbc-theme-save="1"]',
744 'save_ajax_action' => 'WPBC_AJX_SETTINGS_THEMES_SAVE',
745 'save_events' => 'wpbc:setup-wizard:step-saved',
746 ),
747 'wizard_publish' => $publish_step_ui,
748 'get_started' => array(
749 'save_behavior' => 'complete',
750 'target_selector' => '.wpbc_admin_page',
751 'scroll_selector' => '.wpbc_admin_page:visible',
752 'highlight_disabled' => '1',
753 ),
754 );
755 }
756
757 /**
758 * Determine whether Setup Wizard publishing should use the shared Resource catalog.
759 *
760 * The compatibility resolver remains authoritative so an older paid edition,
761 * the temporary legacy preference, or the support rollback constant keeps the
762 * wizard connected to the released legacy Resources renderer.
763 *
764 * @return bool True when the new Resource catalog is the effective renderer.
765 */
766 function wpbc_setup_wizard__uses_new_resources_catalog() {
767 return function_exists( 'wpbc_booking_resources_catalog_should_use_new_renderer' )
768 && wpbc_booking_resources_catalog_should_use_new_renderer();
769 }
770
771 /**
772 * Get the renderer-aware Setup Wizard publishing integration.
773 *
774 * The new catalog is opened through its domain action event after the initial
775 * AJAX response. The legacy selectors are intentionally retained unchanged
776 * while the compatibility renderer remains available in Booking Calendar 11.6.
777 *
778 * @param bool|null $use_new_catalog Optional renderer override for deterministic tests. Null uses the effective compatibility resolver.
779 *
780 * @return array<string,string> Setup bar selector and action configuration.
781 */
782 function wpbc_setup_wizard__get_publish_step_ui( $use_new_catalog = null ) {
783 if ( null === $use_new_catalog ) {
784 $use_new_catalog = wpbc_setup_wizard__uses_new_resources_catalog();
785 }
786
787 if ( true === $use_new_catalog ) {
788 return array(
789 'save_behavior' => 'link_only',
790 'target_selector' => '#wpbc_catalog_booking_resources',
791 'scroll_selector' => '#wpbc_catalog_booking_resources:visible',
792 'highlight_disabled' => '1',
793 'open_action' => 'catalog_publish',
794 );
795 }
796
797 return array(
798 'save_behavior' => 'link_only',
799 'target_selector' => '.ui_group__publish_btn, .wpbc_resource_field__publish, .wpbc_resource_publish, .wpbc_publish_resources, [data-wpbc-resource-publish]',
800 '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',
801 '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',
802 'highlight_all' => '1',
803 'open_action' => 'publish_area',
804 );
805 }
806
807 /**
808 * Get one UI integration value from the external setup step matrix.
809 *
810 * @param string $step_name Step name.
811 * @param string $key Matrix key.
812 *
813 * @return string
814 */
815 function wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, $key ) {
816
817 $ui_matrix = wpbc_setup_wizard__get_step_ui_matrix();
818
819 return ( isset( $ui_matrix[ $step_name ][ $key ] ) ) ? (string) $ui_matrix[ $step_name ][ $key ] : '';
820 }
821
822 /**
823 * Get save behavior for external setup step.
824 *
825 * @param string $step_name Step name.
826 *
827 * @return string
828 */
829 function wpbc_setup_wizard__get_step_save_behavior( $step_name ) {
830
831 $save_behavior = wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'save_behavior' );
832
833 return ( ! empty( $save_behavior ) ) ? $save_behavior : 'link_only';
834 }
835
836 /**
837 * Get DOM selector to highlight/scroll on external setup pages.
838 *
839 * @param string $step_name Step name.
840 *
841 * @return string
842 */
843 function wpbc_setup_wizard__get_step_target_selector( $step_name ) {
844
845 return wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'target_selector' );
846 }
847
848 /**
849 * Get DOM selector to scroll on external setup pages.
850 *
851 * @param string $step_name Step name.
852 *
853 * @return string
854 */
855 function wpbc_setup_wizard__get_step_scroll_selector( $step_name ) {
856
857 $scroll_selector = wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'scroll_selector' );
858
859 return ( ! empty( $scroll_selector ) ) ? $scroll_selector : wpbc_setup_wizard__get_step_target_selector( $step_name );
860 }
861
862 /**
863 * Get DOM selector to highlight on external setup pages.
864 *
865 * @param string $step_name Step name.
866 *
867 * @return string
868 */
869 function wpbc_setup_wizard__get_step_highlight_selector( $step_name ) {
870
871 if ( wpbc_setup_wizard__is_step_highlight_disabled( $step_name ) ) {
872 return '';
873 }
874
875 $highlight_selector = wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'highlight_selector' );
876
877 return ( ! empty( $highlight_selector ) ) ? $highlight_selector : wpbc_setup_wizard__get_step_target_selector( $step_name );
878 }
879
880 /**
881 * Check if external setup page highlighting is disabled for a step.
882 *
883 * @param string $step_name Step name.
884 *
885 * @return bool
886 */
887 function wpbc_setup_wizard__is_step_highlight_disabled( $step_name ) {
888
889 return '1' === wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'highlight_disabled' );
890 }
891
892 /**
893 * Get page open action for external setup pages.
894 *
895 * @param string $step_name Step name.
896 *
897 * @return string
898 */
899 function wpbc_setup_wizard__get_step_open_action( $step_name ) {
900
901 return wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'open_action' );
902 }
903
904 /**
905 * Get browser events that confirm an external setup page save.
906 *
907 * @param string $step_name Step name.
908 *
909 * @return string
910 */
911 function wpbc_setup_wizard__get_step_save_events( $step_name ) {
912
913 return wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'save_events' );
914 }
915
916 /**
917 * Get AJAX action name used by the existing page save button related to the setup step.
918 *
919 * @param string $step_name Step name.
920 *
921 * @return string
922 */
923 function wpbc_setup_wizard__get_step_save_ajax_action( $step_name ) {
924
925 return wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'save_ajax_action' );
926 }
927
928 /**
929 * Get DOM selector for the existing page form related to the setup step.
930 *
931 * @param string $step_name Step name.
932 *
933 * @return string
934 */
935 function wpbc_setup_wizard__get_step_form_selector( $step_name ) {
936
937 return wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'form_selector' );
938 }
939
940 /**
941 * Get selector for the existing page save button related to the setup step.
942 *
943 * @param string $step_name Step name.
944 *
945 * @return string
946 */
947 function wpbc_setup_wizard__get_step_save_selector( $step_name ) {
948
949 return wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'save_selector' );
950 }
951
952 /**
953 * Add setup guide context to a target URL.
954 *
955 * @param string $url URL.
956 * @param string $step_name Step name.
957 *
958 * @return string
959 */
960 function wpbc_setup_wizard__add_setup_context_to_url( $url, $step_name ) {
961
962 return add_query_arg(
963 array(
964 'wpbc_setup' => '1',
965 'wpbc_setup_step' => $step_name,
966 ),
967 $url
968 );
969 }
970
971 /**
972 * Get the Form Builder template search key for the selected booking type.
973 *
974 * @return string
975 */
976 function wpbc_setup_wizard__get_bfb_template_search_key() {
977
978 $booking_wizard_data_arr = get_bk_option( 'booking_wizard_data' );
979 if (
980 empty( $booking_wizard_data_arr )
981 || ! is_array( $booking_wizard_data_arr )
982 || empty( $booking_wizard_data_arr['save_and_continue__bookings_types'] )
983 || ! is_array( $booking_wizard_data_arr['save_and_continue__bookings_types'] )
984 ) {
985 return '';
986 }
987
988 $booking_type = isset( $booking_wizard_data_arr['save_and_continue__bookings_types']['wpbc_swp_booking_types'] )
989 ? $booking_wizard_data_arr['save_and_continue__bookings_types']['wpbc_swp_booking_types']
990 : '';
991 $url_sep = defined( 'WPBC_BFB_TEMPLATE_SEARCH_OR_SEPARATOR_URL' ) ? WPBC_BFB_TEMPLATE_SEARCH_OR_SEPARATOR_URL : '^';
992
993 if ( 'full_days_bookings' === $booking_type ) {
994 return 'full-days' . $url_sep . 'dates_form';
995 }
996
997 if ( 'time_slots_appointments' === $booking_type ) {
998 if ( 'rangetime' === wpbc_setup_wizard__get_selected_appointments_type( $booking_wizard_data_arr ) ) {
999 return 'times' . $url_sep . 'time slots';
1000 }
1001
1002 return 'appointments' . $url_sep . 'service';
1003 }
1004
1005 if ( 'changeover_multi_dates_bookings' === $booking_type ) {
1006 return 'changeover' . $url_sep . 'triangles';
1007 }
1008
1009 return '';
1010 }
1011
1012 /**
1013 * Get the existing admin page URL that should handle a setup step.
1014 *
1015 * @param string $step_name Step name.
1016 *
1017 * @return string
1018 */
1019 function wpbc_setup_wizard__get_step_target_url( $step_name ) {
1020 $target_fragment = '';
1021
1022 if ( wpbc_setup_wizard__is_internal_step( $step_name ) ) {
1023 return add_query_arg( 'current_step', $step_name, wpbc_get_setup_wizard_page_url() );
1024 }
1025
1026 switch ( $step_name ) {
1027 case 'service_provider':
1028 $url = function_exists( 'wpbc_booking_modes_get_canonical_page_url' )
1029 ? wpbc_booking_modes_get_canonical_page_url( 'wpbc-services__appointment_services' )
1030 : admin_url( 'admin.php?page=wpbc-services&tab=appointment_services' );
1031 break;
1032
1033 case 'date_selection':
1034 $url = function_exists( 'wpbc_get_settings_calendar_url' )
1035 ? wpbc_get_settings_calendar_url()
1036 : wpbc_get_settings_url() . '&tab=calendar_settings';
1037 $url = add_query_arg( 'wpbc_calendar_section', 'days_selection', $url );
1038 break;
1039
1040 case 'changeover_days':
1041 $url = function_exists( 'wpbc_get_settings_calendar_url' )
1042 ? wpbc_get_settings_calendar_url()
1043 : wpbc_get_settings_url() . '&tab=calendar_settings';
1044 $url = add_query_arg( 'wpbc_calendar_section', 'changeover_times', $url );
1045 break;
1046
1047 case 'working_time':
1048 $url = function_exists( 'wpbc_get_general_availability_url' )
1049 ? wpbc_get_general_availability_url()
1050 : admin_url( 'admin.php?page=wpbc-availability&tab=general_availability' );
1051 $url = add_query_arg( 'wpbc_ag_open', 'working_time', $url );
1052 break;
1053
1054 case 'time_slots_availability':
1055 $url = function_exists( 'wpbc_get_time_slots_availability_url' )
1056 ? wpbc_get_time_slots_availability_url()
1057 : admin_url( 'admin.php?page=wpbc-availability&tab=time_slots_availability' );
1058 break;
1059
1060 case 'date_availability':
1061 if ( 'rental' === wpbc_setup_wizard__get_selected_mode_id() ) {
1062 $url = function_exists( 'wpbc_get_general_availability_url' )
1063 ? wpbc_get_general_availability_url()
1064 : admin_url( 'admin.php?page=wpbc-availability&tab=general_availability' );
1065 break;
1066 }
1067
1068 $canonical_url = function_exists( 'wpbc_booking_modes_get_canonical_page_url' )
1069 ? wpbc_booking_modes_get_canonical_page_url( 'wpbc-availability__availability' )
1070 : '';
1071 $url = ! empty( $canonical_url ) ? $canonical_url : admin_url( 'admin.php?page=wpbc-availability&tab=availability' );
1072 break;
1073
1074 case 'form_structure':
1075 $url = wpbc_get_settings_url() . '&tab=builder_booking_form';
1076
1077 $template_search_key = wpbc_setup_wizard__get_bfb_template_search_key();
1078 if ( ! empty( $template_search_key ) ) {
1079 $url = add_query_arg( 'auto_open_template', $template_search_key, $url );
1080 }
1081 break;
1082
1083 case 'color_theme':
1084 $url = function_exists( 'wpbc_get_settings_themes_url' )
1085 ? wpbc_get_settings_themes_url()
1086 : wpbc_get_settings_url() . '&tab=themes';
1087 break;
1088
1089 case 'wizard_publish':
1090 $url = function_exists( 'wpbc_booking_modes_get_canonical_page_url' )
1091 ? wpbc_booking_modes_get_canonical_page_url( 'wpbc-resources__resources' )
1092 : '';
1093 if ( empty( $url ) ) {
1094 $url = wpbc_get_resources_url();
1095 }
1096 $url = add_query_arg( 'tab', 'resources', $url );
1097 $target_fragment = wpbc_setup_wizard__uses_new_resources_catalog()
1098 ? 'wpbc_catalog_booking_resources'
1099 : 'wpbc_booking_resource_table';
1100 break;
1101
1102 case 'get_started':
1103 $url = wpbc_get_bookings_url() . '&tab=vm_booking_listing';
1104 break;
1105
1106 default:
1107 $url = wpbc_get_setup_wizard_page_url();
1108 break;
1109 }
1110
1111 $url = wpbc_setup_wizard__add_setup_context_to_url( $url, $step_name );
1112
1113 if ( ! empty( $target_fragment ) ) {
1114 $url .= '#' . $target_fragment;
1115 }
1116
1117 return $url;
1118 }
1119
1120 /**
1121 * Get URL that completes an external setup step and redirects to the next mapped step.
1122 *
1123 * @param string $step_name Step name.
1124 *
1125 * @return string
1126 */
1127 function wpbc_setup_wizard__get_step_continue_url( $step_name ) {
1128
1129 if ( wpbc_setup_wizard__is_internal_step( $step_name ) ) {
1130 return wpbc_setup_wizard__get_step_target_url( $step_name );
1131 }
1132
1133 return add_query_arg(
1134 array(
1135 'wpbc_setup_wizard' => 'continue',
1136 'wpbc_setup_step' => $step_name,
1137 'wpbc_setup_from_page_step' => $step_name,
1138 '_wpnonce' => wp_create_nonce( 'wpbc_settings_url_nonce' ),
1139 ),
1140 wpbc_get_setup_wizard_page_url()
1141 );
1142 }
1143
1144 /**
1145 * Get setup step metadata for routing and UI.
1146 *
1147 * @param string $step_name Step name.
1148 *
1149 * @return array
1150 */
1151 function wpbc_setup_wizard__get_step_route_metadata( $step_name ) {
1152
1153 return array(
1154 'is_external' => ! wpbc_setup_wizard__is_internal_step( $step_name ),
1155 'target_url' => wpbc_setup_wizard__get_step_target_url( $step_name ),
1156 'title' => wpbc_setup_wizard__get_step_title( $step_name ),
1157 'heading' => wpbc_setup_wizard__get_step_heading( $step_name ),
1158 'description' => wpbc_setup_wizard__get_step_description( $step_name ),
1159 'save_behavior' => wpbc_setup_wizard__get_step_save_behavior( $step_name ),
1160 'target_selector' => wpbc_setup_wizard__get_step_target_selector( $step_name ),
1161 'scroll_selector' => wpbc_setup_wizard__get_step_scroll_selector( $step_name ),
1162 'highlight_selector' => wpbc_setup_wizard__get_step_highlight_selector( $step_name ),
1163 'highlight_disabled' => wpbc_setup_wizard__is_step_highlight_disabled( $step_name ) ? '1' : '0',
1164 'form_selector' => wpbc_setup_wizard__get_step_form_selector( $step_name ),
1165 'save_selector' => wpbc_setup_wizard__get_step_save_selector( $step_name ),
1166 'save_ajax_action' => wpbc_setup_wizard__get_step_save_ajax_action( $step_name ),
1167 'save_events' => wpbc_setup_wizard__get_step_save_events( $step_name ),
1168 'open_action' => wpbc_setup_wizard__get_step_open_action( $step_name ),
1169 'secondary_action_url' => wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'secondary_action_url' ),
1170 'secondary_action_label' => wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'secondary_action_label' ),
1171 );
1172 }
1173
1174 /**
1175 * Get first step after "Booking Type" for current profile.
1176 *
1177 * @return string
1178 */
1179 function wpbc_setup_wizard__get_first_profile_step() {
1180
1181 $route = wpbc_setup_wizard__get_profile_route();
1182
1183 return ( empty( $route ) ) ? 'color_theme' : $route[0];
1184 }
1185