PluginProbe
Booking Calendar / 11.2
Booking Calendar v11.2
11.8.3 11.8.2 11.8.1 11.8 11.7 11.6.1 11.6 11.5 11.4.3 11.4.2 11.4.1 11.4 11.3 11.2.1 11.2 11.1 11.0 10.15.7 10.15.6 10.1.3 10.10 10.10.1 10.10.2 10.11 10.11.2 All 203 releases
booking / includes / page-setup / setup_profiles.php

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

854 lines 30.1 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 server-side when it moves between internal and external setup screens.
15 *
16 * @param bool $is_full_screen Whether WPBC admin pages should open in fullscreen mode.
17 *
18 * @return bool
19 */
20 function wpbc_setup_wizard__set_full_screen_mode_for_current_user( $is_full_screen ) {
21
22 $user_id = wpbc_get_current_user_id();
23
24 if ( empty( $user_id ) ) {
25 return false;
26 }
27
28 return update_user_option(
29 $user_id,
30 'booking_custom_is_full_screen',
31 array( 'value' => $is_full_screen ? 'On' : 'Off' )
32 );
33 }
34
35 /**
36 * Get persisted wizard choices.
37 *
38 * @return array
39 */
40 function wpbc_setup_wizard__get_booking_wizard_data() {
41
42 $wizard_data = get_bk_option( 'booking_wizard_data' );
43
44 return ( empty( $wizard_data ) || ( ! is_array( $wizard_data ) ) ) ? array() : $wizard_data;
45 }
46
47 /**
48 * Get selected booking type from wizard history or current options.
49 *
50 * @param array|null $wizard_data Wizard data.
51 *
52 * @return string
53 */
54 function wpbc_setup_wizard__get_selected_booking_type( $wizard_data = null ) {
55
56 if ( null === $wizard_data ) {
57 $wizard_data = wpbc_setup_wizard__get_booking_wizard_data();
58 }
59
60 if (
61 isset( $wizard_data['save_and_continue__bookings_types']['wpbc_swp_booking_types'] )
62 && ( ! empty( $wizard_data['save_and_continue__bookings_types']['wpbc_swp_booking_types'] ) )
63 ) {
64 return (string) $wizard_data['save_and_continue__bookings_types']['wpbc_swp_booking_types'];
65 }
66
67 if ( 'On' === get_bk_option( 'booking_range_selection_time_is_active' ) ) {
68 return 'changeover_multi_dates_bookings';
69 }
70
71 if ( 'single' === get_bk_option( 'booking_type_of_day_selections' ) ) {
72 return 'time_slots_appointments';
73 }
74
75 return 'full_days_bookings';
76 }
77
78 /**
79 * Get selected appointment mode from wizard history or current options.
80 *
81 * @param array|null $wizard_data Wizard data.
82 *
83 * @return string
84 */
85 function wpbc_setup_wizard__get_selected_appointments_type( $wizard_data = null ) {
86
87 if ( null === $wizard_data ) {
88 $wizard_data = wpbc_setup_wizard__get_booking_wizard_data();
89 }
90
91 if (
92 isset( $wizard_data['save_and_continue__bookings_types']['wpbc_swp_booking_appointments_type'] )
93 && ( ! empty( $wizard_data['save_and_continue__bookings_types']['wpbc_swp_booking_appointments_type'] ) )
94 ) {
95 return (string) $wizard_data['save_and_continue__bookings_types']['wpbc_swp_booking_appointments_type'];
96 }
97
98 return 'rangetime';
99 }
100
101 /**
102 * Convert selected booking type to a setup profile.
103 *
104 * @param array|null $wizard_data Wizard data.
105 *
106 * @return string
107 */
108 function wpbc_setup_wizard__get_selected_profile( $wizard_data = null ) {
109
110 $booking_type = wpbc_setup_wizard__get_selected_booking_type( $wizard_data );
111
112 if ( 'time_slots_appointments' === $booking_type ) {
113 return ( 'durationtime' === wpbc_setup_wizard__get_selected_appointments_type( $wizard_data ) ) ? 'duration_appointments' : 'time_slots';
114 }
115
116 if ( 'changeover_multi_dates_bookings' === $booking_type ) {
117 return 'changeover';
118 }
119
120 return 'full_day';
121 }
122
123 /**
124 * Check whether profile uses booking times.
125 *
126 * @param string|null $profile Profile.
127 *
128 * @return bool
129 */
130 function wpbc_setup_wizard__is_time_based_profile( $profile = null ) {
131
132 $profile = ( null === $profile ) ? wpbc_setup_wizard__get_selected_profile() : $profile;
133
134 return in_array( $profile, array( 'time_slots', 'duration_appointments' ), true );
135 }
136
137 /**
138 * Check whether profile uses changeover mode.
139 *
140 * @param string|null $profile Profile.
141 *
142 * @return bool
143 */
144 function wpbc_setup_wizard__is_changeover_profile( $profile = null ) {
145
146 $profile = ( null === $profile ) ? wpbc_setup_wizard__get_selected_profile() : $profile;
147
148 return ( 'changeover' === $profile );
149 }
150
151 /**
152 * Get the internal setup wizard route before profile-specific external pages.
153 *
154 * @return array
155 */
156 function wpbc_setup_wizard__get_intro_route() {
157
158 $route = array( 'welcome' );
159 if ( ! wpbc_is_this_demo() ) {
160 $route[] = 'general_info';
161 }
162 $route[] = 'date_time_formats';
163 $route[] = 'bookings_types';
164
165 return $route;
166 }
167
168 /**
169 * Get profile-specific setup route matrix after "Booking Type".
170 *
171 * Steps 1-4 stay inside the setup wizard. Every route below starts with the shared Booking Form and Date Selection
172 * configuration, then branches only where the selected booking profile needs different existing WPBC admin pages.
173 *
174 * @return array
175 */
176 function wpbc_setup_wizard__get_profile_route_map() {
177
178 $full_day_route = array(
179 'form_structure',
180 'date_selection',
181 'date_availability',
182 'color_theme',
183 'wizard_publish',
184 'get_started',
185 );
186
187 $time_based_route = array(
188 'form_structure',
189 'date_selection',
190 'working_time',
191 'time_slots_availability',
192 'date_availability',
193 'color_theme',
194 'wizard_publish',
195 'get_started',
196 );
197
198 return array(
199 'full_day' => $full_day_route,
200 'changeover' => $full_day_route,
201 'time_slots' => $time_based_route,
202 'duration_appointments' => $time_based_route,
203 );
204 }
205
206 /**
207 * Get profile-specific setup route after "Booking Type".
208 *
209 * @param string|null $profile Profile.
210 * @param bool|null $is_bfb_enabled Deprecated. Kept for backward-compatible calls.
211 *
212 * @return array
213 */
214 function wpbc_setup_wizard__get_profile_route( $profile = null, $is_bfb_enabled = null ) {
215
216 $profile = ( null === $profile ) ? wpbc_setup_wizard__get_selected_profile() : $profile;
217 $route_map = wpbc_setup_wizard__get_profile_route_map();
218 $route = isset( $route_map[ $profile ] ) ? $route_map[ $profile ] : $route_map['full_day'];
219
220 if ( wpbc_is_this_demo() ) {
221 $route = array_values( array_diff( $route, array( 'wizard_publish' ) ) );
222 }
223
224 return $route;
225 }
226
227 /**
228 * Get the next setup step from the current profile route.
229 *
230 * @param string $current_step Current step name.
231 *
232 * @return string
233 */
234 function wpbc_setup_wizard__get_next_step_name( $current_step ) {
235
236 $route = array_merge( wpbc_setup_wizard__get_intro_route(), wpbc_setup_wizard__get_profile_route() );
237
238 $current_step_index = array_search( $current_step, $route, true );
239
240 if ( false === $current_step_index ) {
241 return '';
242 }
243
244 return isset( $route[ $current_step_index + 1 ] ) ? $route[ $current_step_index + 1 ] : '';
245 }
246
247 /**
248 * Check whether the step is rendered inside the setup wizard page.
249 *
250 * @param string $step_name Step name.
251 *
252 * @return bool
253 */
254 function wpbc_setup_wizard__is_internal_step( $step_name ) {
255
256 return in_array( $step_name, array( 'welcome', 'general_info', 'date_time_formats', 'bookings_types' ), true );
257 }
258
259 /**
260 * Detect the external setup step from the current WPBC admin page request.
261 *
262 * @return string
263 */
264 function wpbc_setup_wizard__detect_step_from_admin_request() {
265
266 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
267 $page = isset( $_GET['page'] ) ? sanitize_key( wp_unslash( $_GET['page'] ) ) : '';
268 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
269 $tab = isset( $_GET['tab'] ) ? sanitize_key( wp_unslash( $_GET['tab'] ) ) : '';
270 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
271 $scroll_to_section = isset( $_GET['scroll_to_section'] ) ? sanitize_key( wp_unslash( $_GET['scroll_to_section'] ) ) : '';
272 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
273 $wpbc_ag_open = isset( $_GET['wpbc_ag_open'] ) ? sanitize_key( wp_unslash( $_GET['wpbc_ag_open'] ) ) : '';
274
275 if ( 'wpbc-settings' === $page ) {
276 if ( 'builder_booking_form' === $tab ) {
277 return 'form_structure';
278 }
279
280 if ( 'form' === $tab ) {
281 return 'form_structure';
282 }
283
284 if ( 'wpbc_general_settings_calendar_tab' === $scroll_to_section ) {
285 return 'date_selection';
286 }
287
288 if ( 'color_themes' === $tab ) {
289 return 'color_theme';
290 }
291 }
292
293 if ( 'wpbc-availability' === $page ) {
294 if ( 'time_slots_availability' === $tab ) {
295 return 'time_slots_availability';
296 }
297
298 if ( 'working_time' === $wpbc_ag_open ) {
299 return 'working_time';
300 }
301
302 return 'date_availability';
303 }
304
305 if ( 'wpbc-resources' === $page ) {
306 return 'wizard_publish';
307 }
308
309 return '';
310 }
311
312 /**
313 * Detect an external setup step from an admin URL.
314 *
315 * @param string $url URL.
316 *
317 * @return string
318 */
319 function wpbc_setup_wizard__detect_step_from_admin_url( $url ) {
320
321 if ( empty( $url ) ) {
322 return '';
323 }
324
325 $url_parts = wp_parse_url( $url );
326 if ( empty( $url_parts['query'] ) ) {
327 return '';
328 }
329
330 $query_args = array();
331 wp_parse_str( $url_parts['query'], $query_args );
332
333 $page = isset( $query_args['page'] ) ? sanitize_key( $query_args['page'] ) : '';
334 $tab = isset( $query_args['tab'] ) ? sanitize_key( $query_args['tab'] ) : '';
335 $scroll_to_section = isset( $query_args['scroll_to_section'] ) ? sanitize_key( $query_args['scroll_to_section'] ) : '';
336 $wpbc_ag_open = isset( $query_args['wpbc_ag_open'] ) ? sanitize_key( $query_args['wpbc_ag_open'] ) : '';
337
338 if ( 'wpbc-settings' === $page ) {
339 if ( 'builder_booking_form' === $tab ) {
340 return 'form_structure';
341 }
342
343 if ( 'form' === $tab ) {
344 return 'form_structure';
345 }
346
347 if ( 'wpbc_general_settings_calendar_tab' === $scroll_to_section ) {
348 return 'date_selection';
349 }
350
351 if ( 'color_themes' === $tab ) {
352 return 'color_theme';
353 }
354 }
355
356 if ( 'wpbc-availability' === $page ) {
357 if ( 'time_slots_availability' === $tab ) {
358 return 'time_slots_availability';
359 }
360
361 if ( 'working_time' === $wpbc_ag_open ) {
362 return 'working_time';
363 }
364
365 return 'date_availability';
366 }
367
368 if ( 'wpbc-resources' === $page ) {
369 return 'wizard_publish';
370 }
371
372 return '';
373 }
374
375 /**
376 * Get human-readable setup step title.
377 *
378 * @param string $step_name Step name.
379 *
380 * @return string
381 */
382 function wpbc_setup_wizard__get_step_title( $step_name ) {
383
384 $step_titles = array(
385 'welcome' => __( 'Welcome', 'booking' ),
386 'general_info' => __( 'General Info', 'booking' ),
387 'date_time_formats' => __( 'Dates and Times', 'booking' ),
388 'bookings_types' => __( 'Booking Type', 'booking' ),
389 'date_selection' => __( 'Date Selection', 'booking' ),
390 'working_time' => __( 'Working Time', 'booking' ),
391 'time_slots_availability' => __( 'Time Slots', 'booking' ),
392 'date_availability' => __( 'Date Availability', 'booking' ),
393 'form_structure' => __( 'Booking Form', 'booking' ),
394 'color_theme' => __( 'Color Theme', 'booking' ),
395 'wizard_publish' => __( 'Publish', 'booking' ),
396 'get_started' => __( 'Get Started', 'booking' ),
397 );
398
399 return isset( $step_titles[ $step_name ] ) ? $step_titles[ $step_name ] : $step_name;
400 }
401
402 /**
403 * Get action-oriented setup step heading shown in the floating setup bar.
404 *
405 * @param string $step_name Step name.
406 *
407 * @return string
408 */
409 function wpbc_setup_wizard__get_step_heading( $step_name ) {
410
411 $step_headings = array(
412 'welcome' => __( 'Start the initial setup', 'booking' ),
413 'general_info' => __( 'Confirm your business details', 'booking' ),
414 'date_time_formats' => __( 'Choose date and time formats', 'booking' ),
415 'bookings_types' => __( 'Choose the main booking workflow', 'booking' ),
416 'form_structure' => __( 'Select and save the booking form template', 'booking' ),
417 'date_selection' => __( 'Set how visitors select dates', 'booking' ),
418 'working_time' => __( 'Define when bookings can start and end', 'booking' ),
419 'time_slots_availability' => __( 'Review availability for appointment slots', 'booking' ),
420 'date_availability' => __( 'Set date availability rules', 'booking' ),
421 'color_theme' => __( 'Choose the calendar appearance', 'booking' ),
422 'wizard_publish' => __( 'Publish the booking form on your site', 'booking' ),
423 'get_started' => __( 'Complete setup and manage bookings', 'booking' ),
424 );
425
426 return isset( $step_headings[ $step_name ] ) ? $step_headings[ $step_name ] : wpbc_setup_wizard__get_step_title( $step_name );
427 }
428
429 /**
430 * Get setup step guidance shown in the floating setup bar.
431 *
432 * @param string $step_name Step name.
433 *
434 * @return string
435 */
436 function wpbc_setup_wizard__get_step_description( $step_name ) {
437
438 $step_descriptions = array(
439 'welcome' => __( 'Begin the guided setup. You can leave the wizard at any time and continue later from the setup bar.', 'booking' ),
440 'general_info' => __( 'Review the business name, contact details, and basic information used while preparing the booking configuration.', 'booking' ),
441 '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' ),
442 'bookings_types' => __( 'Select whether bookings use full days, appointment time slots, or changeover-style date ranges. This choice controls the next configuration steps.', 'booking' ),
443 'form_structure' => __( 'Open the form template chooser, select the template that matches your booking type, and save the Booking Form page before continuing.', 'booking' ),
444 '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' ),
445 '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' ),
446 'time_slots_availability' => __( 'Check the generated appointment slots and adjust any slot-specific availability rules before moving to broader date availability.', 'booking' ),
447 'date_availability' => __( 'Set which weekdays, dates, booking windows, and buffer rules should be available or unavailable for visitors.', 'booking' ),
448 'color_theme' => __( 'Choose the calendar skin and visual style so the booking form fits your site before you publish it.', 'booking' ),
449 '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' ),
450 'get_started' => __( 'Finish the setup wizard. After this, the setup bar will disappear and you can start managing bookings normally.', 'booking' ),
451 );
452
453 return isset( $step_descriptions[ $step_name ] ) ? $step_descriptions[ $step_name ] : '';
454 }
455
456 /**
457 * Get external setup step UI integration matrix.
458 *
459 * Each entry describes how the floating setup bar should connect a wizard step
460 * to an existing WPBC admin page: what to open, what to scroll/highlight, which
461 * form/save control belongs to this step, and which JS events mean the external
462 * page has saved successfully.
463 *
464 * @return array
465 */
466 function wpbc_setup_wizard__get_step_ui_matrix() {
467
468 return array(
469 'form_structure' => array(
470 'save_behavior' => 'manual_save_required',
471 'target_selector' => '.wpbc_admin_page__tab__builder_booking_form, #wpbc_form_field_free',
472 'scroll_selector' => '.wpbc_bfb_popup_modal__forms_loading_section:visible, #wpbc_form_field_free:visible, .wpbc_admin_page__tab__builder_booking_form:visible',
473 'highlight_selector' => '.wpbc_bfb_popup_modal__forms_loading_section:visible, #wpbc_form_field_free:visible, .wpbc_admin_page__tab__builder_booking_form:visible',
474 'form_selector' => '#wpbc_form_field_free',
475 '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]',
476 'save_events' => 'wpbc:bfb:form:ajax_saved,wpbc:bfb:form:saved,wpbc:bfb:save:done,wpbc:bfb:ajax_saved,wpbc:setup-wizard:step-saved',
477 ),
478 'date_selection' => array(
479 'save_behavior' => 'manual_save_required',
480 'target_selector' => '.wpbc_tr_set_gen_booking_type_of_day_selections, #wpbc_general_settings_calendar_metabox',
481 'scroll_selector' => '.wpbc_tr_set_gen_booking_type_of_day_selections:visible, #wpbc_general_settings_calendar_metabox:visible',
482 'highlight_selector' => '.wpbc_tr_set_gen_booking_type_of_day_selections:visible, #wpbc_general_settings_calendar_metabox:visible',
483 'form_selector' => '#wpbc_general_settings_form',
484 'save_selector' => '#wpbc_general_settings_form .wpbc_submit_button_trigger, #wpbc_general_settings_form .wpbc_submit_button',
485 'save_events' => 'wpbc:setup-wizard:step-saved',
486 'open_action' => 'settings_section',
487 ),
488 'working_time' => array(
489 'save_behavior' => 'manual_save_required',
490 'target_selector' => '[data-group="general-availability-working-time"], .wpbc_ag_working_time_block, .wpbc_admin_page__tab__general_availability',
491 'scroll_selector' => '[data-group="general-availability-working-time"]:visible, .wpbc_ag_working_time_block:visible, [data-wpbc-ag-settings-form="1"]:visible',
492 'highlight_selector' => '[data-group="general-availability-working-time"]:visible, .wpbc_ag_working_time_block:visible',
493 'form_selector' => '[data-wpbc-ag-settings-form="1"]',
494 'save_selector' => '[data-wpbc-ag-save="1"]',
495 'save_events' => 'wpbc:availability-general:settings-saved,wpbc:setup-wizard:step-saved',
496 'open_action' => 'availability_section',
497 ),
498 'time_slots_availability' => array(
499 'save_behavior' => 'link_only',
500 'target_selector' => '.wpbc_admin_page__tab__time_slots_availability, .wpbc_ts_page',
501 'scroll_selector' => '.wpbc_admin_page__tab__time_slots_availability:visible, .wpbc_ts_page:visible',
502 'highlight_selector' => '.wpbc_admin_page__tab__time_slots_availability:visible, .wpbc_ts_page:visible',
503 ),
504 'date_availability' => array(
505 'save_behavior' => 'manual_save_required',
506 'target_selector' => '[data-group="general-availability-weekdays"], .wpbc_admin_page__tab__general_availability, [data-wpbc-ag-settings-form="1"]',
507 'scroll_selector' => '[data-group="general-availability-weekdays"]:visible, [data-wpbc-ag-settings-form="1"]:visible',
508 'highlight_selector' => '[data-group="general-availability-weekdays"]:visible, [data-wpbc-ag-settings-form="1"]:visible',
509 'form_selector' => '[data-wpbc-ag-settings-form="1"]',
510 'save_selector' => '[data-wpbc-ag-save="1"]',
511 'save_events' => 'wpbc:availability-general:settings-saved,wpbc:setup-wizard:step-saved',
512 'open_action' => 'availability_section',
513 ),
514 'color_theme' => array(
515 'save_behavior' => 'manual_save_required',
516 'target_selector' => '#wpbc_general_settings_form',
517 'scroll_selector' => '#wpbc_general_settings_form:visible',
518 'highlight_selector' => '#wpbc_general_settings_form:visible',
519 'form_selector' => '#wpbc_general_settings_form',
520 'save_selector' => '#wpbc_general_settings_form .wpbc_submit_button_trigger, #wpbc_general_settings_form .wpbc_submit_button',
521 'save_events' => 'wpbc:setup-wizard:step-saved',
522 ),
523 'wizard_publish' => array(
524 'save_behavior' => 'link_only',
525 'target_selector' => '.ui_group__publish_btn, .wpbc_resource_field__publish, .wpbc_resource_publish, .wpbc_publish_resources, .wpbc_resource_shortcode, [data-wpbc-resource-publish], #wpbc_booking_resource_table, .wpbc_admin_page',
526 'scroll_selector' => '.ui_group__publish_btn:visible, .wpbc_resource_field__publish:visible, .wpbc_resource_publish:visible, .wpbc_publish_resources:visible, .wpbc_resource_shortcode:visible, [data-wpbc-resource-publish]:visible, #wpbc_booking_resource_table:visible',
527 'highlight_selector' => '.ui_group__publish_btn:visible, .wpbc_resource_field__publish:visible, .wpbc_resource_publish:visible, .wpbc_publish_resources:visible, .wpbc_resource_shortcode:visible, [data-wpbc-resource-publish]:visible, #wpbc_booking_resource_table:visible',
528 'open_action' => 'publish_area',
529 ),
530 'get_started' => array(
531 'save_behavior' => 'complete',
532 'target_selector' => '.wpbc_admin_page',
533 'scroll_selector' => '.wpbc_admin_page:visible',
534 'highlight_selector' => '.wpbc_admin_page:visible',
535 ),
536 );
537 }
538
539 /**
540 * Get one UI integration value from the external setup step matrix.
541 *
542 * @param string $step_name Step name.
543 * @param string $key Matrix key.
544 *
545 * @return string
546 */
547 function wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, $key ) {
548
549 $ui_matrix = wpbc_setup_wizard__get_step_ui_matrix();
550
551 return ( isset( $ui_matrix[ $step_name ][ $key ] ) ) ? (string) $ui_matrix[ $step_name ][ $key ] : '';
552 }
553
554 /**
555 * Get save behavior for external setup step.
556 *
557 * @param string $step_name Step name.
558 *
559 * @return string
560 */
561 function wpbc_setup_wizard__get_step_save_behavior( $step_name ) {
562
563 $save_behavior = wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'save_behavior' );
564
565 return ( ! empty( $save_behavior ) ) ? $save_behavior : 'link_only';
566 }
567
568 /**
569 * Get DOM selector to highlight/scroll on external setup pages.
570 *
571 * @param string $step_name Step name.
572 *
573 * @return string
574 */
575 function wpbc_setup_wizard__get_step_target_selector( $step_name ) {
576
577 return wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'target_selector' );
578 }
579
580 /**
581 * Get DOM selector to scroll on external setup pages.
582 *
583 * @param string $step_name Step name.
584 *
585 * @return string
586 */
587 function wpbc_setup_wizard__get_step_scroll_selector( $step_name ) {
588
589 $scroll_selector = wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'scroll_selector' );
590
591 return ( ! empty( $scroll_selector ) ) ? $scroll_selector : wpbc_setup_wizard__get_step_target_selector( $step_name );
592 }
593
594 /**
595 * Get DOM selector to highlight on external setup pages.
596 *
597 * @param string $step_name Step name.
598 *
599 * @return string
600 */
601 function wpbc_setup_wizard__get_step_highlight_selector( $step_name ) {
602
603 $highlight_selector = wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'highlight_selector' );
604
605 return ( ! empty( $highlight_selector ) ) ? $highlight_selector : wpbc_setup_wizard__get_step_target_selector( $step_name );
606 }
607
608 /**
609 * Get page open action for external setup pages.
610 *
611 * @param string $step_name Step name.
612 *
613 * @return string
614 */
615 function wpbc_setup_wizard__get_step_open_action( $step_name ) {
616
617 return wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'open_action' );
618 }
619
620 /**
621 * Get browser events that confirm an external setup page save.
622 *
623 * @param string $step_name Step name.
624 *
625 * @return string
626 */
627 function wpbc_setup_wizard__get_step_save_events( $step_name ) {
628
629 return wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'save_events' );
630 }
631
632 /**
633 * Get DOM selector for the existing page form related to the setup step.
634 *
635 * @param string $step_name Step name.
636 *
637 * @return string
638 */
639 function wpbc_setup_wizard__get_step_form_selector( $step_name ) {
640
641 return wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'form_selector' );
642 }
643
644 /**
645 * Get selector for the existing page save button related to the setup step.
646 *
647 * @param string $step_name Step name.
648 *
649 * @return string
650 */
651 function wpbc_setup_wizard__get_step_save_selector( $step_name ) {
652
653 return wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'save_selector' );
654 }
655
656 /**
657 * Add setup guide context to a target URL.
658 *
659 * @param string $url URL.
660 * @param string $step_name Step name.
661 *
662 * @return string
663 */
664 function wpbc_setup_wizard__add_setup_context_to_url( $url, $step_name ) {
665
666 return add_query_arg(
667 array(
668 'wpbc_setup' => '1',
669 'wpbc_setup_step' => $step_name,
670 ),
671 $url
672 );
673 }
674
675 /**
676 * Get the Form Builder template search key for the selected booking type.
677 *
678 * @return string
679 */
680 function wpbc_setup_wizard__get_bfb_template_search_key() {
681
682 $booking_wizard_data_arr = get_bk_option( 'booking_wizard_data' );
683 if (
684 empty( $booking_wizard_data_arr )
685 || ! is_array( $booking_wizard_data_arr )
686 || empty( $booking_wizard_data_arr['save_and_continue__bookings_types'] )
687 || ! is_array( $booking_wizard_data_arr['save_and_continue__bookings_types'] )
688 ) {
689 return '';
690 }
691
692 $booking_type = isset( $booking_wizard_data_arr['save_and_continue__bookings_types']['wpbc_swp_booking_types'] )
693 ? $booking_wizard_data_arr['save_and_continue__bookings_types']['wpbc_swp_booking_types']
694 : '';
695 $url_sep = defined( 'WPBC_BFB_TEMPLATE_SEARCH_OR_SEPARATOR_URL' ) ? WPBC_BFB_TEMPLATE_SEARCH_OR_SEPARATOR_URL : '^';
696
697 if ( 'full_days_bookings' === $booking_type ) {
698 return 'full-days' . $url_sep . 'dates_form';
699 }
700
701 if ( 'time_slots_appointments' === $booking_type ) {
702 if ( 'rangetime' === wpbc_setup_wizard__get_selected_appointments_type( $booking_wizard_data_arr ) ) {
703 return 'times' . $url_sep . 'time slots';
704 }
705
706 return 'appointments' . $url_sep . 'service';
707 }
708
709 if ( 'changeover_multi_dates_bookings' === $booking_type ) {
710 return 'changeover' . $url_sep . 'triangles';
711 }
712
713 return '';
714 }
715
716 /**
717 * Get the existing admin page URL that should handle a setup step.
718 *
719 * @param string $step_name Step name.
720 *
721 * @return string
722 */
723 function wpbc_setup_wizard__get_step_target_url( $step_name ) {
724
725 if ( wpbc_setup_wizard__is_internal_step( $step_name ) ) {
726 return add_query_arg( 'current_step', $step_name, wpbc_get_setup_wizard_page_url() );
727 }
728
729 switch ( $step_name ) {
730 case 'date_selection':
731 $url = add_query_arg(
732 array(
733 'tab' => 'general',
734 'scroll_to_section' => 'wpbc_general_settings_calendar_tab',
735 ),
736 wpbc_get_settings_url()
737 );
738 $url .= '#do_expand__wpbc_general_settings_calendar_metabox#do_other_actions__blink_day_selections';
739 break;
740
741 case 'working_time':
742 $url = function_exists( 'wpbc_get_general_availability_url' )
743 ? wpbc_get_general_availability_url()
744 : admin_url( 'admin.php?page=wpbc-availability&tab=general_availability' );
745 $url = add_query_arg( 'wpbc_ag_open', 'working_time', $url );
746 break;
747
748 case 'time_slots_availability':
749 $url = function_exists( 'wpbc_get_time_slots_availability_url' )
750 ? wpbc_get_time_slots_availability_url()
751 : admin_url( 'admin.php?page=wpbc-availability&tab=time_slots_availability' );
752 break;
753
754 case 'date_availability':
755 $url = function_exists( 'wpbc_get_general_availability_url' )
756 ? wpbc_get_general_availability_url()
757 : admin_url( 'admin.php?page=wpbc-availability&tab=general_availability' );
758 $url = add_query_arg( 'wpbc_ag_open', 'weekdays', $url );
759 break;
760
761 case 'form_structure':
762 $url = ( (bool) WPBC_Frontend_Settings::is_bfb_enabled( null ) )
763 ? wpbc_get_settings_url() . '&tab=builder_booking_form'
764 : wpbc_get_settings_url() . '&tab=form';
765 if ( (bool) WPBC_Frontend_Settings::is_bfb_enabled( null ) ) {
766 $template_search_key = wpbc_setup_wizard__get_bfb_template_search_key();
767 if ( ! empty( $template_search_key ) ) {
768 $url = add_query_arg( 'auto_open_template', $template_search_key, $url );
769 }
770 }
771 break;
772
773 case 'color_theme':
774 $url = wpbc_get_settings_url() . '&tab=color_themes';
775 break;
776
777 case 'wizard_publish':
778 $url = wpbc_get_resources_url() . '#wpbc_booking_resource_table';
779 break;
780
781 case 'get_started':
782 $url = wpbc_get_bookings_url() . '&tab=vm_booking_listing';
783 break;
784
785 default:
786 $url = wpbc_get_setup_wizard_page_url();
787 break;
788 }
789
790 return wpbc_setup_wizard__add_setup_context_to_url( $url, $step_name );
791 }
792
793 /**
794 * Get URL that completes an external setup step and redirects to the next mapped step.
795 *
796 * @param string $step_name Step name.
797 *
798 * @return string
799 */
800 function wpbc_setup_wizard__get_step_continue_url( $step_name ) {
801
802 if ( wpbc_setup_wizard__is_internal_step( $step_name ) ) {
803 return wpbc_setup_wizard__get_step_target_url( $step_name );
804 }
805
806 return add_query_arg(
807 array(
808 'wpbc_setup_wizard' => 'continue',
809 'wpbc_setup_step' => $step_name,
810 'wpbc_setup_from_page_step' => $step_name,
811 '_wpnonce' => wp_create_nonce( 'wpbc_settings_url_nonce' ),
812 ),
813 wpbc_get_setup_wizard_page_url()
814 );
815 }
816
817 /**
818 * Get setup step metadata for routing and UI.
819 *
820 * @param string $step_name Step name.
821 *
822 * @return array
823 */
824 function wpbc_setup_wizard__get_step_route_metadata( $step_name ) {
825
826 return array(
827 'is_external' => ! wpbc_setup_wizard__is_internal_step( $step_name ),
828 'target_url' => wpbc_setup_wizard__get_step_target_url( $step_name ),
829 'title' => wpbc_setup_wizard__get_step_title( $step_name ),
830 'heading' => wpbc_setup_wizard__get_step_heading( $step_name ),
831 'description' => wpbc_setup_wizard__get_step_description( $step_name ),
832 'save_behavior' => wpbc_setup_wizard__get_step_save_behavior( $step_name ),
833 'target_selector' => wpbc_setup_wizard__get_step_target_selector( $step_name ),
834 'scroll_selector' => wpbc_setup_wizard__get_step_scroll_selector( $step_name ),
835 'highlight_selector' => wpbc_setup_wizard__get_step_highlight_selector( $step_name ),
836 'form_selector' => wpbc_setup_wizard__get_step_form_selector( $step_name ),
837 'save_selector' => wpbc_setup_wizard__get_step_save_selector( $step_name ),
838 'save_events' => wpbc_setup_wizard__get_step_save_events( $step_name ),
839 'open_action' => wpbc_setup_wizard__get_step_open_action( $step_name ),
840 );
841 }
842
843 /**
844 * Get first step after "Booking Type" for current profile.
845 *
846 * @return string
847 */
848 function wpbc_setup_wizard__get_first_profile_step() {
849
850 $route = wpbc_setup_wizard__get_profile_route();
851
852 return ( empty( $route ) ) ? 'color_theme' : $route[0];
853 }
854