PluginProbe
Booking Calendar / 11.8.4
Booking Calendar v11.8.4
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 10.11 All 204 releases
← All changes | includes/page-form-builder/save-load/bfb-activate.php +388 -347 11.411.8.4 View file →
@@ -1,4 +1,4 @@
1 1 <?php
2 2 /**
3 3 * Booking Form Builder - Activation helpers.
4 4 *
@@ -275,8 +275,13 @@
275 275 * @return false|int
276 276 */
277 277 function wpbc_bfb_activation__create_preview_page_raw() {
278 278
279 + /* Reuse an existing preview page on demos, but never auto-create one. */
280 + if ( function_exists( 'wpbc_is_this_demo' ) && wpbc_is_this_demo() ) {
281 + return false;
282 + }
283 +
279 284 $page_data = array(
280 285 'post_title' => __( 'Booking Form Preview', 'booking' ),
281 286 'post_content' => '', // Content will be injected dynamically at preview time by bfb-preview.php.
282 287 'post_status' => 'publish',
@@ -409,8 +414,14 @@
409 414 *
410 415 * @return void
411 416 */
412 417 function wpbc_bfb_activation__preview_page() {
418 + // Activation callbacks also run during version upgrades. Keep page creation
419 + // strictly inside the verified first-install boundary.
420 + if ( ! function_exists( 'wpbc_should_create_activation_pages' ) || ! wpbc_should_create_activation_pages() ) {
421 + return;
422 + }
423 +
413 424 wpbc_bfb_activation__ensure_preview_page_exists();
414 425 }
415 426 add_bk_action( 'wpbc_free_version_activation', 'wpbc_bfb_activation__preview_page' );
416 427
@@ -500,17 +511,20 @@
500 511 add_bk_action( 'wpbc_free_version_deactivation', 'wpbc_bfb_deactivation__form_structures_table' );
501 512
502 513
503 514 /**
504 - * Import legacy "standard" booking form as initial BFB structure.
515 + * Check the shared activation decision before provisioning a Standard form.
505 516 *
506 - * @return void
517 + * The wrapper name is retained for compatibility with existing Form Builder
518 + * callers and tests. The core detector additionally requires the canonical
519 + * booking table to be absent, so a missing version option on an established
520 + * installation cannot be mistaken for a new install.
521 + *
522 + * @return bool True only during a genuine first-install activation request.
507 523 */
508 524 function wpbc_bfb_is_brand_new_install__before_version_update() {
509 525
510 - $stored_version = get_option( 'booking_version_num', false );
511 -
512 - return ( false === $stored_version );
526 + return function_exists( 'wpbc_is_plugin_initial_install' ) && wpbc_is_plugin_initial_install();
513 527 }
514 528
515 529 /**
516 530 * Let the initial standard BFB form follow the global calendar days-selection setting.
@@ -550,8 +564,22 @@
550 564 return $template_record;
551 565 }
552 566
553 567 /**
568 + * Get the bundled template key used for a brand-new Standard form.
569 + *
570 + * Every customer edition starts with the spacious vertical full-day form. The
571 + * surrounding activation gate limits this choice to a genuine first install,
572 + * so upgrades, reactivations, and existing forms remain unchanged.
573 + *
574 + * @return string Stable bundled template key for a genuine first install.
575 + */
576 +function wpbc_bfb_activation__get_initial_standard_template_key() {
577 +
578 + return 'dates_vertical_hints_full_days';
579 +}
580 +
581 +/**
554 582 * Maybe create the initial standard BFB form from a bundled template.
555 583 *
556 584 * Used only during brand new plugin activation, before booking_version_num
557 585 * gets updated. Upgrades keep migrating the existing legacy configuration.
@@ -557,9 +585,9 @@
557 585 * gets updated. Upgrades keep migrating the existing legacy configuration.
558 586 *
559 587 * @return bool
560 588 */
561 -function wpbc_bfb_maybe_create_initial_standard_form_from_template() {
589 +function wpbc_bfb_maybe_create_initial_standard_form_from_template() {
562 590
563 591 if ( ! wpbc_bfb_is_brand_new_install__before_version_update() ) {
564 592 return false;
565 593 }
@@ -568,11 +596,16 @@
568 596 return false;
569 597 }
570 598
571 599 if ( function_exists( 'wpbc_get_bfb_template_record_by_key' ) ) {
572 - // Default Booking Form Template - Just after Booking Calendar activation!
573 - // $template_record = wpbc_get_bfb_template_record_by_key( 'time_appointments_3_steps_review_with_hints' ); // Time appointments.
574 - $template_record = wpbc_get_bfb_template_record_by_key( 'dates_2_columns_sidebar_hints' ); // Full Days - 2 Columns - with dates hints.
600 + $template_key = wpbc_bfb_activation__get_initial_standard_template_key();
601 + $template_record = wpbc_get_bfb_template_record_by_key( $template_key );
602 +
603 + // Preserve a usable first-install form if a registry filter removes the
604 + // new starter template.
605 + if ( empty( $template_record ) && 'dates_2_columns_sidebar_hints' !== $template_key ) {
606 + $template_record = wpbc_get_bfb_template_record_by_key( 'dates_2_columns_sidebar_hints' );
607 + }
575 608 } else {
576 609 $template_record = array();
577 610 }
578 611
@@ -596,312 +629,320 @@
596 629 }
597 630
598 631 $booking_form_id = WPBC_BFB_Form_Storage::save_form( $template_record );
599 632
600 - return ! empty( $booking_form_id );
601 -}
602 -
603 -
604 -/**
605 - * Get the dedicated bundled template for the current live-demo edition.
606 - *
607 - * @param int $owner_user_id Optional MultiUser owner ID.
608 - *
609 - * @return string Template key, or an empty string outside a supported demo.
610 - */
611 -function wpbc_bfb_live_demo__get_template_key( $owner_user_id = 0 ) {
612 -
613 - if ( ! function_exists( 'wpbc_is_this_demo' ) || ! wpbc_is_this_demo() ) {
614 - return '';
615 - }
616 -
617 - $owner_user_id = absint( $owner_user_id );
618 -
619 - if ( class_exists( 'wpdev_bk_multiuser' ) ) {
620 - return ( $owner_user_id > 0 ) ? 'demo_multiuser_owner_1' : 'demo_multiuser';
621 - }
622 - if ( class_exists( 'wpdev_bk_biz_l' ) ) {
623 - return 'demo_business_large';
624 - }
625 - if ( class_exists( 'wpdev_bk_biz_m' ) ) {
626 - return 'demo_business_medium';
627 - }
628 - if ( class_exists( 'wpdev_bk_biz_s' ) ) {
629 - return 'demo_business_small';
630 - }
631 - if ( class_exists( 'wpdev_bk_personal' ) ) {
632 - return 'demo_personal';
633 - }
634 -
635 - return '';
636 -}
637 -
638 -
639 -/**
640 - * Get the global Form Style used by the current live-demo edition.
641 - *
642 - * @return string Form Style preset key.
643 - */
644 -function wpbc_bfb_live_demo__get_form_style() {
645 -
646 - if ( class_exists( 'wpdev_bk_multiuser' ) || class_exists( 'wpdev_bk_biz_l' ) ) {
647 - return 'light_bordered';
648 - }
649 - if ( class_exists( 'wpdev_bk_biz_m' ) ) {
650 - return 'light_soft';
651 - }
652 - if ( class_exists( 'wpdev_bk_biz_s' ) ) {
653 - return 'light_bordered';
654 - }
655 - if ( class_exists( 'wpdev_bk_personal' ) ) {
656 - return 'light_none';
657 - }
658 -
659 - return 'light_bordered';
660 -}
661 -
662 -
663 -/**
664 - * Provision a live-demo standard form from a real bundled BFB template.
665 - *
666 - * Normal owner activation is idempotent and preserves an existing form. The
667 - * explicit demo reset path may request replacement to restore fixture data.
668 - *
669 - * @param int $owner_user_id Owner ID, or 0 for the global/Super Admin form.
670 - * @param string $template_key Optional explicit bundled template key.
671 - * @param bool $replace Whether to replace an existing standard form.
672 - *
673 - * @return int|false Booking form ID on success, false on failure.
674 - */
675 -function wpbc_bfb_live_demo__provision_standard_form( $owner_user_id = 0, $template_key = '', $replace = false ) {
676 -
677 - if ( ! function_exists( 'wpbc_is_this_demo' ) || ! wpbc_is_this_demo() ) {
678 - return false;
679 - }
680 - if ( ! class_exists( 'WPBC_BFB_Form_Storage' ) ) {
681 - return false;
682 - }
683 - if ( function_exists( 'wpbc_is_table_exists' ) && ! wpbc_is_table_exists( 'booking_form_structures' ) ) {
684 - return false;
685 - }
686 -
687 - $owner_user_id = absint( $owner_user_id );
688 - $template_key = sanitize_key( (string) $template_key );
689 - if ( '' === $template_key ) {
690 - $template_key = wpbc_bfb_live_demo__get_template_key( $owner_user_id );
691 - }
692 - if ( '' === $template_key ) {
693 - return false;
694 - }
695 -
696 - $existing = WPBC_BFB_Form_Storage::get_current_form_by_key( 'standard', $owner_user_id, 'published' );
697 - if ( ! empty( $existing->booking_form_id ) && ! $replace ) {
698 - return (int) $existing->booking_form_id;
699 - }
700 -
701 - $template_record = function_exists( 'wpbc_get_bfb_template_record_by_key' )
702 - ? wpbc_get_bfb_template_record_by_key( $template_key )
703 - : array();
704 -
705 - if (
706 - empty( $template_record ) ||
707 - ! is_array( $template_record ) ||
708 - empty( $template_record['structure_json'] ) ||
709 - empty( $template_record['engine'] ) ||
710 - 'bfb' !== (string) $template_record['engine']
711 - ) {
712 - return false;
713 - }
714 -
715 - $template_record['form_slug'] = 'standard';
716 - $template_record['status'] = 'published';
717 - $template_record['scope'] = ( $owner_user_id > 0 ) ? 'user' : 'global';
718 - $template_record['owner_user_id'] = $owner_user_id;
719 - $template_record['booking_resource_id'] = null;
720 - $template_record['is_default'] = 1;
721 - $template_record['title'] = __( 'Standard', 'booking' );
722 - $template_record['description'] = '';
723 - $template_record['picture_url'] = isset( $template_record['picture_url'] ) ? (string) $template_record['picture_url'] : '';
724 -
725 - if ( function_exists( 'wpbc_bfb_resolve_picture_url' ) ) {
726 - $template_record['picture_url'] = wpbc_bfb_resolve_picture_url( $template_record['picture_url'] );
727 - }
728 -
729 - $booking_form_id = WPBC_BFB_Form_Storage::save_form( $template_record );
730 -
731 - return ! empty( $booking_form_id ) ? (int) $booking_form_id : false;
732 -}
733 -
734 -
735 -/**
736 - * Return regular-owner fixtures used by the MultiUser live demo.
737 - *
738 - * @return array Owner user ID => bundled template key.
739 - */
740 -function wpbc_bfb_live_demo__get_multiuser_owner_template_map() {
741 -
742 - $owner_templates = array(
743 - 3 => 'demo_multiuser_owner_1',
744 - 4 => 'demo_multiuser_owner_2',
745 - 5 => 'demo_multiuser_owner_3',
746 - );
747 -
748 - /**
749 - * Allow a private demo installation to use different owner IDs while
750 - * retaining the same centralized provisioning flow.
751 - *
752 - * @param array $owner_templates Owner user ID => template key.
753 - */
754 - $owner_templates = apply_filters( 'wpbc_bfb_live_demo_multiuser_owner_templates', $owner_templates );
755 -
756 - return is_array( $owner_templates ) ? $owner_templates : array();
757 -}
758 -
759 -
760 -/**
761 - * Apply all standard-form fixtures required by the active live demo.
762 - *
763 - * This is the canonical final activation step. It intentionally replaces demo
764 - * fixtures, but never runs on customer installations.
765 - *
766 - * @return bool True when every applicable fixture was saved.
767 - */
768 -function wpbc_bfb_live_demo__provision_all_standard_forms() {
769 -
770 - if ( ! function_exists( 'wpbc_is_this_demo' ) || ! wpbc_is_this_demo() ) {
771 - return false;
772 - }
773 -
774 - // Pro-only reactivation does not necessarily rerun the Free activation
775 - // callback that normally synchronizes bundled template rows.
776 - if ( function_exists( 'wpbc_bfb_activation__seed_templates' ) ) {
777 - wpbc_bfb_activation__seed_templates();
778 - }
779 -
780 - $is_success = ( false !== wpbc_bfb_live_demo__provision_standard_form( 0, '', true ) );
781 -
782 - // Form Style is a site-wide setting, not part of an individual form row.
783 - // Write directly to the global option so the result is deterministic even
784 - // when finalization runs from a regular MultiUser administrator session.
785 - update_option( 'booking_form_style', wpbc_bfb_live_demo__get_form_style() );
786 -
787 - if ( class_exists( 'wpdev_bk_multiuser' ) ) {
788 - foreach ( wpbc_bfb_live_demo__get_multiuser_owner_template_map() as $owner_user_id => $template_key ) {
789 - $owner_user_id = absint( $owner_user_id );
790 - $template_key = sanitize_key( (string) $template_key );
791 - if ( $owner_user_id <= 0 || '' === $template_key ) {
792 - $is_success = false;
793 - continue;
794 - }
795 -
796 - if ( function_exists( 'get_userdata' ) && ! get_userdata( $owner_user_id ) ) {
797 - $is_success = false;
798 - continue;
799 - }
800 -
801 - if ( false === wpbc_bfb_live_demo__provision_standard_form( $owner_user_id, $template_key, true ) ) {
802 - $is_success = false;
803 - }
804 - }
805 - }
806 -
807 - return $is_success;
808 -}
809 -
810 -
811 -/**
812 - * Ensure that a regular MultiUser owner has an independent standard BFB form.
813 - *
814 - * Existing owner forms are never overwritten. On normal installations the
815 - * current global standard form is cloned, preserving the Super Admin's chosen
816 - * Builder structure. Live demos use their dedicated bundled fixture instead.
817 - *
818 - * @param int $owner_user_id Regular MultiUser owner ID.
819 - *
820 - * @return int|false Booking form ID on success, false on failure.
821 - */
822 -function wpbc_bfb_ensure_standard_form_for_owner( $owner_user_id ) {
823 -
824 - $owner_user_id = absint( $owner_user_id );
825 - if ( $owner_user_id <= 0 || ! class_exists( 'WPBC_BFB_Form_Storage' ) ) {
826 - return false;
827 - }
828 - if ( function_exists( 'wpbc_is_table_exists' ) && ! wpbc_is_table_exists( 'booking_form_structures' ) ) {
829 - return false;
830 - }
831 -
832 - $existing = WPBC_BFB_Form_Storage::get_current_form_by_key( 'standard', $owner_user_id, 'published' );
833 - if ( ! empty( $existing->booking_form_id ) ) {
834 - return (int) $existing->booking_form_id;
835 - }
836 -
837 - if ( function_exists( 'wpbc_is_this_demo' ) && wpbc_is_this_demo() ) {
838 - return wpbc_bfb_live_demo__provision_standard_form( $owner_user_id, '', false );
839 - }
840 -
841 - $global_standard = WPBC_BFB_Form_Storage::get_current_form_by_key( 'standard', 0, 'published' );
842 - $form_record = ! empty( $global_standard ) ? get_object_vars( $global_standard ) : array();
843 -
844 - if ( empty( $form_record['structure_json'] ) && function_exists( 'wpbc_get_bfb_template_record_by_key' ) ) {
845 - $form_record = wpbc_get_bfb_template_record_by_key( 'dates_2_columns_sidebar_hints' );
846 - }
847 - if (
848 - empty( $form_record ) ||
849 - ! is_array( $form_record ) ||
850 - empty( $form_record['structure_json'] ) ||
851 - empty( $form_record['engine'] ) ||
852 - 'bfb' !== (string) $form_record['engine']
853 - ) {
854 - return false;
855 - }
856 -
857 - unset(
858 - $form_record['booking_form_id'],
859 - $form_record['created_at'],
860 - $form_record['created_by'],
861 - $form_record['updated_at'],
862 - $form_record['updated_by']
863 - );
864 -
865 - $form_record['form_slug'] = 'standard';
866 - $form_record['status'] = 'published';
867 - $form_record['scope'] = 'user';
868 - $form_record['owner_user_id'] = $owner_user_id;
869 - $form_record['booking_resource_id'] = null;
870 - $form_record['is_default'] = 1;
871 - $form_record['title'] = __( 'Standard', 'booking' );
872 - $form_record['description'] = '';
873 -
874 - $booking_form_id = WPBC_BFB_Form_Storage::save_form( $form_record );
875 -
876 - return ! empty( $booking_form_id ) ? (int) $booking_form_id : false;
877 -}
633 + return ! empty( $booking_form_id );
634 +}
878 635
636 +
879 637 /**
638 + * Get the dedicated bundled template for the current live-demo edition.
639 + *
640 + * @param int $owner_user_id Optional MultiUser owner ID.
641 + *
642 + * @return string Template key, or an empty string outside a supported demo.
643 + */
644 +function wpbc_bfb_live_demo__get_template_key( $owner_user_id = 0 ) {
645 +
646 + if ( ! function_exists( 'wpbc_is_this_demo' ) || ! wpbc_is_this_demo() ) {
647 + return '';
648 + }
649 +
650 + $owner_user_id = absint( $owner_user_id );
651 +
652 + if ( class_exists( 'wpdev_bk_multiuser' ) ) {
653 + return ( $owner_user_id > 0 ) ? 'demo_multiuser_owner_1' : 'demo_multiuser';
654 + }
655 + if ( class_exists( 'wpdev_bk_biz_l' ) ) {
656 + return 'demo_business_large';
657 + }
658 + if ( class_exists( 'wpdev_bk_biz_m' ) ) {
659 + return 'demo_business_medium';
660 + }
661 + if ( class_exists( 'wpdev_bk_biz_s' ) ) {
662 + return 'demo_business_small';
663 + }
664 + if ( class_exists( 'wpdev_bk_personal' ) ) {
665 + return 'demo_personal';
666 + }
667 +
668 + return '';
669 +}
670 +
671 +
672 +/**
673 + * Get the global Form Style used by the current live-demo edition.
674 + *
675 + * @return string Form Style preset key.
676 + */
677 +function wpbc_bfb_live_demo__get_form_style() {
678 +
679 + if ( class_exists( 'wpdev_bk_multiuser' ) || class_exists( 'wpdev_bk_biz_l' ) ) {
680 + return 'light_bordered';
681 + }
682 + if ( class_exists( 'wpdev_bk_biz_m' ) ) {
683 + return 'light_soft';
684 + }
685 + if ( class_exists( 'wpdev_bk_biz_s' ) ) {
686 + return 'light_bordered';
687 + }
688 + if ( class_exists( 'wpdev_bk_personal' ) ) {
689 + return 'light_none';
690 + }
691 +
692 + return 'light_bordered';
693 +}
694 +
695 +
696 +/**
697 + * Provision a live-demo standard form from a real bundled BFB template.
698 + *
699 + * Normal owner activation is idempotent and preserves an existing form. The
700 + * explicit demo reset path may request replacement to restore fixture data.
701 + *
702 + * @param int $owner_user_id Owner ID, or 0 for the global/Super Admin form.
703 + * @param string $template_key Optional explicit bundled template key.
704 + * @param bool $replace Whether to replace an existing standard form.
705 + *
706 + * @return int|false Booking form ID on success, false on failure.
707 + */
708 +function wpbc_bfb_live_demo__provision_standard_form( $owner_user_id = 0, $template_key = '', $replace = false ) {
709 +
710 + if ( ! function_exists( 'wpbc_is_this_demo' ) || ! wpbc_is_this_demo() ) {
711 + return false;
712 + }
713 + if ( ! class_exists( 'WPBC_BFB_Form_Storage' ) ) {
714 + return false;
715 + }
716 + if ( function_exists( 'wpbc_is_table_exists' ) && ! wpbc_is_table_exists( 'booking_form_structures' ) ) {
717 + return false;
718 + }
719 +
720 + $owner_user_id = absint( $owner_user_id );
721 + $template_key = sanitize_key( (string) $template_key );
722 + if ( '' === $template_key ) {
723 + $template_key = wpbc_bfb_live_demo__get_template_key( $owner_user_id );
724 + }
725 + if ( '' === $template_key ) {
726 + return false;
727 + }
728 +
729 + $existing = WPBC_BFB_Form_Storage::get_current_form_by_key( 'standard', $owner_user_id, 'published' );
730 + if ( ! empty( $existing->booking_form_id ) && ! $replace ) {
731 + return (int) $existing->booking_form_id;
732 + }
733 +
734 + $template_record = function_exists( 'wpbc_get_bfb_template_record_by_key' )
735 + ? wpbc_get_bfb_template_record_by_key( $template_key )
736 + : array();
737 +
738 + if (
739 + empty( $template_record ) ||
740 + ! is_array( $template_record ) ||
741 + empty( $template_record['structure_json'] ) ||
742 + empty( $template_record['engine'] ) ||
743 + 'bfb' !== (string) $template_record['engine']
744 + ) {
745 + return false;
746 + }
747 +
748 + $template_record['form_slug'] = 'standard';
749 + $template_record['status'] = 'published';
750 + $template_record['scope'] = ( $owner_user_id > 0 ) ? 'user' : 'global';
751 + $template_record['owner_user_id'] = $owner_user_id;
752 + $template_record['booking_resource_id'] = null;
753 + $template_record['is_default'] = 1;
754 + $template_record['title'] = __( 'Standard', 'booking' );
755 + $template_record['description'] = '';
756 + $template_record['picture_url'] = isset( $template_record['picture_url'] ) ? (string) $template_record['picture_url'] : '';
757 +
758 + if ( function_exists( 'wpbc_bfb_resolve_picture_url' ) ) {
759 + $template_record['picture_url'] = wpbc_bfb_resolve_picture_url( $template_record['picture_url'] );
760 + }
761 +
762 + $booking_form_id = WPBC_BFB_Form_Storage::save_form( $template_record );
763 +
764 + return ! empty( $booking_form_id ) ? (int) $booking_form_id : false;
765 +}
766 +
767 +
768 +/**
769 + * Return regular-owner fixtures used by the MultiUser live demo.
770 + *
771 + * @return array Owner user ID => bundled template key.
772 + */
773 +function wpbc_bfb_live_demo__get_multiuser_owner_template_map() {
774 +
775 + $owner_templates = array(
776 + 3 => 'demo_multiuser_owner_1',
777 + 4 => 'demo_multiuser_owner_2',
778 + 5 => 'demo_multiuser_owner_3',
779 + );
780 +
781 + /**
782 + * Allow a private demo installation to use different owner IDs while
783 + * retaining the same centralized provisioning flow.
784 + *
785 + * @param array $owner_templates Owner user ID => template key.
786 + */
787 + $owner_templates = apply_filters( 'wpbc_bfb_live_demo_multiuser_owner_templates', $owner_templates );
788 +
789 + return is_array( $owner_templates ) ? $owner_templates : array();
790 +}
791 +
792 +
793 +/**
794 + * Apply all standard-form fixtures required by the active live demo.
795 + *
796 + * This is the canonical final activation step. It intentionally replaces demo
797 + * fixtures, but never runs on customer installations.
798 + *
799 + * @return bool True when every applicable fixture was saved.
800 + */
801 +function wpbc_bfb_live_demo__provision_all_standard_forms() {
802 +
803 + if ( ! function_exists( 'wpbc_is_this_demo' ) || ! wpbc_is_this_demo() ) {
804 + return false;
805 + }
806 +
807 + // Pro-only reactivation does not necessarily rerun the Free activation
808 + // callback that normally synchronizes bundled template rows.
809 + if ( function_exists( 'wpbc_bfb_activation__seed_templates' ) ) {
810 + wpbc_bfb_activation__seed_templates();
811 + }
812 +
813 + $is_success = ( false !== wpbc_bfb_live_demo__provision_standard_form( 0, '', true ) );
814 +
815 + // Form Style is a site-wide setting, not part of an individual form row.
816 + // Write directly to the global option so the result is deterministic even
817 + // when finalization runs from a regular MultiUser administrator session.
818 + update_option( 'booking_form_style', wpbc_bfb_live_demo__get_form_style() );
819 +
820 + // Live demos intentionally showcase the shared accent experience. Customer
821 + // installations keep the backward-compatible disabled default.
822 + $form_accent_defaults = function_exists( 'wpbc_bfb_settings__get_default_form_accent_options' )
823 + ? wpbc_bfb_settings__get_default_form_accent_options()
824 + : array( 'booking_form_accent_color' => WPBC_DEFAULT_FORM_ACCENT_COLOR );
825 + update_option( 'booking_form_accent_enabled', 'On' );
826 + update_option( 'booking_form_accent_color', $form_accent_defaults['booking_form_accent_color'] );
827 +
828 + if ( class_exists( 'wpdev_bk_multiuser' ) ) {
829 + foreach ( wpbc_bfb_live_demo__get_multiuser_owner_template_map() as $owner_user_id => $template_key ) {
830 + $owner_user_id = absint( $owner_user_id );
831 + $template_key = sanitize_key( (string) $template_key );
832 + if ( $owner_user_id <= 0 || '' === $template_key ) {
833 + $is_success = false;
834 + continue;
835 + }
836 +
837 + if ( function_exists( 'get_userdata' ) && ! get_userdata( $owner_user_id ) ) {
838 + $is_success = false;
839 + continue;
840 + }
841 +
842 + if ( false === wpbc_bfb_live_demo__provision_standard_form( $owner_user_id, $template_key, true ) ) {
843 + $is_success = false;
844 + }
845 + }
846 + }
847 +
848 + return $is_success;
849 +}
850 +
851 +
852 +/**
853 + * Ensure that a regular MultiUser owner has an independent standard BFB form.
854 + *
855 + * Existing owner forms are never overwritten. On normal installations the
856 + * current global standard form is cloned, preserving the Super Admin's chosen
857 + * Builder structure. Live demos use their dedicated bundled fixture instead.
858 + *
859 + * @param int $owner_user_id Regular MultiUser owner ID.
860 + *
861 + * @return int|false Booking form ID on success, false on failure.
862 + */
863 +function wpbc_bfb_ensure_standard_form_for_owner( $owner_user_id ) {
864 +
865 + $owner_user_id = absint( $owner_user_id );
866 + if ( $owner_user_id <= 0 || ! class_exists( 'WPBC_BFB_Form_Storage' ) ) {
867 + return false;
868 + }
869 + if ( function_exists( 'wpbc_is_table_exists' ) && ! wpbc_is_table_exists( 'booking_form_structures' ) ) {
870 + return false;
871 + }
872 +
873 + $existing = WPBC_BFB_Form_Storage::get_current_form_by_key( 'standard', $owner_user_id, 'published' );
874 + if ( ! empty( $existing->booking_form_id ) ) {
875 + return (int) $existing->booking_form_id;
876 + }
877 +
878 + if ( function_exists( 'wpbc_is_this_demo' ) && wpbc_is_this_demo() ) {
879 + return wpbc_bfb_live_demo__provision_standard_form( $owner_user_id, '', false );
880 + }
881 +
882 + $global_standard = WPBC_BFB_Form_Storage::get_current_form_by_key( 'standard', 0, 'published' );
883 + $form_record = ! empty( $global_standard ) ? get_object_vars( $global_standard ) : array();
884 +
885 + if ( empty( $form_record['structure_json'] ) && function_exists( 'wpbc_get_bfb_template_record_by_key' ) ) {
886 + $form_record = wpbc_get_bfb_template_record_by_key( 'dates_2_columns_sidebar_hints' );
887 + }
888 + if (
889 + empty( $form_record ) ||
890 + ! is_array( $form_record ) ||
891 + empty( $form_record['structure_json'] ) ||
892 + empty( $form_record['engine'] ) ||
893 + 'bfb' !== (string) $form_record['engine']
894 + ) {
895 + return false;
896 + }
897 +
898 + unset(
899 + $form_record['booking_form_id'],
900 + $form_record['created_at'],
901 + $form_record['created_by'],
902 + $form_record['updated_at'],
903 + $form_record['updated_by']
904 + );
905 +
906 + $form_record['form_slug'] = 'standard';
907 + $form_record['status'] = 'published';
908 + $form_record['scope'] = 'user';
909 + $form_record['owner_user_id'] = $owner_user_id;
910 + $form_record['booking_resource_id'] = null;
911 + $form_record['is_default'] = 1;
912 + $form_record['title'] = __( 'Standard', 'booking' );
913 + $form_record['description'] = '';
914 +
915 + $booking_form_id = WPBC_BFB_Form_Storage::save_form( $form_record );
916 +
917 + return ! empty( $booking_form_id ) ? (int) $booking_form_id : false;
918 +}
919 +
920 +/**
880 921 * Import legacy "standard" booking form as initial BFB structure.
881 922 *
882 923 * @return void
883 924 */
884 -function wpbc_bfb__import_old_booking_forms() {
885 -
886 - if ( wpbc_bfb_maybe_create_initial_standard_form_from_template() ) {
887 - return;
888 - }
889 -
890 - if ( function_exists( 'wpbc_bfb_import_legacy_forms' ) ) {
891 - wpbc_bfb_import_legacy_forms(
892 - array(
893 - 'mode' => 'all_global',
894 - 'import_standard' => true,
895 - 'import_custom' => true,
896 - 'skip_if_exists' => true,
897 - 'set_bfb_form_not_defined' => false,
898 - )
899 - );
900 - }
901 -}
925 +function wpbc_bfb__import_old_booking_forms() {
902 926
927 + if ( wpbc_bfb_maybe_create_initial_standard_form_from_template() ) {
928 + return;
929 + }
903 930
931 + if ( function_exists( 'wpbc_bfb_import_legacy_forms' ) ) {
932 + wpbc_bfb_import_legacy_forms(
933 + array(
934 + 'mode' => 'all_global',
935 + 'import_standard' => true,
936 + 'import_custom' => true,
937 + 'skip_if_exists' => true,
938 + 'set_bfb_form_not_defined' => false,
939 + )
940 + );
941 + }
942 +}
943 +
944 +
904 945 /**
905 946 * Remove BFB Preview page from rendered nav menus.
906 947 *
907 948 * @param array $sorted_menu_items Menu item objects.
@@ -1162,50 +1203,50 @@
1162 1203 * $mode = 'all_users'; // Import booking forms for == All Users ==.
1163 1204 *
1164 1205 * @return void
1165 1206 */
1166 -function wpbc_bfb_import_legacy_forms__on_activation() {
1207 +function wpbc_bfb_import_legacy_forms__on_activation() {
1167 1208
1168 1209 if ( ! is_admin() ) {
1169 1210 return;
1170 1211 }
1171 1212
1172 - if ( false === ( $is_in_action_late_activation = get_transient( 'wpbc_pro_versions__late_activation_60' ) ) ) {
1173 - return;
1174 - }
1175 -
1176 - delete_transient( 'wpbc_pro_versions__late_activation_60' );
1177 -
1178 - $import_version = '11.3.1';
1179 -
1180 - // Live demos use dedicated BFB fixtures as their canonical source. Importing
1181 - // legacy options here would overwrite the fixtures installed during the
1182 - // activation request, especially because the old demo importer used
1183 - // skip_if_exists=false.
1184 - if ( wpbc_is_this_demo() ) {
1185 - if ( wpbc_bfb_live_demo__provision_all_standard_forms() ) {
1186 - update_option( 'wpbc_bfb_legacy_import_done_for_pro', $import_version );
1187 - } else {
1188 - // Keep a bounded retry available if activation dependencies were not
1189 - // ready yet on this request.
1190 - $retry_count = is_numeric( $is_in_action_late_activation ) ? absint( $is_in_action_late_activation ) : 0;
1191 - if ( $retry_count < 3 ) {
1192 - set_transient( 'wpbc_pro_versions__late_activation_60', $retry_count + 1, HOUR_IN_SECONDS );
1193 - }
1194 - }
1195 - return;
1196 - }
1197 -
1198 - if ( $import_version === get_option( 'wpbc_bfb_legacy_import_done_for_pro', '' ) ) {
1199 - return;
1200 - }
1201 -
1202 - $summary = wpbc_bfb_import_legacy_forms(
1213 + if ( false === ( $is_in_action_late_activation = get_transient( 'wpbc_pro_versions__late_activation_60' ) ) ) {
1214 + return;
1215 + }
1216 +
1217 + delete_transient( 'wpbc_pro_versions__late_activation_60' );
1218 +
1219 + $import_version = '11.3.1';
1220 +
1221 + // Live demos use dedicated BFB fixtures as their canonical source. Importing
1222 + // legacy options here would overwrite the fixtures installed during the
1223 + // activation request, especially because the old demo importer used
1224 + // skip_if_exists=false.
1225 + if ( wpbc_is_this_demo() ) {
1226 + if ( wpbc_bfb_live_demo__provision_all_standard_forms() ) {
1227 + update_option( 'wpbc_bfb_legacy_import_done_for_pro', $import_version );
1228 + } else {
1229 + // Keep a bounded retry available if activation dependencies were not
1230 + // ready yet on this request.
1231 + $retry_count = is_numeric( $is_in_action_late_activation ) ? absint( $is_in_action_late_activation ) : 0;
1232 + if ( $retry_count < 3 ) {
1233 + set_transient( 'wpbc_pro_versions__late_activation_60', $retry_count + 1, HOUR_IN_SECONDS );
1234 + }
1235 + }
1236 + return;
1237 + }
1238 +
1239 + if ( $import_version === get_option( 'wpbc_bfb_legacy_import_done_for_pro', '' ) ) {
1240 + return;
1241 + }
1242 +
1243 + $summary = wpbc_bfb_import_legacy_forms(
1203 1244 array(
1204 1245 'mode' => ( class_exists( 'wpdev_bk_multiuser' ) ) ? 'all_users' : 'all_global',
1205 1246 'import_standard' => true,
1206 1247 'import_custom' => true,
1207 - 'skip_if_exists' => true,
1248 + 'skip_if_exists' => true,
1208 1249 'set_bfb_form_not_defined' => true,
1209 1250 )
1210 1251 );
1211 1252 update_option( 'wpbc_bfb_legacy_import_done_for_pro', $import_version );
@@ -1217,17 +1258,17 @@
1217 1258 * Schedule one deferred legacy-form import after Pro activation. The import runs on a later request while this transient exists.
1218 1259 *
1219 1260 * @return void
1220 1261 */
1221 -function wpbc_pro_versions__late_activation(){
1222 -
1223 - // A regular MultiUser owner activation runs the Pro activation callbacks in
1224 - // its own context. It must not schedule a later demo-wide reset.
1225 - if ( false !== apply_bk_filter( 'wpbc_is_user_in_activation_process' ) ) {
1226 - return;
1227 - }
1228 -
1229 - // Get any existing copy of our transient data
1262 +function wpbc_pro_versions__late_activation(){
1263 +
1264 + // A regular MultiUser owner activation runs the Pro activation callbacks in
1265 + // its own context. It must not schedule a later demo-wide reset.
1266 + if ( false !== apply_bk_filter( 'wpbc_is_user_in_activation_process' ) ) {
1267 + return;
1268 + }
1269 +
1270 + // Get any existing copy of our transient data
1230 1271 if ( false === ( $is_in_action_late_activation = get_transient( 'wpbc_pro_versions__late_activation_60' ) ) ) {
1231 1272 // It wasn't there, so regenerate the data and save the transient
1232 1273 $is_in_action_late_activation = true;
1233 1274 set_transient( 'wpbc_pro_versions__late_activation_60', $is_in_action_late_activation, HOUR_IN_SECONDS );