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

928 lines 33.4 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 $changeover_route = array(
188 'form_structure',
189 'date_selection',
190 'changeover_days',
191 'date_availability',
192 'color_theme',
193 'wizard_publish',
194 'get_started',
195 );
196
197 $time_based_route = array(
198 'form_structure',
199 'date_selection',
200 'working_time',
201 'time_slots_availability',
202 'color_theme',
203 'wizard_publish',
204 'get_started',
205 );
206
207 return array(
208 'full_day' => $full_day_route,
209 'changeover' => $changeover_route,
210 'time_slots' => $time_based_route,
211 'duration_appointments' => $time_based_route,
212 );
213 }
214
215 /**
216 * Get profile-specific setup route after "Booking Type".
217 *
218 * @param string|null $profile Profile.
219 * @param bool|null $is_bfb_enabled Deprecated. Kept for backward-compatible calls.
220 *
221 * @return array
222 */
223 function wpbc_setup_wizard__get_profile_route( $profile = null, $is_bfb_enabled = null ) {
224
225 $profile = ( null === $profile ) ? wpbc_setup_wizard__get_selected_profile() : $profile;
226 $route_map = wpbc_setup_wizard__get_profile_route_map();
227 $route = isset( $route_map[ $profile ] ) ? $route_map[ $profile ] : $route_map['full_day'];
228
229 if ( wpbc_is_this_demo() && 'changeover' !== $profile ) {
230 $route = array_values( array_diff( $route, array( 'wizard_publish' ) ) );
231 }
232
233 return $route;
234 }
235
236 /**
237 * Get the next setup step from the current profile route.
238 *
239 * @param string $current_step Current step name.
240 *
241 * @return string
242 */
243 function wpbc_setup_wizard__get_next_step_name( $current_step ) {
244
245 $route = array_merge( wpbc_setup_wizard__get_intro_route(), wpbc_setup_wizard__get_profile_route() );
246
247 $current_step_index = array_search( $current_step, $route, true );
248
249 if ( false === $current_step_index ) {
250 return '';
251 }
252
253 return isset( $route[ $current_step_index + 1 ] ) ? $route[ $current_step_index + 1 ] : '';
254 }
255
256 /**
257 * Check whether the step is rendered inside the setup wizard page.
258 *
259 * @param string $step_name Step name.
260 *
261 * @return bool
262 */
263 function wpbc_setup_wizard__is_internal_step( $step_name ) {
264
265 return in_array( $step_name, array( 'welcome', 'general_info', 'date_time_formats', 'bookings_types' ), true );
266 }
267
268 /**
269 * Detect the external setup step from the current WPBC admin page request.
270 *
271 * @return string
272 */
273 function wpbc_setup_wizard__detect_step_from_admin_request() {
274
275 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
276 $page = isset( $_GET['page'] ) ? sanitize_key( wp_unslash( $_GET['page'] ) ) : '';
277 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
278 $tab = isset( $_GET['tab'] ) ? sanitize_key( wp_unslash( $_GET['tab'] ) ) : '';
279 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
280 $scroll_to_section = isset( $_GET['scroll_to_section'] ) ? sanitize_key( wp_unslash( $_GET['scroll_to_section'] ) ) : '';
281 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
282 $wpbc_ag_open = isset( $_GET['wpbc_ag_open'] ) ? sanitize_key( wp_unslash( $_GET['wpbc_ag_open'] ) ) : '';
283 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
284 $wpbc_calendar_section = isset( $_GET['wpbc_calendar_section'] ) ? sanitize_key( wp_unslash( $_GET['wpbc_calendar_section'] ) ) : '';
285
286 if ( 'wpbc-settings' === $page ) {
287 if ( 'builder_booking_form' === $tab ) {
288 return 'form_structure';
289 }
290
291 if ( 'form' === $tab ) {
292 return 'form_structure';
293 }
294
295 if ( 'calendar_settings' === $tab ) {
296 if ( 'changeover_times' === $wpbc_calendar_section ) {
297 return 'changeover_days';
298 }
299 return 'date_selection';
300 }
301
302 if ( 'wpbc_general_settings_calendar_tab' === $scroll_to_section ) {
303 return 'date_selection';
304 }
305
306 if ( 'themes' === $tab ) {
307 return 'color_theme';
308 }
309 }
310
311 if ( 'wpbc-availability' === $page ) {
312 if ( 'time_slots_availability' === $tab ) {
313 return 'time_slots_availability';
314 }
315
316 if ( 'working_time' === $wpbc_ag_open ) {
317 return 'working_time';
318 }
319
320 return 'date_availability';
321 }
322
323 if ( 'wpbc-resources' === $page ) {
324 return 'wizard_publish';
325 }
326
327 return '';
328 }
329
330 /**
331 * Detect an external setup step from an admin URL.
332 *
333 * @param string $url URL.
334 *
335 * @return string
336 */
337 function wpbc_setup_wizard__detect_step_from_admin_url( $url ) {
338
339 if ( empty( $url ) ) {
340 return '';
341 }
342
343 $url_parts = wp_parse_url( $url );
344 if ( empty( $url_parts['query'] ) ) {
345 return '';
346 }
347
348 $query_args = array();
349 wp_parse_str( $url_parts['query'], $query_args );
350
351 $page = isset( $query_args['page'] ) ? sanitize_key( $query_args['page'] ) : '';
352 $tab = isset( $query_args['tab'] ) ? sanitize_key( $query_args['tab'] ) : '';
353 $scroll_to_section = isset( $query_args['scroll_to_section'] ) ? sanitize_key( $query_args['scroll_to_section'] ) : '';
354 $wpbc_ag_open = isset( $query_args['wpbc_ag_open'] ) ? sanitize_key( $query_args['wpbc_ag_open'] ) : '';
355 $wpbc_calendar_section = isset( $query_args['wpbc_calendar_section'] ) ? sanitize_key( $query_args['wpbc_calendar_section'] ) : '';
356
357 if ( 'wpbc-settings' === $page ) {
358 if ( 'builder_booking_form' === $tab ) {
359 return 'form_structure';
360 }
361
362 if ( 'form' === $tab ) {
363 return 'form_structure';
364 }
365
366 if ( 'calendar_settings' === $tab ) {
367 if ( 'changeover_times' === $wpbc_calendar_section ) {
368 return 'changeover_days';
369 }
370 return 'date_selection';
371 }
372
373 if ( 'wpbc_general_settings_calendar_tab' === $scroll_to_section ) {
374 return 'date_selection';
375 }
376
377 if ( 'themes' === $tab ) {
378 return 'color_theme';
379 }
380 }
381
382 if ( 'wpbc-availability' === $page ) {
383 if ( 'time_slots_availability' === $tab ) {
384 return 'time_slots_availability';
385 }
386
387 if ( 'working_time' === $wpbc_ag_open ) {
388 return 'working_time';
389 }
390
391 return 'date_availability';
392 }
393
394 if ( 'wpbc-resources' === $page ) {
395 return 'wizard_publish';
396 }
397
398 return '';
399 }
400
401 /**
402 * Get human-readable setup step title.
403 *
404 * @param string $step_name Step name.
405 *
406 * @return string
407 */
408 function wpbc_setup_wizard__get_step_title( $step_name ) {
409
410 $step_titles = array(
411 'welcome' => __( 'Welcome', 'booking' ),
412 'general_info' => __( 'General Info', 'booking' ),
413 'date_time_formats' => __( 'Dates and Times', 'booking' ),
414 'bookings_types' => __( 'Booking Type', 'booking' ),
415 'date_selection' => __( 'Date Selection', 'booking' ),
416 'changeover_days' => __( 'Changeover Days', 'booking' ),
417 'working_time' => __( 'Working Time', 'booking' ),
418 'time_slots_availability' => __( 'Time Slots', 'booking' ),
419 'date_availability' => __( 'Date Availability', 'booking' ),
420 'form_structure' => __( 'Booking Form', 'booking' ),
421 'color_theme' => __( 'Color Theme', 'booking' ),
422 'wizard_publish' => __( 'Publish', 'booking' ),
423 'get_started' => __( 'Get Started', 'booking' ),
424 );
425
426 return isset( $step_titles[ $step_name ] ) ? $step_titles[ $step_name ] : $step_name;
427 }
428
429 /**
430 * Get action-oriented setup step heading 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_heading( $step_name ) {
437
438 $step_headings = array(
439 'welcome' => __( 'Start the initial setup', 'booking' ),
440 'general_info' => __( 'Confirm your business details', 'booking' ),
441 'date_time_formats' => __( 'Choose date and time formats', 'booking' ),
442 'bookings_types' => __( 'Choose the main booking workflow', 'booking' ),
443 'form_structure' => __( 'Select and save the booking form template', 'booking' ),
444 'date_selection' => __( 'Set how visitors select dates', 'booking' ),
445 'changeover_days' => __( 'Configure changeover days', 'booking' ),
446 'working_time' => __( 'Define when bookings can start and end', 'booking' ),
447 'time_slots_availability' => __( 'Review availability for appointment slots', 'booking' ),
448 'date_availability' => __( 'Set date availability rules', 'booking' ),
449 'color_theme' => __( 'Choose the calendar appearance', 'booking' ),
450 'wizard_publish' => __( 'Publish the booking form on your site', 'booking' ),
451 'get_started' => __( 'Complete setup and manage bookings', 'booking' ),
452 );
453
454 return isset( $step_headings[ $step_name ] ) ? $step_headings[ $step_name ] : wpbc_setup_wizard__get_step_title( $step_name );
455 }
456
457 /**
458 * Get setup step guidance shown in the floating setup bar.
459 *
460 * @param string $step_name Step name.
461 *
462 * @return string
463 */
464 function wpbc_setup_wizard__get_step_description( $step_name ) {
465
466 $step_descriptions = array(
467 'welcome' => __( 'Begin the guided setup. You can leave the wizard at any time and continue later from the setup bar.', 'booking' ),
468 'general_info' => __( 'Review the business name, contact details, and basic information used while preparing the booking configuration.', 'booking' ),
469 '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' ),
470 'bookings_types' => __( 'Select whether bookings use full days, appointment time slots, or changeover-style date ranges. This choice controls the next configuration steps.', 'booking' ),
471 'form_structure' => __( 'Open the form template chooser, select the template that matches your booking type, and save the Booking Form page before continuing.', 'booking' ),
472 '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' ),
473 'changeover_days' => __( 'Enable and review check-in/check-out changeover days, including diagonal or vertical markings and related changeover options.', 'booking' ),
474 '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' ),
475 'time_slots_availability' => __( 'Check the generated appointment slots and adjust any slot-specific availability rules before choosing the calendar appearance.', 'booking' ),
476 'date_availability' => __( 'Set which weekdays, dates, booking windows, and buffer rules should be available or unavailable for visitors.', 'booking' ),
477 'color_theme' => __( 'Choose the calendar skin and visual style so the booking form fits your site before you publish it.', 'booking' ),
478 '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' ),
479 'get_started' => __( 'Finish the setup wizard. After this, the setup bar will disappear and you can start managing bookings normally.', 'booking' ),
480 );
481
482 return isset( $step_descriptions[ $step_name ] ) ? $step_descriptions[ $step_name ] : '';
483 }
484
485 /**
486 * Get external setup step UI integration matrix.
487 *
488 * Each entry describes how the floating setup bar should connect a wizard step
489 * to an existing WPBC admin page: what to open, what to scroll/highlight, which
490 * form/save control belongs to this step, and which JS events mean the external
491 * page has saved successfully.
492 *
493 * @return array
494 */
495 function wpbc_setup_wizard__get_step_ui_matrix() {
496
497 return array(
498 'form_structure' => array(
499 'save_behavior' => 'manual_save_required',
500 'target_selector' => '.wpbc_admin_page__tab__builder_booking_form, #wpbc_form_field_free',
501 'scroll_selector' => '.wpbc_bfb_popup_modal__forms_loading_section:visible, #wpbc_form_field_free:visible, .wpbc_admin_page__tab__builder_booking_form:visible',
502 'highlight_disabled' => '1',
503 'form_selector' => '#wpbc_form_field_free',
504 '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]',
505 'save_events' => 'wpbc:bfb:form:ajax_saved,wpbc:bfb:form:saved,wpbc:bfb:save:done,wpbc:bfb:ajax_saved,wpbc:setup-wizard:step-saved',
506 ),
507 'date_selection' => array(
508 'save_behavior' => 'manual_save_required',
509 '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"]',
510 'scroll_selector' => '[data-group="settings-calendar-days-selection"]:visible, .wpbc_calendar__inspector_settings:visible, [data-wpbc-calendar-settings-form="1"]:visible',
511 'highlight_selector' => '[data-group="settings-calendar-days-selection"]:visible, .wpbc_calendar__inspector_settings:visible, [data-wpbc-calendar-settings-form="1"]:visible',
512 'form_selector' => '[data-wpbc-calendar-settings-form="1"], #wpbc_general_settings_form',
513 'save_selector' => '[data-wpbc-calendar-save="1"], #wpbc_general_settings_form .wpbc_submit_button_trigger, #wpbc_general_settings_form .wpbc_submit_button',
514 'save_ajax_action' => 'WPBC_AJX_SETTINGS_CALENDAR_SAVE',
515 'save_events' => 'wpbc:setup-wizard:step-saved',
516 ),
517 'changeover_days' => array(
518 'save_behavior' => 'manual_save_required',
519 '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"]',
520 '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',
521 'highlight_selector' => '[data-group="settings-calendar-time"]:visible, [data-wpbc-calendar-changeover-settings="1"]:visible, [name="booking_range_selection_time_is_active"]:visible',
522 'form_selector' => '[data-wpbc-calendar-settings-form="1"]',
523 'save_selector' => '[data-wpbc-calendar-save="1"]',
524 'save_ajax_action' => 'WPBC_AJX_SETTINGS_CALENDAR_SAVE',
525 'save_events' => 'wpbc:setup-wizard:step-saved',
526 ),
527 'working_time' => array(
528 'save_behavior' => 'manual_save_required',
529 'target_selector' => '[data-group="general-availability-working-time"], .wpbc_ag_working_time_block, .wpbc_admin_page__tab__general_availability',
530 'scroll_selector' => '[data-group="general-availability-working-time"]:visible, .wpbc_ag_working_time_block:visible, [data-wpbc-ag-settings-form="1"]:visible',
531 'highlight_selector' => '[data-group="general-availability-working-time"]:visible, .wpbc_ag_working_time_block:visible',
532 'form_selector' => '[data-wpbc-ag-settings-form="1"]',
533 'save_selector' => '[data-wpbc-ag-save="1"]',
534 'save_ajax_action' => 'WPBC_AJX_AVAILABILITY_GENERAL_SAVE',
535 'save_events' => 'wpbc:availability-general:settings-saved,wpbc:setup-wizard:step-saved',
536 'open_action' => 'availability_section',
537 ),
538 'time_slots_availability' => array(
539 'save_behavior' => 'link_only',
540 'target_selector' => '.wpbc_admin_page__tab__time_slots_availability, .wpbc_ts_page',
541 'scroll_selector' => '.wpbc_admin_page__tab__time_slots_availability:visible, .wpbc_ts_page:visible',
542 'highlight_disabled' => '1',
543 ),
544 'date_availability' => array(
545 'save_behavior' => 'manual_save_required',
546 'target_selector' => '[data-group="general-availability-weekdays"], .wpbc_admin_page__tab__general_availability, [data-wpbc-ag-settings-form="1"]',
547 'scroll_selector' => '[data-group="general-availability-weekdays"]:visible, [data-wpbc-ag-settings-form="1"]:visible',
548 'highlight_selector' => '[data-group="general-availability-weekdays"]:visible, [data-wpbc-ag-settings-form="1"]:visible',
549 'form_selector' => '[data-wpbc-ag-settings-form="1"]',
550 'save_selector' => '[data-wpbc-ag-save="1"]',
551 'save_ajax_action' => 'WPBC_AJX_AVAILABILITY_GENERAL_SAVE',
552 'save_events' => 'wpbc:availability-general:settings-saved,wpbc:setup-wizard:step-saved',
553 'open_action' => 'availability_section',
554 ),
555 'color_theme' => array(
556 'save_behavior' => 'manual_save_required',
557 'target_selector' => '.wpbc_admin_page__tab__themes, [data-wpbc-theme-page="1"]',
558 'scroll_selector' => '.wpbc_theme__inspector_settings:visible, [data-wpbc-theme-settings-form="1"]:visible, .wpbc_theme_rightbar_panels:visible',
559 'highlight_selector' => '.wpbc_theme__inspector_settings:visible, [data-wpbc-theme-settings-form="1"]:visible, .wpbc_theme_rightbar_panels:visible',
560 'form_selector' => '[data-wpbc-theme-settings-form="1"]',
561 'save_selector' => '[data-wpbc-theme-save="1"]',
562 'save_ajax_action' => 'WPBC_AJX_SETTINGS_THEMES_SAVE',
563 'save_events' => 'wpbc:setup-wizard:step-saved',
564 ),
565 'wizard_publish' => array(
566 'save_behavior' => 'link_only',
567 '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',
568 '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',
569 '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',
570 'open_action' => 'publish_area',
571 ),
572 'get_started' => array(
573 'save_behavior' => 'complete',
574 'target_selector' => '.wpbc_admin_page',
575 'scroll_selector' => '.wpbc_admin_page:visible',
576 'highlight_disabled' => '1',
577 ),
578 );
579 }
580
581 /**
582 * Get one UI integration value from the external setup step matrix.
583 *
584 * @param string $step_name Step name.
585 * @param string $key Matrix key.
586 *
587 * @return string
588 */
589 function wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, $key ) {
590
591 $ui_matrix = wpbc_setup_wizard__get_step_ui_matrix();
592
593 return ( isset( $ui_matrix[ $step_name ][ $key ] ) ) ? (string) $ui_matrix[ $step_name ][ $key ] : '';
594 }
595
596 /**
597 * Get save behavior for external setup step.
598 *
599 * @param string $step_name Step name.
600 *
601 * @return string
602 */
603 function wpbc_setup_wizard__get_step_save_behavior( $step_name ) {
604
605 $save_behavior = wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'save_behavior' );
606
607 return ( ! empty( $save_behavior ) ) ? $save_behavior : 'link_only';
608 }
609
610 /**
611 * Get DOM selector to highlight/scroll on external setup pages.
612 *
613 * @param string $step_name Step name.
614 *
615 * @return string
616 */
617 function wpbc_setup_wizard__get_step_target_selector( $step_name ) {
618
619 return wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'target_selector' );
620 }
621
622 /**
623 * Get DOM selector to scroll on external setup pages.
624 *
625 * @param string $step_name Step name.
626 *
627 * @return string
628 */
629 function wpbc_setup_wizard__get_step_scroll_selector( $step_name ) {
630
631 $scroll_selector = wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'scroll_selector' );
632
633 return ( ! empty( $scroll_selector ) ) ? $scroll_selector : wpbc_setup_wizard__get_step_target_selector( $step_name );
634 }
635
636 /**
637 * Get DOM selector to highlight on external setup pages.
638 *
639 * @param string $step_name Step name.
640 *
641 * @return string
642 */
643 function wpbc_setup_wizard__get_step_highlight_selector( $step_name ) {
644
645 if ( wpbc_setup_wizard__is_step_highlight_disabled( $step_name ) ) {
646 return '';
647 }
648
649 $highlight_selector = wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'highlight_selector' );
650
651 return ( ! empty( $highlight_selector ) ) ? $highlight_selector : wpbc_setup_wizard__get_step_target_selector( $step_name );
652 }
653
654 /**
655 * Check if external setup page highlighting is disabled for a step.
656 *
657 * @param string $step_name Step name.
658 *
659 * @return bool
660 */
661 function wpbc_setup_wizard__is_step_highlight_disabled( $step_name ) {
662
663 return '1' === wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'highlight_disabled' );
664 }
665
666 /**
667 * Get page open action for external setup pages.
668 *
669 * @param string $step_name Step name.
670 *
671 * @return string
672 */
673 function wpbc_setup_wizard__get_step_open_action( $step_name ) {
674
675 return wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'open_action' );
676 }
677
678 /**
679 * Get browser events that confirm an external setup page save.
680 *
681 * @param string $step_name Step name.
682 *
683 * @return string
684 */
685 function wpbc_setup_wizard__get_step_save_events( $step_name ) {
686
687 return wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'save_events' );
688 }
689
690 /**
691 * Get AJAX action name used by the existing page save button related to the setup step.
692 *
693 * @param string $step_name Step name.
694 *
695 * @return string
696 */
697 function wpbc_setup_wizard__get_step_save_ajax_action( $step_name ) {
698
699 return wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'save_ajax_action' );
700 }
701
702 /**
703 * Get DOM selector for the existing page form related to the setup step.
704 *
705 * @param string $step_name Step name.
706 *
707 * @return string
708 */
709 function wpbc_setup_wizard__get_step_form_selector( $step_name ) {
710
711 return wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'form_selector' );
712 }
713
714 /**
715 * Get selector for the existing page save button related to the setup step.
716 *
717 * @param string $step_name Step name.
718 *
719 * @return string
720 */
721 function wpbc_setup_wizard__get_step_save_selector( $step_name ) {
722
723 return wpbc_setup_wizard__get_step_ui_matrix_value( $step_name, 'save_selector' );
724 }
725
726 /**
727 * Add setup guide context to a target URL.
728 *
729 * @param string $url URL.
730 * @param string $step_name Step name.
731 *
732 * @return string
733 */
734 function wpbc_setup_wizard__add_setup_context_to_url( $url, $step_name ) {
735
736 return add_query_arg(
737 array(
738 'wpbc_setup' => '1',
739 'wpbc_setup_step' => $step_name,
740 ),
741 $url
742 );
743 }
744
745 /**
746 * Get the Form Builder template search key for the selected booking type.
747 *
748 * @return string
749 */
750 function wpbc_setup_wizard__get_bfb_template_search_key() {
751
752 $booking_wizard_data_arr = get_bk_option( 'booking_wizard_data' );
753 if (
754 empty( $booking_wizard_data_arr )
755 || ! is_array( $booking_wizard_data_arr )
756 || empty( $booking_wizard_data_arr['save_and_continue__bookings_types'] )
757 || ! is_array( $booking_wizard_data_arr['save_and_continue__bookings_types'] )
758 ) {
759 return '';
760 }
761
762 $booking_type = isset( $booking_wizard_data_arr['save_and_continue__bookings_types']['wpbc_swp_booking_types'] )
763 ? $booking_wizard_data_arr['save_and_continue__bookings_types']['wpbc_swp_booking_types']
764 : '';
765 $url_sep = defined( 'WPBC_BFB_TEMPLATE_SEARCH_OR_SEPARATOR_URL' ) ? WPBC_BFB_TEMPLATE_SEARCH_OR_SEPARATOR_URL : '^';
766
767 if ( 'full_days_bookings' === $booking_type ) {
768 return 'full-days' . $url_sep . 'dates_form';
769 }
770
771 if ( 'time_slots_appointments' === $booking_type ) {
772 if ( 'rangetime' === wpbc_setup_wizard__get_selected_appointments_type( $booking_wizard_data_arr ) ) {
773 return 'times' . $url_sep . 'time slots';
774 }
775
776 return 'appointments' . $url_sep . 'service';
777 }
778
779 if ( 'changeover_multi_dates_bookings' === $booking_type ) {
780 return 'changeover' . $url_sep . 'triangles';
781 }
782
783 return '';
784 }
785
786 /**
787 * Get the existing admin page URL that should handle a setup step.
788 *
789 * @param string $step_name Step name.
790 *
791 * @return string
792 */
793 function wpbc_setup_wizard__get_step_target_url( $step_name ) {
794
795 if ( wpbc_setup_wizard__is_internal_step( $step_name ) ) {
796 return add_query_arg( 'current_step', $step_name, wpbc_get_setup_wizard_page_url() );
797 }
798
799 switch ( $step_name ) {
800 case 'date_selection':
801 $url = function_exists( 'wpbc_get_settings_calendar_url' )
802 ? wpbc_get_settings_calendar_url()
803 : wpbc_get_settings_url() . '&tab=calendar_settings';
804 $url = add_query_arg( 'wpbc_calendar_section', 'days_selection', $url );
805 break;
806
807 case 'changeover_days':
808 $url = function_exists( 'wpbc_get_settings_calendar_url' )
809 ? wpbc_get_settings_calendar_url()
810 : wpbc_get_settings_url() . '&tab=calendar_settings';
811 $url = add_query_arg( 'wpbc_calendar_section', 'changeover_times', $url );
812 break;
813
814 case 'working_time':
815 $url = function_exists( 'wpbc_get_general_availability_url' )
816 ? wpbc_get_general_availability_url()
817 : admin_url( 'admin.php?page=wpbc-availability&tab=general_availability' );
818 $url = add_query_arg( 'wpbc_ag_open', 'working_time', $url );
819 break;
820
821 case 'time_slots_availability':
822 $url = function_exists( 'wpbc_get_time_slots_availability_url' )
823 ? wpbc_get_time_slots_availability_url()
824 : admin_url( 'admin.php?page=wpbc-availability&tab=time_slots_availability' );
825 break;
826
827 case 'date_availability':
828 $url = function_exists( 'wpbc_get_general_availability_url' )
829 ? wpbc_get_general_availability_url()
830 : admin_url( 'admin.php?page=wpbc-availability&tab=general_availability' );
831 $url = add_query_arg( 'wpbc_ag_open', 'weekdays', $url );
832 break;
833
834 case 'form_structure':
835 $url = wpbc_get_settings_url() . '&tab=builder_booking_form';
836
837 $template_search_key = wpbc_setup_wizard__get_bfb_template_search_key();
838 if ( ! empty( $template_search_key ) ) {
839 $url = add_query_arg( 'auto_open_template', $template_search_key, $url );
840 }
841 break;
842
843 case 'color_theme':
844 $url = function_exists( 'wpbc_get_settings_themes_url' )
845 ? wpbc_get_settings_themes_url()
846 : wpbc_get_settings_url() . '&tab=themes';
847 break;
848
849 case 'wizard_publish':
850 $url = wpbc_get_resources_url() . '#wpbc_booking_resource_table';
851 break;
852
853 case 'get_started':
854 $url = wpbc_get_bookings_url() . '&tab=vm_booking_listing';
855 break;
856
857 default:
858 $url = wpbc_get_setup_wizard_page_url();
859 break;
860 }
861
862 return wpbc_setup_wizard__add_setup_context_to_url( $url, $step_name );
863 }
864
865 /**
866 * Get URL that completes an external setup step and redirects to the next mapped step.
867 *
868 * @param string $step_name Step name.
869 *
870 * @return string
871 */
872 function wpbc_setup_wizard__get_step_continue_url( $step_name ) {
873
874 if ( wpbc_setup_wizard__is_internal_step( $step_name ) ) {
875 return wpbc_setup_wizard__get_step_target_url( $step_name );
876 }
877
878 return add_query_arg(
879 array(
880 'wpbc_setup_wizard' => 'continue',
881 'wpbc_setup_step' => $step_name,
882 'wpbc_setup_from_page_step' => $step_name,
883 '_wpnonce' => wp_create_nonce( 'wpbc_settings_url_nonce' ),
884 ),
885 wpbc_get_setup_wizard_page_url()
886 );
887 }
888
889 /**
890 * Get setup step metadata for routing and UI.
891 *
892 * @param string $step_name Step name.
893 *
894 * @return array
895 */
896 function wpbc_setup_wizard__get_step_route_metadata( $step_name ) {
897
898 return array(
899 'is_external' => ! wpbc_setup_wizard__is_internal_step( $step_name ),
900 'target_url' => wpbc_setup_wizard__get_step_target_url( $step_name ),
901 'title' => wpbc_setup_wizard__get_step_title( $step_name ),
902 'heading' => wpbc_setup_wizard__get_step_heading( $step_name ),
903 'description' => wpbc_setup_wizard__get_step_description( $step_name ),
904 'save_behavior' => wpbc_setup_wizard__get_step_save_behavior( $step_name ),
905 'target_selector' => wpbc_setup_wizard__get_step_target_selector( $step_name ),
906 'scroll_selector' => wpbc_setup_wizard__get_step_scroll_selector( $step_name ),
907 'highlight_selector' => wpbc_setup_wizard__get_step_highlight_selector( $step_name ),
908 'highlight_disabled' => wpbc_setup_wizard__is_step_highlight_disabled( $step_name ) ? '1' : '0',
909 'form_selector' => wpbc_setup_wizard__get_step_form_selector( $step_name ),
910 'save_selector' => wpbc_setup_wizard__get_step_save_selector( $step_name ),
911 'save_ajax_action' => wpbc_setup_wizard__get_step_save_ajax_action( $step_name ),
912 'save_events' => wpbc_setup_wizard__get_step_save_events( $step_name ),
913 'open_action' => wpbc_setup_wizard__get_step_open_action( $step_name ),
914 );
915 }
916
917 /**
918 * Get first step after "Booking Type" for current profile.
919 *
920 * @return string
921 */
922 function wpbc_setup_wizard__get_first_profile_step() {
923
924 $route = wpbc_setup_wizard__get_profile_route();
925
926 return ( empty( $route ) ) ? 'color_theme' : $route[0];
927 }
928