PluginProbe
Booking Calendar / 11.9
Booking Calendar v11.9
11.9 11.8.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 All 205 releases
← All changes | core/wpbc-activation.php +218 -14 11.4.3 → 11.9 View file →
@@ -13,8 +13,59 @@
13 13
14 14 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
15 15
16 16
17 +/**
18 + * Evaluate whether the current activation starts from a genuinely empty install.
19 + *
20 + * Both signals are required. A missing version option by itself is not reliable,
21 + * because older installations or interrupted upgrades can still have Booking
22 + * Calendar tables. A missing table by itself is also insufficient when stored
23 + * installation metadata remains.
24 + *
25 + * @param mixed $stored_version Stored Booking Calendar version, or false when absent.
26 + * @param bool $booking_table_exists Whether the canonical booking table exists.
27 + *
28 + * @return bool True only when neither installation signal exists.
29 + */
30 +function wpbc_is_plugin_initial_install_state( $stored_version, $booking_table_exists ) {
31 +
32 + return ( false === $stored_version ) && ! (bool) $booking_table_exists;
33 +}
34 +
35 +
36 +/**
37 + * Check whether the active activation request is a genuine first installation.
38 + *
39 + * The result is cached before activation creates tables or saves
40 + * `booking_version_num`, allowing later activation callbacks to consume the same
41 + * immutable request-scoped decision. For later administration requests, use the
42 + * persisted first-install marker owned by the Setup Wizard instead.
43 + *
44 + * @return bool True during a genuine first-install activation; otherwise false.
45 + */
46 +function wpbc_is_plugin_initial_install() {
47 +
48 + static $is_initial_install = null;
49 +
50 + if ( null !== $is_initial_install ) {
51 + return $is_initial_install;
52 + }
53 +
54 + if ( ! function_exists( 'wpbc_is_table_exists' ) ) {
55 + $is_initial_install = false;
56 + return $is_initial_install;
57 + }
58 +
59 + $is_initial_install = wpbc_is_plugin_initial_install_state(
60 + get_option( 'booking_version_num', false ),
61 + wpbc_is_table_exists( 'booking' )
62 + );
63 +
64 + return $is_initial_install;
65 +}
66 +
67 +
17 68 /** Activation & Deactivation of Booking Calendar */
18 69 class WPBC_BookingInstall extends WPBC_Install {
19 70
20 71 /**
@@ -72,8 +123,11 @@
72 123 // FixIn: 9.9.0.13.
73 124 if ( ( ! $is_make_activation ) && ( class_exists( 'wpdev_bk_biz_m' ) ) && ( ! wpbc_is_table_exists( 'booking_seasons' ) ) ) {
74 125 $is_make_activation = true;
75 126 }
127 + if ( ( ! $is_make_activation ) && ( class_exists( 'wpdev_bk_biz_m' ) ) && ( wpbc_is_field_in_table_exists( 'booking_seasons', 'season_color' ) == 0 ) ) {
128 + $is_make_activation = true;
129 + }
76 130 if ( ( ! $is_make_activation ) && ( class_exists( 'wpdev_bk_biz_l' ) ) && ( ! wpbc_is_table_exists( 'booking_coupons' ) ) ) {
77 131 $is_make_activation = true;
78 132 }
79 133 if ( ( ! $is_make_activation ) && ( class_exists( 'wpdev_bk_multiuser' ) ) && ( wpbc_is_field_in_table_exists( 'booking_coupons', 'users' ) == 0 ) ) {
@@ -187,8 +241,10 @@
187 241 function wpbc_booking_activate() {
188 242
189 243 wpbc_load_translation();
190 244
245 + $is_new_install = wpbc_is_plugin_initial_install();
246 +
191 247 make_bk_action( 'wpbc_before_activation' );
192 248
193 249
194 250
@@ -197,9 +253,19 @@
197 253
198 254 // -----------------------------------------------------------------------------------------------------------------
199 255 // Options
200 256 // -----------------------------------------------------------------------------------------------------------------
201 - $default_options_to_add = wpbc_get_default_options();
257 + $default_options_to_add = wpbc_get_default_options();
258 + // Existing installations retain their saved value; add_bk_option() never overwrites it during upgrades.
259 + if ( $is_new_install ) {
260 + $default_options_to_add['booking_form_accent_enabled'] = 'On';
261 + $default_options_to_add['booking_setup_wizard_initial_install'] = 'On';
262 + $default_options_to_add['booking_setup_wizard_first_run_prompt'] = 'On';
263 + $default_options_to_add['booking_setup_wizard_booking_pages_prompt'] = 'On';
264 + if ( ! class_exists( 'wpdev_bk_personal' ) ) {
265 + $default_options_to_add['booking_resources_catalog_default_view'] = 'publishing';
266 + }
267 + }
202 268 // TODO: for Import / Export options, we can use this function to get all option_names and then just get the real values from the wp_options table.
203 269 make_bk_action( 'wpbc_before_activation__add_options', $default_options_to_add ); // FixIn: 9.6.2.11.
204 270
205 271 foreach ( $default_options_to_add as $default_option_name => $default_option_value ) {
@@ -321,9 +387,13 @@
321 387 $sql_check_table = "SELECT booking_id as id FROM {$wpdb->prefix}booking ORDER BY booking_id DESC LIMIT 0, 100";
322 388
323 389 $res = $wpdb->get_results( $sql_check_table ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
324 390 foreach ( $res as $l ) {
325 - $wp_queries[] = "UPDATE {$wpdb->prefix}booking SET hash = MD5('" . time() . '_' . wp_rand( 1000, 1000000 ) . "') WHERE booking_id = " . $l->id; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
391 + $wp_queries[] = $wpdb->prepare(
392 + "UPDATE {$wpdb->prefix}booking SET hash = %s WHERE booking_id = %d",
393 + wpbc_hash__generate_booking_hash(),
394 + $l->id
395 + ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
326 396 }
327 397 }
328 398 }
329 399
@@ -377,9 +447,9 @@
377 447 if ( $is_insert_test_bookings ) {
378 448 // -- Test Booking #1 --
379 449 $is_appr = 1;
380 450 $wp_queries_sub = "INSERT INTO {$wpdb->prefix}booking ( form, modification_date ) VALUES (
381 - 'text^name1^John~text^secondname1^Smith~text^email1^[email protected]~text^phone1^458-77-77~textarea^details1^This is a test booking showing booking for several days.', " . wpbc_sql_date_math_expr_explicit('', 'now') . " );";
451 + 'text^firstname1^John~text^secondname1^Smith~text^email1^[email protected]~text^phone1^458-77-77~textarea^details1^This is a test booking showing booking for several days.', " . wpbc_sql_date_math_expr_explicit('', 'now') . " );";
382 452 $wpdb->query( $wp_queries_sub ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
383 453
384 454 $temp_id = $wpdb->insert_id;
385 455 $wp_queries_sub = "INSERT INTO {$wpdb->prefix}bookingdates ( booking_id, booking_date, approved ) VALUES
@@ -390,9 +460,9 @@
390 460
391 461 // -- Test Booking #2 --
392 462 $is_appr = 0;
393 463 $wp_queries_sub = "INSERT INTO {$wpdb->prefix}booking ( form, modification_date ) VALUES (
394 - 'text^name1^Emma~text^secondname1^Robinson~text^email1^[email protected]~text^phone1^999-77-77~textarea^details1^This is a test booking showing booking for several days.', " . wpbc_sql_date_math_expr_explicit('', 'now') . " );";
464 + 'text^firstname1^Emma~text^secondname1^Robinson~text^email1^[email protected]~text^phone1^999-77-77~textarea^details1^This is a test booking showing booking for several days.', " . wpbc_sql_date_math_expr_explicit('', 'now') . " );";
395 465 $wpdb->query( $wp_queries_sub ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
396 466
397 467 $temp_id = $wpdb->insert_id;
398 468 $wp_queries_sub = "INSERT INTO {$wpdb->prefix}bookingdates ( booking_id, booking_date, approved ) VALUES
@@ -406,9 +476,9 @@
406 476 $is_appr = 1;
407 477 $start_time = '10:00';
408 478 $end_time = '10:30';
409 479 $wp_queries_sub = "INSERT INTO {$wpdb->prefix}booking ( form, modification_date, is_new ) VALUES (
410 - 'selectbox^rangetime1^".$start_time." - ".$end_time."~text^name1^Sophia~text^secondname1^Robinson~text^email1^[email protected]~text^phone1^458-77-77~textarea^details1^This is a test booking showing a one day time slot booking.', " . wpbc_sql_date_math_expr_explicit('', 'now') . ", 0 );";
480 + 'selectbox^rangetime1^".$start_time." - ".$end_time."~text^firstname1^Sophia~text^secondname1^Robinson~text^email1^[email protected]~text^phone1^458-77-77~textarea^details1^This is a test booking showing a one day time slot booking.', " . wpbc_sql_date_math_expr_explicit('', 'now') . ", 0 );";
411 481 $wpdb->query( $wp_queries_sub ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
412 482
413 483 $temp_id = $wpdb->insert_id;
414 484
@@ -440,9 +510,94 @@
440 510 }
441 511 add_bk_action( 'wpbc_activation', 'wpbc_booking_activate' );
442 512
443 513
514 +/**
515 + * Determine whether the commercial registration data must survive full data removal.
516 + *
517 + * Demo sites need to retain the validated commercial registration payload so that
518 + * resetting demo booking data does not expose the order-number registration form.
519 + * Requiring both the established demo check and the official domain prevents this
520 + * exception from changing cleanup behavior on customer, local, or beta websites.
521 + *
522 + * @return bool True when registration data must be preserved; otherwise false.
523 + */
524 +function wpbc_deactivation__should_preserve_registration_data() {
444 525
526 + if ( ! function_exists( 'wpbc_is_this_demo' ) || ! wpbc_is_this_demo() ) {
527 + return false;
528 + }
529 +
530 + $site_host = wp_parse_url( home_url( '/' ), PHP_URL_HOST );
531 +
532 + if ( ! is_string( $site_host ) || '' === $site_host ) {
533 + return false;
534 + }
535 +
536 + $site_host = strtolower( rtrim( $site_host, '.' ) );
537 + $official_demo_host = 'wpbookingcalendar.com';
538 + $official_demo_suffix = '.' . $official_demo_host;
539 +
540 + if ( $official_demo_host === $site_host ) {
541 + return true;
542 + }
543 +
544 + return strlen( $site_host ) > strlen( $official_demo_suffix )
545 + && $official_demo_suffix === substr( $site_host, -strlen( $official_demo_suffix ) );
546 +}
547 +
548 +
549 +/**
550 + * Delete every site option and transient owned by Booking Calendar.
551 + *
552 + * The historical deactivation path deletes options returned by
553 + * wpbc_get_default_options(). Runtime modules also create version markers,
554 + * setup state, caches, and transients outside that registry. This final pass
555 + * runs after all module callbacks so those callbacks can still read their
556 + * settings while removing tables and other data.
557 + *
558 + * @return void
559 + */
560 +function wpbc_deactivation__delete_all_plugin_options() {
561 +
562 + global $wpdb;
563 +
564 + $option_name_patterns = array(
565 + $wpdb->esc_like( 'booking_' ) . '%',
566 + $wpdb->esc_like( 'wpbc_' ) . '%',
567 + $wpdb->esc_like( '_transient_' ) . '%' . $wpdb->esc_like( 'booking_' ) . '%',
568 + $wpdb->esc_like( '_transient_' ) . '%' . $wpdb->esc_like( 'wpbc_' ) . '%',
569 + $wpdb->esc_like( '_site_transient_' ) . '%' . $wpdb->esc_like( 'booking_' ) . '%',
570 + $wpdb->esc_like( '_site_transient_' ) . '%' . $wpdb->esc_like( 'wpbc_' ) . '%',
571 + );
572 +
573 + $sql = $wpdb->prepare(
574 + "SELECT option_name
575 + FROM {$wpdb->options}
576 + WHERE option_name LIKE %s
577 + OR option_name LIKE %s
578 + OR option_name LIKE %s
579 + OR option_name LIKE %s
580 + OR option_name LIKE %s
581 + OR option_name LIKE %s",
582 + $option_name_patterns
583 + );
584 +
585 + // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared
586 + $option_names = $wpdb->get_col( $sql );
587 + $option_names = is_array( $option_names ) ? array_unique( $option_names ) : array();
588 +
589 + if ( ! wpbc_deactivation__should_preserve_registration_data() ) {
590 + $option_names[] = 'bk_version_data';
591 + }
592 +
593 + foreach ( $option_names as $option_name ) {
594 + delete_option( $option_name );
595 + }
596 +}
597 +
598 +
599 +
445 600 // Deactivate.
446 601 function wpbc_booking_deactivate() {
447 602
448 603 // -----------------------------------------------------------------------------------------------------------------
@@ -471,11 +626,18 @@
471 626 $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}booking" );
472 627 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.DirectDatabaseQuery.SchemaChange
473 628 $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}bookingdates" );
474 629
475 - // Delete all users booking windows states.
476 - // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter,
477 - if ( false === $wpdb->query( "DELETE FROM {$wpdb->usermeta} WHERE meta_key LIKE '%booking_%'" ) ) {
630 + // Delete all Booking Calendar user options, listing state, and dismissed notices.
631 + $booking_meta_pattern = '%' . $wpdb->esc_like( 'booking_' ) . '%';
632 + $wpbc_meta_pattern = '%' . $wpdb->esc_like( 'wpbc_' ) . '%';
633 + $user_meta_delete_sql = $wpdb->prepare(
634 + "DELETE FROM {$wpdb->usermeta} WHERE meta_key LIKE %s OR meta_key LIKE %s",
635 + $booking_meta_pattern,
636 + $wpbc_meta_pattern
637 + );
638 + // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
639 + if ( false === $wpdb->query( $user_meta_delete_sql ) ) {
478 640 debuge_error('Error during deleting user meta at DB',__FILE__,__LINE__);
479 641 die();
480 642 }
481 643
@@ -491,8 +653,10 @@
491 653 ////////////////////////////////////////////////////////////////////////////
492 654 // Other versions Deactivation
493 655 ////////////////////////////////////////////////////////////////////////////
494 656 make_bk_action( 'wpbc_other_versions_deactivation' );
657 +
658 + wpbc_deactivation__delete_all_plugin_options();
495 659 }
496 660 add_bk_action( 'wpbc_deactivation', 'wpbc_booking_deactivate' );
497 661
498 662
@@ -515,11 +679,16 @@
515 679
516 680 // If this option here, then system get this option from "Super Admin" options configuration for "Regular" users.
517 681 $mu_option4delete = array();
518 682
519 - // FixIn: 9.6.3.5.
520 - $default_options['booking_setup_wizard_page_steps_is_done'] = '';
521 - $mu_option4delete[]='booking_setup_wizard_page_steps_is_done';
683 + $default_options['booking_setup_wizard_initial_install'] = 'Off';
684 + $mu_option4delete[] = 'booking_setup_wizard_initial_install';
685 + $default_options['booking_setup_wizard_first_run_prompt'] = 'Off';
686 + $mu_option4delete[] = 'booking_setup_wizard_first_run_prompt';
687 + $default_options['booking_setup_wizard_booking_pages_prompt'] = 'Off';
688 + $mu_option4delete[] = 'booking_setup_wizard_booking_pages_prompt';
689 + $default_options['booking_update_navigation_context'] = array();
690 + $mu_option4delete[] = 'booking_update_navigation_context';
522 691
523 692 $default_options['booking_admin_cal_count'] = ($is_demo) ? '3' : '2';
524 693 $mu_option4delete[]='booking_admin_cal_count'; // $multiuser_general_option[] = implode( '', array_keys( array_slice( $default_options, -1 ) ) );
525 694 $default_options['booking_skin'] = '/css/skins/25_5__square_1.css'; // FixIn: 10.11.4.2.
@@ -526,8 +695,12 @@
526 695 $mu_option4delete[]='booking_skin';
527 696 // FixIn: 9.6.3.5.
528 697 $default_options['booking_listing_default_view_mode'] = 'vm_booking_listing'; // 'vm_calendar'; // FixIn: 9.6.3.5.
529 698 $mu_option4delete[]='booking_listing_default_view_mode';
699 + $default_options['booking_admin_edit_booking_mode'] = 'popup';
700 + $mu_option4delete[]='booking_admin_edit_booking_mode';
701 + $default_options['booking_resources_catalog_default_view'] = '';
702 + $mu_option4delete[] = 'booking_resources_catalog_default_view';
530 703
531 704 $default_options['booking_view_days_num'] = ( ( ! class_exists( 'wpdev_bk_personal' ) ) ? '90' : '30' );
532 705 $mu_option4delete[]='booking_view_days_num';
533 706 // FixIn: 8.9.4.3.
@@ -557,9 +730,10 @@
557 730
558 731 // FixIn: 10.13.1.5.
559 732 $default_options['booking_is_use_phone_validation'] = 'Off';
560 733 $mu_option4delete[]='booking_is_use_phone_validation';
561 - $default_options['booking_date_format'] = get_option( 'date_format' );
734 + $wordpress_date_format = get_option( 'date_format' );
735 + $default_options['booking_date_format'] = ( 'F j, Y' === $wordpress_date_format ) ? 'j M Y' : $wordpress_date_format;
562 736 $mu_option4delete[]='booking_date_format';
563 737 $default_options['booking_time_format'] = get_option( 'time_format' ); //'H:i';
564 738 $mu_option4delete[]='booking_time_format';
565 739
@@ -619,9 +793,9 @@
619 793
620 794 // FixIn: 8.7.11.10.
621 795 $default_options['booking_timeslot_picker'] = 'On';
622 796 $mu_option4delete[]= 'booking_timeslot_picker';
623 - $default_options['booking_timeslot_picker_skin'] = '/css/time_picker_skins/light__24_8.css';
797 + $default_options['booking_timeslot_picker_skin'] = '/css/time_picker_skins/form_style.css';
624 798 $mu_option4delete[]= 'booking_timeslot_picker_skin';
625 799
626 800 $default_options['booking_disable_timeslots_in_tooltip'] = 'Off'; //FixIn: 9.5.0.2.2
627 801 $mu_option4delete[]='booking_disable_timeslots_in_tooltip';
@@ -772,8 +946,12 @@
772 946 $default_options['booking_form_theme'] = '';
773 947 $mu_option4delete[]='booking_form_theme';
774 948 $default_options['booking_form_style'] = 'light_bordered';
775 949 $mu_option4delete[]='booking_form_style';
950 + $default_options['booking_form_accent_enabled'] = 'Off';
951 + $mu_option4delete[]='booking_form_accent_enabled';
952 + $default_options['booking_form_accent_color'] = WPBC_DEFAULT_FORM_ACCENT_COLOR;
953 + $mu_option4delete[]='booking_form_accent_color';
776 954 $default_options['booking_form_appearance_preset'] = 'bordered';
777 955 $mu_option4delete[]='booking_form_appearance_preset';
778 956 $default_options['booking_form_appearance_background_color'] = '#ffffff';
779 957 $mu_option4delete[]='booking_form_appearance_background_color';
@@ -828,8 +1006,12 @@
828 1006 $default_options['booking_form_custom_secondary_button_hover_text_color'] = '#444444';
829 1007 $mu_option4delete[]='booking_form_custom_secondary_button_hover_text_color';
830 1008 $default_options['booking_form_custom_secondary_button_hover_border_color'] = '#4d91cd';
831 1009 $mu_option4delete[]='booking_form_custom_secondary_button_hover_border_color';
1010 + $default_options['booking_form_custom_button_border_width'] = '1px';
1011 + $mu_option4delete[]='booking_form_custom_button_border_width';
1012 + $default_options['booking_form_custom_button_border_radius'] = '3px';
1013 + $mu_option4delete[]='booking_form_custom_button_border_radius';
832 1014 $default_options['booking_is_use_captcha'] = 'Off';
833 1015 $mu_option4delete[]='booking_is_use_captcha';
834 1016 $default_options['booking_frontend_messages'] = array( 'version' => 1, 'messages' => array(), 'enabled' => array() );
835 1017 $mu_option4delete[]='booking_frontend_messages';
@@ -880,8 +1062,10 @@
880 1062 $emails_init = array_merge( $emails_init, wpbc_import6_email__deny__get_fields_array_for_activation() );
881 1063 $emails_init = array_merge( $emails_init, wpbc_import6_email__trash__get_fields_array_for_activation() );
882 1064 if ( class_exists( 'wpdev_bk_personal' ) )
883 1065 $emails_init = array_merge( $emails_init, wpbc_import6_email__modification__get_fields_array_for_activation() );
1066 + if ( class_exists( 'wpdev_bk_personal' ) && function_exists( 'wpbc_customer_verification_email_get_initial_values' ) )
1067 + $emails_init = array_merge( $emails_init, wpbc_customer_verification_email_get_initial_values() );
884 1068 if ( class_exists( 'wpdev_bk_biz_s' ) )
885 1069 $emails_init = array_merge( $emails_init, wpbc_import6_email__payment_request__get_fields_array_for_activation() );
886 1070 foreach ( $emails_init as $email_key_name => $email_values ) {
887 1071
@@ -1026,9 +1210,11 @@
1026 1210 $default_options['booking_auto_cancel_pending_unpaid_bk_is_send_email'] = 'On';
1027 1211 $mu_option4delete[]='booking_auto_cancel_pending_unpaid_bk_is_send_email';
1028 1212 $default_options['booking_auto_cancel_pending_unpaid_bk_email_reason'] = __( 'This booking canceled because we did not receive payment and the administrator did not approve it.', 'booking' );
1029 1213 $mu_option4delete[]='booking_auto_cancel_pending_unpaid_bk_email_reason';
1030 - $default_options['booking_range_selection_type'] = $is_free_version ? 'dynamic' : 'fixed';
1214 + // Start every edition with the unrestricted two-click range.
1215 + // Business Small+ users can opt into a fixed one-click range later.
1216 + $default_options['booking_range_selection_type'] = 'dynamic';
1031 1217 $mu_option4delete[]='booking_range_selection_type';
1032 1218 $default_options['booking_range_selection_days_count'] = '3';
1033 1219 $mu_option4delete[]='booking_range_selection_days_count';
1034 1220 $default_options['booking_range_selection_days_max_count_dynamic'] = 30;
@@ -1202,8 +1388,26 @@
1202 1388 // FixIn: 9.2.3.8.
1203 1389 $default_options['booking_super_admin_receive_regular_user_payments'] = 'Off';
1204 1390 $mu_option4delete[]='booking_super_admin_receive_regular_user_payments';
1205 1391 }
1392 +
1393 + /**
1394 + * Filters the complete Booking Calendar default-option registry.
1395 + *
1396 + * Edition modules may register missing-value defaults without placing their
1397 + * domain-specific option names in the shared Free-version implementation.
1398 + * Existing stored values continue to be preserved by the activation layer.
1399 + *
1400 + * @param array $default_options Default option names and values.
1401 + */
1402 + $default_options = apply_filters( 'wpbc_default_options', $default_options );
1403 +
1404 + /**
1405 + * Filters option names handled by the applicable MultiUser cleanup flow.
1406 + *
1407 + * @param array $mu_option4delete Option names registered for cleanup.
1408 + */
1409 + $mu_option4delete = apply_filters( 'wpbc_multiuser_options_for_delete', $mu_option4delete );
1206 1410
1207 1411
1208 1412 if ( ! $is_get_multiuser_general_options ) {
1209 1413