PluginProbe
Booking Calendar / 11.8.3
Booking Calendar v11.8.3
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
← All changes | includes/page-setup/setup_steps.php +427 -44 11.311.8.3 View file →
@@ -1,4 +1,4 @@
1 1 <?php /**
2 2 * @version 1.0
3 3 * @description Steps Structure for Setup Wizard Page
4 4 * @category Setup Class
@@ -41,12 +41,31 @@
41 41 * Whether the setup bar has already been printed in the current request.
42 42 *
43 43 * @var bool
44 44 */
45 - private static $is_top_bar_rendered = false;
45 + private static $is_top_bar_rendered = false;
46 +
47 + /**
48 + * Check whether the legacy floating Setup Wizard bar is enabled.
49 + *
50 + * The bar is temporarily disabled while the initial Setup Wizard hands the
51 + * user directly to Form Builder. The filter preserves a bounded rollback
52 + * path without changing Setup Wizard progress or stored configuration.
53 + *
54 + * @return bool True when the floating Setup Wizard bar may be registered.
55 + */
56 + private static function is_floating_setup_bar_enabled() {
57 +
58 + /**
59 + * Filter whether the legacy floating Setup Wizard bar is enabled.
60 + *
61 + * @param bool $is_enabled Whether the floating Setup Wizard bar is enabled.
62 + */
63 + return (bool) apply_filters( 'wpbc_setup_wizard_floating_bar_enabled', false );
64 + }
65 +
66 + public function __construct() {
46 67
47 - public function __construct() {
48 -
49 68 if ( WPBC()->is_wp_inited() || did_action( 'init' ) ) {
50 69 $this->init_steps_data();
51 70 } else {
52 71 add_action( 'init', array( $this, 'init_steps_data' ) );
@@ -51,12 +70,12 @@
51 70 } else {
52 71 add_action( 'init', array( $this, 'init_steps_data' ) );
53 72 }
54 73
55 - if ( ! self::$is_top_bar_hook_registered ) {
56 - add_action( 'wpbc_after_wpbc_page_top__header_tabs', array( $this, 'show_top_right_wizard_button' ), 10, 3 );
57 - self::$is_top_bar_hook_registered = true;
58 - }
74 + if ( self::is_floating_setup_bar_enabled() && ! self::$is_top_bar_hook_registered ) {
75 + add_action( 'wpbc_after_wpbc_page_top__header_tabs', array( $this, 'show_top_right_wizard_button' ), 10, 3 );
76 + self::$is_top_bar_hook_registered = true;
77 + }
59 78
60 79 }
61 80
62 81 /**
@@ -116,9 +135,9 @@
116 135 );
117 136 }
118 137 }
119 138
120 - foreach ( array( 'date_selection', 'changeover_days', 'working_time', 'time_slots_availability', 'date_availability', 'form_structure', 'color_theme', 'wizard_publish' ) as $continue_step_name ) {
139 + foreach ( array( 'service_provider', 'date_selection', 'changeover_days', 'working_time', 'time_slots_availability', 'date_availability', 'form_structure', 'color_theme', 'wizard_publish' ) as $continue_step_name ) {
121 140 if ( isset( $steps_arr[ $continue_step_name ] ) ) {
122 141 $steps_arr[ $continue_step_name ]['next_title'] = $is_i18n_ready ? __( 'Continue', 'booking' ) : 'Continue';
123 142 }
124 143 }
@@ -812,16 +831,30 @@
812 831 *
813 832 * Show Continue Setup Wizard Button
814 833 * @return void
815 834 */
816 - public function show_top_right_wizard_button() {
835 + public function show_top_right_wizard_button() {
836 +
837 + if ( ! self::is_floating_setup_bar_enabled() ) {
838 + return false;
839 + }
840 +
841 + if ( ! wpbc_is_setup_wizard_page() ) {
842 + $explicit_step_context = false;
817 843
818 - if ( ! wpbc_is_setup_wizard_page() ){
844 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only Setup Wizard routing context.
845 + if ( isset( $_GET['wpbc_setup_step'] ) && is_scalar( $_GET['wpbc_setup_step'] ) ) {
846 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only Setup Wizard routing context.
847 + $request_step = sanitize_key( wp_unslash( $_GET['wpbc_setup_step'] ) );
848 + $explicit_step_context = isset( $this->steps_arr[ $request_step ] )
849 + && function_exists( 'wpbc_setup_wizard_page__has_explicit_step_context' )
850 + && wpbc_setup_wizard_page__has_explicit_step_context( $request_step );
851 + }
819 852
820 853 if (
821 854 ( ! wpbc_is_user_can_access_wizard_page() ) ||
822 - ( $this->db__is_all_steps_completed() )
823 - ){
855 + ( $this->db__is_all_steps_completed() && ! $explicit_step_context )
856 + ) {
824 857 return false;
825 858 }
826 859
827 860 if ( self::$is_top_bar_rendered ) {
@@ -846,16 +879,26 @@
846 879 $save_behavior = $this->get_step_save_behavior( $current_step );
847 880 $target_selector = $this->get_step_meta_value( $current_step, 'target_selector' );
848 881 $scroll_selector = $this->get_step_meta_value( $current_step, 'scroll_selector' );
849 882 $highlight_selector = $this->get_step_meta_value( $current_step, 'highlight_selector' );
883 + $highlight_disabled = $this->get_step_meta_value( $current_step, 'highlight_disabled' );
884 + $highlight_all = $this->get_step_meta_value( $current_step, 'highlight_all' );
850 885 $form_selector = $this->get_step_meta_value( $current_step, 'form_selector' );
851 886 $save_selector = $this->get_step_meta_value( $current_step, 'save_selector' );
887 + $save_ajax_action = $this->get_step_meta_value( $current_step, 'save_ajax_action' );
852 888 $save_events = $this->get_step_meta_value( $current_step, 'save_events' );
853 889 $open_action = $this->get_step_meta_value( $current_step, 'open_action' );
854 - $continue_title = ( 'complete' === $save_behavior ) ? __( 'Finish Setup', 'booking' ) : __( 'Continue', 'booking' );
855 - $is_step_saved = $this->db__is_step_saved( $current_step );
856 - $is_continue_disabled = ( 'manual_save_required' === $save_behavior && ! $is_step_saved );
857 - $continue_href = $is_continue_disabled ? '#wpbc_setup_save_required' : $continue_url;
890 + $secondary_action_url = $this->get_step_meta_value( $current_step, 'secondary_action_url' );
891 + $secondary_action_label = $this->get_step_meta_value( $current_step, 'secondary_action_label' );
892 + $can_save_from_bar = ( 'manual_save_required' === $save_behavior && ! empty( $save_selector ) );
893 + $continue_title = ( 'complete' === $save_behavior ) ? __( 'Finish Setup', 'booking' ) : __( 'Continue', 'booking' );
894 + if ( $can_save_from_bar ) {
895 + $continue_title = __( 'Save and Continue', 'booking' );
896 + }
897 + $is_step_saved = $this->db__is_step_saved( $current_step );
898 + $is_step_unsaved = ( 'manual_save_required' === $save_behavior && ! $is_step_saved );
899 + $is_continue_disabled = ( $is_step_unsaved && ! $can_save_from_bar );
900 + $continue_href = $is_step_unsaved ? '#wpbc_setup_save_required' : $continue_url;
858 901 $mark_saved_nonce = wp_create_nonce( 'wpbc_setup_wizard_mark_step_saved' );
859 902 $step_target_url = $this->get_step_target_url( $current_step );
860 903 $skip_wizard_url = add_query_arg( 'wpbc_setup_wizard', 'completed', wpbc_get_bookings_url() );
861 904 $reset_wizard_url = add_query_arg( 'wpbc_setup_wizard', 'reset', wpbc_get_setup_wizard_page_url() );
@@ -863,8 +906,12 @@
863 906 /* translators: %s: setup target page title. */
864 907 __( 'Save changes on the %s page before continuing.', 'booking' ),
865 908 '<a href="' . esc_url( $step_target_url ) . '">' . esc_html( $step_save_page_title ) . '</a>'
866 909 );
910 + $test_page_links = (
911 + 'wizard_publish' === $current_step
912 + && function_exists( 'wpbc_booking_modes_get_setup_test_page_links' )
913 + ) ? wpbc_booking_modes_get_setup_test_page_links() : array();
867 914
868 915 // FixIn: 10.12.1.1.
869 916 ?><style type="text/css">
870 917 @media screen and (max-width: 782px) {
@@ -1004,8 +1051,42 @@
1004 1051 }
1005 1052 .wpbc_page_top__wizard_button_actions .button.button-secondary {
1006 1053 background-color: #e4e4e4;
1007 1054 }
1055 + .wpbc_setup_wizard_test_page_actions {
1056 + display: flex;
1057 + flex-flow: row wrap;
1058 + align-items: center;
1059 + gap: 8px;
1060 + font-size: 11px;
1061 + font-weight: 400;
1062 + line-height: 1.35;
1063 + }
1064 + .wpbc_page_top__wizard_button[data-wpbc-setup-step="wizard_publish"] .wpbc_page_top__wizard_button_actions {
1065 + flex-flow: row wrap;
1066 + }
1067 + .wpbc_page_top__wizard_button_actions .button.wpbc_setup_wizard_test_page_button,
1068 + .wpbc_page_top__wizard_button_actions .button.wpbc_setup_wizard_test_page_button:hover,
1069 + .wpbc_page_top__wizard_button_actions .button.wpbc_setup_wizard_test_page_button:focus {
1070 + margin: 20px 0;
1071 + background: #71a501;
1072 + border-color: #71a501;
1073 + color: #f0ffce;
1074 + }
1075 + .wpbc_page_top__wizard_button_actions .button.wpbc_setup_wizard_test_page_button:first-child {
1076 + margin-right: auto;
1077 + margin-left: 0;
1078 + }
1079 + .wpbc_page_top__wizard_button[data-wpbc-setup-step="wizard_publish"] .wpbc_page_top__wizard_button_actions.wpbc_page_top__wizard_button_links {
1080 + margin: 0;
1081 + gap: 10px 15px;
1082 + justify-content: flex-start;
1083 + }
1084 + .wpbc_page_top__wizard_button_actions.wpbc_page_top__wizard_button_links .button.wpbc_setup_wizard_test_page_button:first-child,
1085 + .wpbc_page_top__wizard_button[data-wpbc-setup-step="wizard_publish"] .wpbc_page_top__wizard_button_actions.wpbc_page_top__wizard_button_links a {
1086 + margin: 0;
1087 + flex: 0 1 auto;
1088 + }
1008 1089 .wpbc_page_top__wizard_button_actions .button.disabled,
1009 1090 .wpbc_page_top__wizard_button_actions .button[aria-disabled="true"] {
1010 1091 cursor: not-allowed;
1011 1092 opacity: 0.55;
@@ -1105,10 +1186,13 @@
1105 1186 data-wpbc-setup-mark-saved-nonce="<?php echo esc_attr( $mark_saved_nonce ); ?>"
1106 1187 data-wpbc-setup-target-selector="<?php echo esc_attr( $target_selector ); ?>"
1107 1188 data-wpbc-setup-scroll-selector="<?php echo esc_attr( $scroll_selector ); ?>"
1108 1189 data-wpbc-setup-highlight-selector="<?php echo esc_attr( $highlight_selector ); ?>"
1190 + data-wpbc-setup-highlight-disabled="<?php echo esc_attr( $highlight_disabled ); ?>"
1191 + data-wpbc-setup-highlight-all="<?php echo esc_attr( $highlight_all ); ?>"
1109 1192 data-wpbc-setup-form-selector="<?php echo esc_attr( $form_selector ); ?>"
1110 1193 data-wpbc-setup-save-selector="<?php echo esc_attr( $save_selector ); ?>"
1194 + data-wpbc-setup-save-ajax-action="<?php echo esc_attr( $save_ajax_action ); ?>"
1111 1195 data-wpbc-setup-save-events="<?php echo esc_attr( $save_events ); ?>"
1112 1196 data-wpbc-setup-open-action="<?php echo esc_attr( $open_action ); ?>">
1113 1197 <div class="wpbc_ui_control wpbc_page_top__wizard_button_content">
1114 1198 <div class="in-button-text"
@@ -1133,9 +1217,9 @@
1133 1217 <button type="button"
1134 1218 class="wpbc_setup_wizard_bar_icon_button wpbc_setup_wizard_bar_reset_button"
1135 1219 title="<?php esc_attr_e( 'Reset setup bar position', 'booking' ); ?>"
1136 1220 aria-label="<?php esc_attr_e( 'Reset setup bar position', 'booking' ); ?>">
1137 - <i class="menu_icon icon-1x wpbc_icn_refresh"></i>
1221 + <i class="menu_icon icon-1x wpbc_icn_rotate_90 wpbc_icn_pin_invoke"></i>
1138 1222 </button>
1139 1223 <button type="button"
1140 1224 class="wpbc_setup_wizard_bar_icon_button wpbc_setup_wizard_bar_toggle_button"
1141 1225 title="<?php esc_attr_e( 'Collapse setup bar', 'booking' ); ?>"
@@ -1140,9 +1224,9 @@
1140 1224 class="wpbc_setup_wizard_bar_icon_button wpbc_setup_wizard_bar_toggle_button"
1141 1225 title="<?php esc_attr_e( 'Collapse setup bar', 'booking' ); ?>"
1142 1226 aria-label="<?php esc_attr_e( 'Collapse setup bar', 'booking' ); ?>"
1143 1227 aria-expanded="true">
1144 - <i class="menu_icon icon-1x wpbc_icn_expand_less"></i>
1228 + <i class="menu_icon icon-1x wpbc_icn_minimize"></i>
1145 1229 </button>
1146 1230 </div>
1147 1231 </div>
1148 1232 <div class="name_item wpbc_setup_wizard_bar_expandable" style="flex:1 1 100%;font-size:13px;font-weight:600;line-height:1.35;margin:3px 0 0;color:#f1f1f1;">
@@ -1176,9 +1260,32 @@
1176 1260 }
1177 1261 ?>
1178 1262 </div>
1179 1263 <?php } ?>
1264 + <?php if ( 'wizard_publish' === $current_step && empty( $test_page_links ) ) { ?>
1265 + <div class="wpbc_setup_wizard_test_page_actions wpbc_setup_wizard_bar_expandable">
1266 + <span><?php esc_html_e( 'No published booking page was found yet. Use QuickStart or the page publishing controls, then return to this step.', 'booking' ); ?></span>
1267 + </div>
1268 + <?php } ?>
1269 + <?php if ( 'wizard_publish' === $current_step && ! empty( $test_page_links ) ) { ?>
1270 + <div class="wpbc_page_top__wizard_button_actions wpbc_setup_wizard_bar_expandable wpbc_page_top__wizard_button_links">
1271 + <?php foreach ( $test_page_links as $test_page_link ) {
1272 + if ( empty( $test_page_link['url'] ) || empty( $test_page_link['label'] ) ) {
1273 + continue;
1274 + }
1275 + ?>
1276 + <a class="button button-primary secondary wpbc_setup_wizard_test_page_button"
1277 + href="<?php echo esc_url( $test_page_link['url'] ); ?>"
1278 + target="_blank"
1279 + rel="noopener noreferrer"><?php echo esc_html( $test_page_link['label'] ); ?></a>
1280 + <?php } ?>
1281 + </div>
1282 + <?php } ?>
1180 1283 <div class="wpbc_page_top__wizard_button_actions wpbc_setup_wizard_bar_expandable">
1284 + <?php if ( ! empty( $secondary_action_url ) && ! empty( $secondary_action_label ) ) { ?>
1285 + <a class="button button-secondary wpbc_setup_wizard_secondary_action"
1286 + href="<?php echo esc_url( $secondary_action_url ); ?>"><?php echo esc_html( $secondary_action_label ); ?></a>
1287 + <?php } ?>
1181 1288 <?php if ( ! empty( $prior_url ) ) { ?>
1182 1289 <a href="<?php echo esc_url( $prior_url ); ?>" class="button button-secondary"><?php esc_html_e( 'Back', 'booking' ); ?></a>
1183 1290 <?php } ?>
1184 1291 <a href="<?php echo esc_url( $continue_href ); ?>"
@@ -1207,10 +1314,13 @@
1207 1314 var saveBehavior = $bar.attr( 'data-wpbc-setup-save-behavior' ) || '';
1208 1315 var selector = $bar.attr( 'data-wpbc-setup-target-selector' ) || '';
1209 1316 var scrollSelector = $bar.attr( 'data-wpbc-setup-scroll-selector' ) || selector;
1210 1317 var highlightSelector = $bar.attr( 'data-wpbc-setup-highlight-selector' ) || selector;
1318 + var highlightDisabled = ( '1' === ( $bar.attr( 'data-wpbc-setup-highlight-disabled' ) || '' ) );
1319 + var highlightAll = ( '1' === ( $bar.attr( 'data-wpbc-setup-highlight-all' ) || '' ) );
1211 1320 var formSelector = $bar.attr( 'data-wpbc-setup-form-selector' ) || '';
1212 1321 var saveSelector = $bar.attr( 'data-wpbc-setup-save-selector' ) || '';
1322 + var saveAjaxAction = $bar.attr( 'data-wpbc-setup-save-ajax-action' ) || '';
1213 1323 var saveEvents = ( $bar.attr( 'data-wpbc-setup-save-events' ) || '' ).split( ',' );
1214 1324 var openAction = $bar.attr( 'data-wpbc-setup-open-action' ) || '';
1215 1325 var ajaxUrl = $bar.attr( 'data-wpbc-setup-ajax-url' ) || '';
1216 1326 var nonce = $bar.attr( 'data-wpbc-setup-mark-saved-nonce' ) || '';
@@ -1217,8 +1327,11 @@
1217 1327 var $continueButton = $bar.find( '.wpbc_setup_wizard_continue_button' ).first();
1218 1328 var $note = $bar.find( '.wpbc_page_top__wizard_button_note' ).first();
1219 1329 var savedNote = '<?php echo esc_js( __( 'Changes saved. You can continue.', 'booking' ) ); ?>';
1220 1330 var saveRequiredNote = <?php echo wp_json_encode( wp_kses_post( $save_required_note ) ); ?>;
1331 + var continueTitle = <?php echo wp_json_encode( ( 'complete' === $save_behavior ) ? __( 'Finish Setup', 'booking' ) : __( 'Continue', 'booking' ) ); ?>;
1332 + var saveAndContinueTitle = <?php echo wp_json_encode( __( 'Save and Continue', 'booking' ) ); ?>;
1333 + var savingTitle = <?php echo wp_json_encode( __( 'Saving', 'booking' ) . '...' ); ?>;
1221 1334 var $toggleButton = $bar.find( '.wpbc_setup_wizard_bar_toggle_button' ).first();
1222 1335 var $toggleIcon = $toggleButton.find( 'i' ).first();
1223 1336 var $resetButton = $bar.find( '.wpbc_setup_wizard_bar_reset_button' ).first();
1224 1337 var $dragHandle = $bar.find( '.wpbc_setup_wizard_bar_drag_handle' ).first();
@@ -1226,9 +1339,12 @@
1226 1339 var collapsedStorageKey = 'wpbc_setup_wizard_bar_collapsed';
1227 1340 var collapseLabel = <?php echo wp_json_encode( __( 'Collapse setup bar', 'booking' ) ); ?>;
1228 1341 var expandLabel = <?php echo wp_json_encode( __( 'Expand setup bar', 'booking' ) ); ?>;
1229 1342 var $target;
1343 + var $highlightTargets = jQuery();
1230 1344 var saveClicked = false;
1345 + var saveAndContinueRequested = false;
1346 + var saveAndContinueRedirecting = false;
1231 1347
1232 1348 function wpbcSetupWizardStorageGet( key ) {
1233 1349 try {
1234 1350 return window.localStorage.getItem( key );
@@ -1306,9 +1422,10 @@
1306 1422 return -1 !== jQuery.inArray( step, [
1307 1423 'date_selection',
1308 1424 'changeover_days',
1309 1425 'working_time',
1310 - 'time_slots_availability'
1426 + 'time_slots_availability',
1427 + 'date_availability'
1311 1428 ] );
1312 1429 }
1313 1430
1314 1431 function wpbcSetupWizardGetRightSidebarOffset() {
@@ -1353,9 +1470,13 @@
1353 1470 wpbcSetupWizardApplyPosition( null );
1354 1471 return;
1355 1472 }
1356 1473
1474 + // Clear any visible inspector while retaining the minimum offset used by the Days Availability page.
1357 1475 rightOffset = wpbcSetupWizardGetRightSidebarOffset();
1476 + if ( 'date_availability' === step ) {
1477 + rightOffset = Math.max( rightOffset, 60 );
1478 + }
1358 1479 maxRight = Math.max( 15, jQuery( window ).width() - barWidth - 10 );
1359 1480
1360 1481 if ( wpbcSetupWizardShouldUseTopDefault() ) {
1361 1482 $bar
@@ -1396,8 +1517,11 @@
1396 1517 }
1397 1518
1398 1519 function wpbcSetupWizardApplySavedPosition() {
1399 1520 var savedPosition = wpbcSetupWizardStorageGet( positionStorageKey );
1521 + var rightSidebarOffset;
1522 + var barRect;
1523 + var sidebarLeft;
1400 1524
1401 1525 if ( ! savedPosition ) {
1402 1526 wpbcSetupWizardApplyDefaultPosition();
1403 1527 return;
@@ -1407,9 +1531,20 @@
1407 1531 wpbcSetupWizardApplyPosition( JSON.parse( savedPosition ) );
1408 1532 } catch ( _e ) {
1409 1533 wpbcSetupWizardStorageRemove( positionStorageKey );
1410 1534 wpbcSetupWizardApplyDefaultPosition();
1535 + return;
1411 1536 }
1537 +
1538 + rightSidebarOffset = wpbcSetupWizardGetRightSidebarOffset();
1539 + if ( 'service_provider' === step && rightSidebarOffset > 15 ) {
1540 + barRect = $bar[0].getBoundingClientRect();
1541 + sidebarLeft = jQuery( window ).width() - rightSidebarOffset + 15;
1542 +
1543 + if ( barRect.right > ( sidebarLeft - 10 ) ) {
1544 + wpbcSetupWizardApplyDefaultPosition();
1545 + }
1546 + }
1412 1547 }
1413 1548
1414 1549 function wpbcSetupWizardResetPosition() {
1415 1550 wpbcSetupWizardStorageRemove( positionStorageKey );
@@ -1422,10 +1557,10 @@
1422 1557 .attr( 'aria-expanded', isCollapsed ? 'false' : 'true' )
1423 1558 .attr( 'title', isCollapsed ? expandLabel : collapseLabel )
1424 1559 .attr( 'aria-label', isCollapsed ? expandLabel : collapseLabel );
1425 1560 $toggleIcon
1426 - .toggleClass( 'wpbc_icn_expand_less', ! isCollapsed )
1427 - .toggleClass( 'wpbc_icn_expand_more', !! isCollapsed );
1561 + .toggleClass( 'wpbc_icn_minimize', ! isCollapsed )
1562 + .toggleClass( 'wpbc_icn_fullscreen', !! isCollapsed );
1428 1563 wpbcSetupWizardStorageSet( collapsedStorageKey, isCollapsed ? '1' : '0' );
1429 1564 wpbcSetupWizardApplySavedPosition();
1430 1565 }
1431 1566
@@ -1480,11 +1615,16 @@
1480 1615 wpbcSetupWizardApplySavedPosition();
1481 1616 setTimeout( wpbcSetupWizardApplySavedPosition, 400 );
1482 1617 setTimeout( wpbcSetupWizardApplySavedPosition, 1000 );
1483 1618 jQuery( window ).on( 'resize.wpbc_setup_wizard_bar', wpbcSetupWizardApplySavedPosition );
1619 + jQuery( document ).on( 'wpbc_setup_wizard_layout_changed.wpbc_setup_wizard_bar', wpbcSetupWizardApplySavedPosition );
1484 1620
1485 1621 function wpbcSetupWizardOpenPublishArea() {
1486 - var isResourcesPage = -1 !== window.location.href.indexOf( 'page=wpbc-resources' );
1622 + var currentUrl = new window.URL( window.location.href );
1623 + var currentResourcesTab = currentUrl.searchParams.get( 'tab' ) || '';
1624 + var isResourcesPage = 'wpbc-resources' === currentUrl.searchParams.get( 'page' )
1625 + && ( '' === currentResourcesTab || 'resources' === currentResourcesTab );
1626 + var catalogMount = document.getElementById( 'wpbc_catalog_booking_resources' );
1487 1627 var publishTabSelectors = [
1488 1628 '.wpdvlp-sub-tabs .nav-tab',
1489 1629 '.wpdvlp-top-tabs .nav-tab',
1490 1630 '.wpbc_settings_navigation_item a',
@@ -1502,23 +1642,90 @@
1502 1642 'button.button'
1503 1643 ].join( ',' );
1504 1644 var publishTargetSelector = [
1505 1645 '.wpbc_resources_table .ui_group__publish_btn:visible',
1646 + '#wpbc_booking_resource_table .ui_group__publish_btn:visible',
1506 1647 '.wpbc_resource_field__switchable.wpbc_resource_field__publish:visible',
1507 1648 '.wpbc_resource_field__publish:visible',
1508 1649 '.wpbc_resource_publish:visible',
1509 1650 '.wpbc_publish_resources:visible',
1510 - '.wpbc_resource_shortcode:visible',
1511 - '[data-wpbc-resource-publish]:visible',
1512 - '#wpbc_booking_resource_table:visible'
1651 + '[data-wpbc-resource-publish]:visible'
1513 1652 ].join( ',' );
1514 1653 var $publishTab;
1515 1654 var $publishToggle;
1516 1655
1517 - if ( ( 'wizard_publish' !== step && 'publish_area' !== openAction ) || ! isResourcesPage ) {
1656 + if ( 'wizard_publish' !== step || ! isResourcesPage ) {
1518 1657 return;
1519 1658 }
1520 1659
1660 + if ( 'catalog_publish' === openAction && catalogMount ) {
1661 + var catalogPublishRequested = false;
1662 + /**
1663 + * Open the first authorized Resource at its publishing inspector section.
1664 + *
1665 + * @param {CustomEvent|null} renderEvent Shared catalog render event.
1666 + * @return {void}
1667 + */
1668 + var openCatalogPublishing = function( renderEvent ) {
1669 + var catalogResponse = renderEvent && renderEvent.detail ? renderEvent.detail.response : null;
1670 + var publishAction = catalogMount.querySelector( '[data-wpbc-booking-resource-action="publish_resource"][data-wpbc-booking-resource-id]' );
1671 + var resourceId = publishAction ? Number( publishAction.getAttribute( 'data-wpbc-booking-resource-id' ) || 0 ) : 0;
1672 +
1673 + if ( ! resourceId && catalogResponse && Array.isArray( catalogResponse.items ) ) {
1674 + catalogResponse.items.some( function( resource ) {
1675 + var isPublishAuthorized = Array.isArray( resource.action_items ) && resource.action_items.some( function( resourceAction ) {
1676 + return resourceAction && 'publish_resource' === resourceAction.id;
1677 + } );
1678 +
1679 + if ( ! isPublishAuthorized ) {
1680 + return false;
1681 + }
1682 +
1683 + resourceId = Number( resource.id || 0 );
1684 + return 0 < resourceId;
1685 + } );
1686 + }
1687 + if ( catalogPublishRequested || ! resourceId ) {
1688 + return;
1689 + }
1690 +
1691 + catalogPublishRequested = true;
1692 + catalogMount.removeEventListener( 'wpbc:ui-catalog-rendered', openCatalogPublishing );
1693 +
1694 + // Defer until the domain catalog has completed its synchronous mount listeners.
1695 + window.setTimeout( function() {
1696 + var resourceActionEvent;
1697 +
1698 + if ( 'function' === typeof window.CustomEvent ) {
1699 + resourceActionEvent = new window.CustomEvent( 'wpbc:booking-resource-action', {
1700 + bubbles: false,
1701 + detail: {
1702 + action: 'publish_resource',
1703 + resource_id: resourceId,
1704 + source: 'setup_wizard'
1705 + }
1706 + } );
1707 + } else {
1708 + resourceActionEvent = document.createEvent( 'CustomEvent' );
1709 + resourceActionEvent.initCustomEvent( 'wpbc:booking-resource-action', false, false, {
1710 + action: 'publish_resource',
1711 + resource_id: resourceId,
1712 + source: 'setup_wizard'
1713 + } );
1714 + }
1715 + document.dispatchEvent( resourceActionEvent );
1716 + }, 0 );
1717 + };
1718 +
1719 + catalogMount.addEventListener( 'wpbc:ui-catalog-rendered', openCatalogPublishing );
1720 + openCatalogPublishing( null );
1721 + return;
1722 + }
1723 +
1724 + if ( 'publish_area' !== openAction ) {
1725 + return;
1726 + }
1727 +
1521 1728 $publishTab = jQuery( publishTabSelectors ).filter( ':visible' ).filter( function() {
1522 1729 var $element = jQuery( this );
1523 1730 var text = $element.text() || '';
1524 1731 var href = $element.attr( 'href' ) || '';
@@ -1707,9 +1914,10 @@
1707 1914 $bar.attr( 'data-wpbc-setup-is-saved', '1' );
1708 1915 $continueButton
1709 1916 .removeClass( 'disabled' )
1710 1917 .removeAttr( 'aria-disabled' )
1711 - .attr( 'href', $continueButton.attr( 'data-wpbc-setup-continue-url' ) || '#' );
1918 + .attr( 'href', $continueButton.attr( 'data-wpbc-setup-continue-url' ) || '#' )
1919 + .text( continueTitle );
1712 1920 if ( $note.length ) {
1713 1921 $note
1714 1922 .addClass( 'wpbc_setup_wizard_bar_note_saved' )
1715 1923 .text( savedNote );
@@ -1717,12 +1925,14 @@
1717 1925 }
1718 1926
1719 1927 function wpbcSetupWizardSetUnsaved() {
1720 1928 $bar.attr( 'data-wpbc-setup-is-saved', '0' );
1721 - $continueButton
1722 - .addClass( 'disabled' )
1723 - .attr( 'aria-disabled', 'true' )
1724 - .attr( 'href', '#wpbc_setup_save_required' );
1929 + $continueButton.attr( 'href', '#wpbc_setup_save_required' ).text( saveSelector ? saveAndContinueTitle : continueTitle );
1930 + if ( saveSelector ) {
1931 + $continueButton.removeClass( 'disabled' ).removeAttr( 'aria-disabled' );
1932 + } else {
1933 + $continueButton.addClass( 'disabled' ).attr( 'aria-disabled', 'true' );
1934 + }
1725 1935 if ( $note.length ) {
1726 1936 $note
1727 1937 .removeClass( 'wpbc_setup_wizard_bar_note_saved' )
1728 1938 .html( saveRequiredNote );
@@ -1728,11 +1938,48 @@
1728 1938 .html( saveRequiredNote );
1729 1939 }
1730 1940 }
1731 1941
1732 - function wpbcSetupWizardMarkSaved() {
1942 + function wpbcSetupWizardSetSaveAndContinueBusy( isBusy ) {
1943 + if ( ! saveSelector ) {
1944 + return;
1945 + }
1946 +
1947 + $continueButton.toggleClass( 'disabled', !! isBusy ).text( isBusy ? savingTitle : saveAndContinueTitle );
1948 + if ( isBusy ) {
1949 + $continueButton.attr( 'aria-disabled', 'true' );
1950 + } else {
1951 + $continueButton.removeAttr( 'aria-disabled' );
1952 + }
1953 + }
1954 +
1955 + function wpbcSetupWizardGetContinueUrl() {
1956 + return $continueButton.attr( 'data-wpbc-setup-continue-url' ) || $continueButton.attr( 'href' ) || '';
1957 + }
1958 +
1959 + function wpbcSetupWizardContinueAfterSave() {
1960 + var continueUrl;
1961 +
1962 + if ( saveAndContinueRedirecting ) {
1963 + return;
1964 + }
1965 +
1966 + continueUrl = wpbcSetupWizardGetContinueUrl();
1967 + if ( ! continueUrl || '#wpbc_setup_save_required' === continueUrl ) {
1968 + wpbcSetupWizardSetSaveAndContinueBusy( false );
1969 + return;
1970 + }
1971 +
1972 + saveAndContinueRedirecting = true;
1973 + window.location.href = continueUrl;
1974 + }
1975 +
1976 + function wpbcSetupWizardMarkSaved( afterSavedCallback ) {
1733 1977 if ( ! step || ! ajaxUrl || ! nonce ) {
1734 1978 wpbcSetupWizardSetSaved();
1979 + if ( 'function' === typeof afterSavedCallback ) {
1980 + afterSavedCallback();
1981 + }
1735 1982 return;
1736 1983 }
1737 1984
1738 1985 jQuery.post( ajaxUrl, {
@@ -1746,9 +1993,17 @@
1746 1993 } catch ( _e ) {}
1747 1994 }
1748 1995 if ( response && response.success ) {
1749 1996 wpbcSetupWizardSetSaved();
1997 + if ( 'function' === typeof afterSavedCallback ) {
1998 + afterSavedCallback();
1999 + }
1750 2000 }
2001 + } ).fail( function() {
2002 + if ( saveAndContinueRequested ) {
2003 + wpbcSetupWizardSetSaveAndContinueBusy( false );
2004 + saveAndContinueRequested = false;
2005 + }
1751 2006 } );
1752 2007 }
1753 2008
1754 2009 function wpbcSetupWizardSaveStarted() {
@@ -1756,9 +2011,9 @@
1756 2011 }
1757 2012
1758 2013 function wpbcSetupWizardLooksSuccessfulResponse( response ) {
1759 2014 if ( ! response ) {
1760 - return true;
2015 + return false;
1761 2016 }
1762 2017
1763 2018 return (
1764 2019 !! response.success
@@ -1768,8 +2023,54 @@
1768 2023 || ( response.data && response.data.setup_step_saved )
1769 2024 );
1770 2025 }
1771 2026
2027 + function wpbcSetupWizardGetAjaxAction( ajaxSettings ) {
2028 + var data = ajaxSettings && ajaxSettings.data ? ajaxSettings.data : '';
2029 + var matches;
2030 +
2031 + if ( ! data ) {
2032 + return '';
2033 + }
2034 +
2035 + if ( 'string' === typeof data ) {
2036 + matches = data.match( /(?:^|&)action=([^&]+)/ );
2037 + return matches && matches[1] ? decodeURIComponent( matches[1].replace( /\+/g, ' ' ) ) : '';
2038 + }
2039 +
2040 + if ( window.FormData && data instanceof window.FormData && 'function' === typeof data.get ) {
2041 + return data.get( 'action' ) || '';
2042 + }
2043 +
2044 + if ( 'object' === typeof data && data.action ) {
2045 + return data.action;
2046 + }
2047 +
2048 + return '';
2049 + }
2050 +
2051 + function wpbcSetupWizardIsExpectedSaveAjax( ajaxSettings ) {
2052 + var ajaxAction;
2053 +
2054 + if ( ! saveAjaxAction ) {
2055 + return true;
2056 + }
2057 +
2058 + ajaxAction = wpbcSetupWizardGetAjaxAction( ajaxSettings );
2059 +
2060 + return saveAjaxAction === ajaxAction;
2061 + }
2062 +
2063 + function wpbcSetupWizardHandleSavedEvent() {
2064 + saveClicked = false;
2065 + wpbcSetupWizardSetSaved();
2066 + if ( saveAndContinueRequested ) {
2067 + wpbcSetupWizardMarkSaved( wpbcSetupWizardContinueAfterSave );
2068 + return;
2069 + }
2070 + wpbcSetupWizardMarkSaved();
2071 + }
2072 +
1772 2073 function wpbcSetupWizardRegisterSavedEvent( eventName ) {
1773 2074 eventName = ( eventName || '' ).replace( /^\s+|\s+$/g, '' );
1774 2075 if ( ! eventName ) {
1775 2076 return;
@@ -1774,14 +2075,55 @@
1774 2075 if ( ! eventName ) {
1775 2076 return;
1776 2077 }
1777 2078
1778 - document.addEventListener( eventName, function() {
1779 - wpbcSetupWizardSetSaved();
1780 - wpbcSetupWizardMarkSaved();
1781 - }, true );
2079 + document.addEventListener( eventName, wpbcSetupWizardHandleSavedEvent, true );
2080 + jQuery( document ).on( eventName + '.wpbc_setup_wizard', wpbcSetupWizardHandleSavedEvent );
1782 2081 }
1783 2082
2083 + function wpbcSetupWizardFindSaveControl() {
2084 + var $saveControl = wpbcSetupWizardGetFirstElement( saveSelector );
2085 +
2086 + if ( $saveControl.length ) {
2087 + return $saveControl;
2088 + }
2089 +
2090 + if ( ! formSelector ) {
2091 + return jQuery();
2092 + }
2093 +
2094 + return wpbcSetupWizardGetFirstElement(
2095 + formSelector + ' button[type="submit"],' +
2096 + formSelector + ' input[type="submit"],' +
2097 + formSelector + ' .wpbc_submit_button_trigger,' +
2098 + formSelector + ' .wpbc_submit_button'
2099 + );
2100 + }
2101 +
2102 + function wpbcSetupWizardTriggerSaveAndContinue() {
2103 + var $saveControl = wpbcSetupWizardFindSaveControl();
2104 +
2105 + if ( saveAndContinueRequested ) {
2106 + return;
2107 + }
2108 +
2109 + if ( ! $saveControl.length || $saveControl.hasClass( 'disabled' ) || 'true' === $saveControl.attr( 'aria-disabled' ) ) {
2110 + if ( typeof wpbc_admin_show_message === 'function' ) {
2111 + wpbc_admin_show_message( '<?php echo esc_js( __( 'Please save changes on this page before continuing setup.', 'booking' ) ); ?>', 'warning', 4000, false );
2112 + }
2113 + wpbcSetupWizardPulseSaveRequiredMessage();
2114 + return;
2115 + }
2116 +
2117 + saveAndContinueRequested = true;
2118 + wpbcSetupWizardSaveStarted();
2119 + wpbcSetupWizardSetSaveAndContinueBusy( true );
2120 + if ( formSelector ) {
2121 + jQuery( formSelector ).find( 'input[name="wpbc_setup_continue_after_save"]' ).val( '1' );
2122 + }
2123 + $saveControl.trigger( 'click' );
2124 + }
2125 +
1784 2126 if ( 'manual_save_required' === saveBehavior ) {
1785 2127 window.wpbc_setup_wizard_set_current_step_saved = wpbcSetupWizardSetSaved;
1786 2128 window.wpbc_setup_wizard_mark_current_step_saved = wpbcSetupWizardMarkSaved;
1787 2129
@@ -1791,8 +2133,11 @@
1791 2133 }
1792 2134 wpbcSetupWizardSaveStarted();
1793 2135 event.detail.payload.wpbc_setup = '1';
1794 2136 event.detail.payload.wpbc_setup_step = step;
2137 + if ( saveAndContinueRequested ) {
2138 + event.detail.payload.wpbc_setup_continue_after_save = '1';
2139 + }
1795 2140 }, true );
1796 2141
1797 2142 saveEvents.forEach( wpbcSetupWizardRegisterSavedEvent );
1798 2143
@@ -1810,15 +2155,19 @@
1810 2155 }
1811 2156 if ( ! $form.find( 'input[name="wpbc_setup"]' ).length ) {
1812 2157 $form.append( '<input type="hidden" name="wpbc_setup" value="" />' );
1813 2158 }
2159 + if ( ! $form.find( 'input[name="wpbc_setup_continue_after_save"]' ).length ) {
2160 + $form.append( '<input type="hidden" name="wpbc_setup_continue_after_save" value="" />' );
2161 + }
1814 2162 $form.find( 'input[name="wpbc_setup_saved_step"]' ).val( step );
1815 2163 $form.find( 'input[name="wpbc_setup_step"]' ).val( step );
1816 2164 $form.find( 'input[name="wpbc_setup"]' ).val( '1' );
2165 + $form.find( 'input[name="wpbc_setup_continue_after_save"]' ).val( '0' );
1817 2166 $form
1818 2167 .off( 'change.wpbc_setup_wizard input.wpbc_setup_wizard', ':input' )
1819 2168 .on( 'change.wpbc_setup_wizard input.wpbc_setup_wizard', ':input', function() {
1820 - if ( jQuery( this ).is( '[name="wpbc_setup_saved_step"],[name="wpbc_setup_step"],[name="wpbc_setup"],[name="form_visible_section"]' ) ) {
2169 + if ( jQuery( this ).is( '[name="wpbc_setup_saved_step"],[name="wpbc_setup_step"],[name="wpbc_setup"],[name="wpbc_setup_continue_after_save"],[name="form_visible_section"]' ) ) {
1821 2170 return;
1822 2171 }
1823 2172 wpbcSetupWizardSetUnsaved();
1824 2173 } );
@@ -1828,8 +2177,9 @@
1828 2177 wpbcSetupWizardSaveStarted();
1829 2178 $form.find( 'input[name="wpbc_setup_saved_step"]' ).val( step );
1830 2179 $form.find( 'input[name="wpbc_setup_step"]' ).val( step );
1831 2180 $form.find( 'input[name="wpbc_setup"]' ).val( '1' );
2181 + $form.find( 'input[name="wpbc_setup_continue_after_save"]' ).val( saveAndContinueRequested ? '1' : '0' );
1832 2182 } );
1833 2183 } );
1834 2184 }
1835 2185
@@ -1835,8 +2185,12 @@
1835 2185
1836 2186 $continueButton.on( 'click', function( event ) {
1837 2187 if ( '1' !== $bar.attr( 'data-wpbc-setup-is-saved' ) ) {
1838 2188 event.preventDefault();
2189 + if ( saveSelector ) {
2190 + wpbcSetupWizardTriggerSaveAndContinue();
2191 + return;
2192 + }
1839 2193 if ( typeof wpbc_admin_show_message === 'function' ) {
1840 2194 wpbc_admin_show_message( '<?php echo esc_js( __( 'Please save changes on this page before continuing setup.', 'booking' ) ); ?>', 'warning', 4000, false );
1841 2195 }
1842 2196 wpbcSetupWizardPulseSaveRequiredMessage();
@@ -1852,13 +2206,16 @@
1852 2206 }
1853 2207 } );
1854 2208 }
1855 2209
1856 - jQuery( document ).ajaxComplete( function( _event, xhr ) {
2210 + jQuery( document ).ajaxComplete( function( _event, xhr, ajaxSettings ) {
1857 2211 var response;
1858 2212 if ( ! saveClicked ) {
1859 2213 return;
1860 2214 }
2215 + if ( ! wpbcSetupWizardIsExpectedSaveAjax( ajaxSettings ) ) {
2216 + return;
2217 + }
1861 2218 saveClicked = false;
1862 2219
1863 2220 response = xhr && xhr.responseJSON ? xhr.responseJSON : null;
1864 2221 if ( ! response && xhr && xhr.responseText ) {
@@ -1867,25 +2224,51 @@
1867 2224 } catch ( _e ) {}
1868 2225 }
1869 2226 if ( response && response.data && response.data.setup_step_saved ) {
1870 2227 wpbcSetupWizardSetSaved();
2228 + if ( saveAndContinueRequested ) {
2229 + wpbcSetupWizardContinueAfterSave();
2230 + }
1871 2231 } else if ( wpbcSetupWizardLooksSuccessfulResponse( response ) ) {
1872 - wpbcSetupWizardMarkSaved();
2232 + if ( saveAndContinueRequested ) {
2233 + wpbcSetupWizardMarkSaved( wpbcSetupWizardContinueAfterSave );
2234 + } else {
2235 + wpbcSetupWizardMarkSaved();
2236 + }
2237 + } else if ( saveAndContinueRequested ) {
2238 + wpbcSetupWizardSetSaveAndContinueBusy( false );
2239 + saveAndContinueRequested = false;
1873 2240 }
1874 2241 } );
1875 2242 }
1876 2243
2244 + if ( highlightDisabled ) {
2245 + highlightSelector = '';
2246 + }
2247 +
1877 2248 if ( ! selector && ! scrollSelector && ! highlightSelector ) {
1878 2249 return;
1879 2250 }
1880 2251
1881 - $target = wpbcSetupWizardGetFirstElement( highlightSelector || selector );
1882 - if ( $target.length ) {
1883 - wpbcSetupWizardHighlightElement( $target );
2252 + if ( ! highlightDisabled && highlightAll ) {
2253 + try {
2254 + $highlightTargets = jQuery( highlightSelector || selector ).filter( ':visible' );
2255 + } catch ( _e ) {
2256 + $highlightTargets = jQuery();
2257 + }
2258 +
2259 + $highlightTargets.each( function() {
2260 + wpbcSetupWizardHighlightElement( jQuery( this ) );
2261 + } );
2262 + } else if ( ! highlightDisabled ) {
2263 + $highlightTargets = wpbcSetupWizardGetFirstElement( highlightSelector || selector );
2264 + wpbcSetupWizardHighlightElement( $highlightTargets );
1884 2265 }
1885 2266
2267 + $target = $highlightTargets.first();
2268 +
1886 2269 setTimeout( function() {
1887 - var $scrollTarget = wpbcSetupWizardGetFirstElement( scrollSelector || highlightSelector || selector );
2270 + var $scrollTarget = wpbcSetupWizardGetFirstElement( scrollSelector || ( highlightDisabled ? selector : highlightSelector ) || selector );
1888 2271 if ( ! $scrollTarget.length ) {
1889 2272 $scrollTarget = $target;
1890 2273 }
1891 2274 wpbcSetupWizardScrollToElement( $scrollTarget );