Changeset 3492420
- Timestamp:
- 03/27/2026 08:09:49 AM (7 days ago)
- Location:
- booking/trunk
- Files:
-
- 9 edited
-
includes/_functions/booking_data__parse.php (modified) (5 diffs)
-
includes/_functions/str_regex.php (modified) (1 diff)
-
includes/page-form-builder/assets/template-records/technical_support_form.php (modified) (1 diff)
-
includes/page-form-builder/assets/template-records/time_slots_20_min_2_steps_wizard.php (modified) (1 diff)
-
includes/page-form-builder/assets/template-records/time_slots_30_min_2_steps_wizard.php (modified) (1 diff)
-
includes/page-form-builder/assets/template-records/time_slots_start_duration_times_selection.php (modified) (1 diff)
-
includes/page-form-builder/assets/template-records/time_slots_start_end_times_1_hour_selection.php (modified) (1 diff)
-
readme.txt (modified) (12 diffs)
-
wpdev-booking.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
booking/trunk/includes/_functions/booking_data__parse.php
r3488732 r3492420 574 574 } 575 575 576 /** 577 * Get booking form pair (fields + show template) for listing/inspection purposes, 578 * but allow BFB resolver to override legacy options. 576 // FixIn: 10.15.4.1. 577 /** 578 * Extract "advanced_form" from BFB loader result. 579 * 580 * @param mixed $bfb_pair 581 * 582 * @return string 583 */ 584 function wpbc_extract__advanced_form_from_bfb_pair__for_field_names_listing( $bfb_pair ) { 585 586 $containers = array(); 587 588 if ( ! is_array( $bfb_pair ) ) { 589 return ''; 590 } 591 592 /** 593 * Safety: 594 * Do not override if loader already fell back to legacy. 595 */ 596 if ( isset( $bfb_pair['source'] ) && ( 'builder' !== $bfb_pair['source'] ) ) { 597 return ''; 598 } 599 600 $containers[] = $bfb_pair; 601 602 if ( isset( $bfb_pair['pair'] ) && is_array( $bfb_pair['pair'] ) ) { 603 $containers[] = $bfb_pair['pair']; 604 } 605 606 if ( isset( $bfb_pair['form'] ) && is_array( $bfb_pair['form'] ) ) { 607 $containers[] = $bfb_pair['form']; 608 } 609 610 foreach ( $containers as $container ) { 611 612 if ( isset( $container['form'] ) && is_string( $container['form'] ) ) { 613 return (string) $container['form']; 614 } 615 616 if ( isset( $container['advanced_form'] ) && is_string( $container['advanced_form'] ) ) { 617 return (string) $container['advanced_form']; 618 } 619 } 620 621 return ''; 622 } 623 624 625 /** 626 * Extract "content_form" from BFB loader result. 627 * 628 * @param mixed $bfb_pair 629 * 630 * @return string 631 */ 632 function wpbc_extract__content_form_from_bfb_pair__for_field_names_listing( $bfb_pair ) { 633 634 $containers = array(); 635 636 if ( ! is_array( $bfb_pair ) ) { 637 return ''; 638 } 639 640 /** 641 * Safety: 642 * Do not override if loader already fell back to legacy. 643 */ 644 if ( isset( $bfb_pair['source'] ) && ( 'builder' !== $bfb_pair['source'] ) ) { 645 return ''; 646 } 647 648 $containers[] = $bfb_pair; 649 650 if ( isset( $bfb_pair['pair'] ) && is_array( $bfb_pair['pair'] ) ) { 651 $containers[] = $bfb_pair['pair']; 652 } 653 654 if ( isset( $bfb_pair['form'] ) && is_array( $bfb_pair['form'] ) ) { 655 $containers[] = $bfb_pair['form']; 656 } 657 658 foreach ( $containers as $container ) { 659 660 if ( isset( $container['content'] ) && is_string( $container['content'] ) ) { 661 return (string) $container['content']; 662 } 663 664 if ( isset( $container['content_form'] ) && is_string( $container['content_form'] ) ) { 665 return (string) $container['content_form']; 666 } 667 } 668 669 return ''; 670 } 671 672 673 /** 674 * Maybe get booking form pair from BFB using the same resolver chain as front-end rendering. 579 675 * 580 676 * @param int $resource_id … … 582 678 * @param array $ctx 583 679 * 584 * @return array { form:string, content:string } 680 * @return array 681 */ 682 function wpbc_get__bfb_booking_form_pair__for_field_names_listing( $resource_id = 1, $form_name = 'standard', $ctx = array() ) { 683 684 $resource_id = absint( $resource_id ); 685 $form_name = sanitize_text_field( (string) $form_name ); 686 $ctx = ( is_array( $ctx ) ) ? $ctx : array(); 687 688 if ( '' === $form_name ) { 689 $form_name = 'standard'; 690 } 691 692 $owner_user_id = isset( $ctx['owner_user_id'] ) ? absint( $ctx['owner_user_id'] ) : null; 693 694 if ( ! class_exists( 'WPBC_FE_Form_Source_Resolver' ) ) { 695 return array(); 696 } 697 698 if ( ! function_exists( 'wpbc_bfb_get_booking_form_pair' ) ) { 699 return array(); 700 } 701 702 $form_status = isset( $ctx['form_status'] ) ? sanitize_key( $ctx['form_status'] ) : 'published'; 703 704 if ( in_array( $form_status, array( 'publish', 'published' ), true ) ) { 705 $form_status = 'published'; 706 } 707 if ( 'preview' !== $form_status ) { 708 $form_status = 'published'; 709 } 710 711 /** 712 * Preview payload shortcut. 713 */ 714 if ( 715 ( 'preview' === $form_status ) 716 && function_exists( 'wpbc_bfb_preview__maybe_get_payload_from_context' ) 717 ) { 718 $payload = wpbc_bfb_preview__maybe_get_payload_from_context( $ctx ); 719 720 if ( ! empty( $payload ) && is_array( $payload ) ) { 721 722 $pair = array( 723 'form' => isset( $payload['advanced_form'] ) ? (string) $payload['advanced_form'] : '', 724 'content' => isset( $payload['content_form'] ) ? (string) $payload['content_form'] : '', 725 ); 726 727 if ( ( '' !== trim( $pair['form'] ) ) || ( '' !== trim( $pair['content'] ) ) ) { 728 return $pair; 729 } 730 } 731 } 732 733 $req = array( 734 'resource_id' => $resource_id, 735 'form_slug' => $form_name, 736 'form_status' => $form_status, 737 'custom_params' => array(), 738 'legacy_instance' => null, 739 'ctx' => $ctx, 740 ); 741 742 if ( null !== $owner_user_id ) { 743 $req['owner_user_id'] = $owner_user_id; 744 } 745 746 $resolved = WPBC_FE_Form_Source_Resolver::resolve( $req ); 747 748 // Same behavior as your content resolver: preview can fallback to published. 749 if ( 750 ( empty( $resolved['engine'] ) || ( 'bfb_db' !== $resolved['engine'] ) ) 751 && ( 'preview' === $form_status ) 752 ) { 753 $req['form_status'] = 'published'; 754 $resolved = WPBC_FE_Form_Source_Resolver::resolve( $req ); 755 } 756 757 if ( empty( $resolved['engine'] ) || ( 'bfb_db' !== $resolved['engine'] ) ) { 758 return array(); 759 } 760 761 $bfb_loader_args = array(); 762 763 if ( ! empty( $resolved['bfb_loader_args'] ) && is_array( $resolved['bfb_loader_args'] ) ) { 764 $bfb_loader_args = $resolved['bfb_loader_args']; 765 } 766 767 $bfb_pair = wpbc_bfb_get_booking_form_pair( $bfb_loader_args ); 768 769 $pair = array( 770 'form' => wpbc_extract__advanced_form_from_bfb_pair__for_field_names_listing( $bfb_pair ), 771 'content' => wpbc_extract__content_form_from_bfb_pair__for_field_names_listing( $bfb_pair ), 772 ); 773 774 if ( '' === trim( $pair['form'] ) && '' === trim( $pair['content'] ) ) { 775 return array(); 776 } 777 778 return $pair; 779 } 780 781 782 /** 783 * Get booking form pair (fields + show template) for listing/inspection purposes. 784 * 785 * - Legacy mode: returns legacy form + content. 786 * - BFB mode: uses resolver and returns advanced_form + content_form. 787 * 788 * @param int $resource_id 789 * @param string $form_name 790 * @param array $ctx 791 * 792 * @return array 585 793 */ 586 794 function wpbc_get__booking_form_pair__for_field_names_listing( $resource_id = 1, $form_name = 'standard', $ctx = array() ) { 587 795 796 $resource_id = absint( $resource_id ); 797 $form_name = sanitize_text_field( (string) $form_name ); 798 $ctx = ( is_array( $ctx ) ) ? $ctx : array(); 799 800 if ( '' === $form_name ) { 801 $form_name = 'standard'; 802 } 803 804 /** 805 * --------------------------------------------------------------------- 806 * Legacy baseline pair. 807 * --------------------------------------------------------------------- 808 */ 588 809 $pair = array( 589 'form' => wpbc_bf__replace_custom_html_shortcodes( get_bk_option( 'booking_form' ) ),590 'content' => wpbc_bf__replace_custom_html_shortcodes( get_bk_option( 'booking_form_show' ) ),810 'form' => '', 811 'content' => '', 591 812 ); 592 813 593 // Let BFB override both "form" and "content" if available. 594 if ( class_exists( 'WPBC_BFB_Booking_Data_Content_Resolver' ) ) { 595 596 // Recommended: add this method to the resolver (see section 3 below). 597 if ( method_exists( 'WPBC_BFB_Booking_Data_Content_Resolver', 'maybe_override_booking_form_pair_by_bfb' ) ) { 598 $pair = WPBC_BFB_Booking_Data_Content_Resolver::maybe_override_booking_form_pair_by_bfb( 599 $pair, 600 (int) $resource_id, 601 (string) $form_name, 602 '', // no form_data here 603 (is_array( $ctx ) ? $ctx : array()) 814 // Legacy "fields" configuration. 815 $pair['form'] = wpbc_get__booking_form_fields__configuration( $resource_id, $form_name ); 816 $pair['form'] = wpbc_bf__replace_custom_html_shortcodes( $pair['form'] ); 817 818 // Legacy "show/content" configuration. 819 if ( ! class_exists( 'wpdev_bk_personal' ) ) { 820 821 $pair['content'] = wpbc_simple_form__get_form_show__as_shortcodes(); 822 $pair['content'] = wpbc_bf__replace_custom_html_shortcodes( $pair['content'] ); 823 824 } else { 825 826 $pair['content'] = get_bk_option( 'booking_form_show' ); 827 $pair['content'] = wpbc_bf__replace_custom_html_shortcodes( $pair['content'] ); 828 829 if ( class_exists( 'wpdev_bk_biz_m' ) ) { 830 831 $my_booking_form_name = $form_name; 832 833 if ( empty( $my_booking_form_name ) ) { 834 $my_booking_form_name = apply_bk_filter( 'wpbc_get_default_custom_form', 'standard', $resource_id ); 835 } 836 837 if ( ( 'standard' !== $my_booking_form_name ) && ( '' !== $my_booking_form_name ) ) { 838 $pair['content'] = apply_bk_filter( 'wpdev_get_booking_form_content', $pair['content'], $my_booking_form_name ); 839 } 840 841 $pair['content'] = apply_bk_filter( 842 'wpbc_multiuser_get_booking_form_show_of_regular_user', 843 $pair['content'], 844 $resource_id, 845 $my_booking_form_name 604 846 ); 847 } 848 } 849 850 /** 851 * --------------------------------------------------------------------- 852 * BFB override. 853 * --------------------------------------------------------------------- 854 */ 855 $bfb_pair = wpbc_get__bfb_booking_form_pair__for_field_names_listing( $resource_id, $form_name, $ctx ); 856 857 if ( ! empty( $bfb_pair ) ) { 858 859 if ( isset( $bfb_pair['form'] ) && ( '' !== trim( (string) $bfb_pair['form'] ) ) ) { 860 $pair['form'] = (string) $bfb_pair['form']; 861 } 862 863 if ( isset( $bfb_pair['content'] ) && ( '' !== trim( (string) $bfb_pair['content'] ) ) ) { 864 $pair['content'] = (string) $bfb_pair['content']; 865 } 866 } 867 868 $pair['form'] = wpbc_bf__replace_custom_html_shortcodes( (string) $pair['form'] ); 869 $pair['content'] = wpbc_bf__replace_custom_html_shortcodes( (string) $pair['content'] ); 870 871 $pair['form'] = wpbc_lang( (string) $pair['form'] ); 872 $pair['content'] = wpbc_lang( (string) $pair['content'] ); 873 874 875 return $pair; 876 } 877 878 /** 879 * Get arr of all fields names from all booking forms (including custom). 880 * 881 * Legacy mode: 882 * - Keep previous behavior exactly as before. 883 * 884 * BFB mode: 885 * - Load form names via helper. 886 * - Load each pair through BFB-aware resolver logic. 887 * 888 * @return array 889 */ 890 function wpbc_get__in_all_forms__field_names_arr() { 891 892 $booking_form_fields_arr = array(); 893 894 $is_bfb_enabled = ( 895 class_exists( 'WPBC_Frontend_Settings' ) 896 && method_exists( 'WPBC_Frontend_Settings', 'is_bfb_enabled' ) 897 && WPBC_Frontend_Settings::is_bfb_enabled( null ) 898 ); 899 900 // --------------------------------------------------------------------- 901 // Legacy mode: keep previous behavior exactly. 902 // --------------------------------------------------------------------- 903 if ( ! $is_bfb_enabled ) { 904 905 $booking_form_fields_arr[] = array( 906 'name' => 'standard', 907 'form' => wpbc_bf__replace_custom_html_shortcodes( get_bk_option( 'booking_form' ) ), 908 'content' => wpbc_bf__replace_custom_html_shortcodes( get_bk_option( 'booking_form_show' ) ), 909 ); 910 911 $is_can = apply_bk_filter( 'multiuser_is_user_can_be_here', true, 'only_super_admin' ); 912 913 if ( ( $is_can ) || ( get_bk_option( 'booking_is_custom_forms_for_regular_users' ) === 'On' ) ) { 914 915 $booking_forms_extended = get_bk_option( 'booking_forms_extended' ); 916 $booking_forms_extended = maybe_unserialize( $booking_forms_extended ); 917 918 if ( is_array( $booking_forms_extended ) ) { 919 foreach ( $booking_forms_extended as $form_extended ) { 920 if ( is_array( $form_extended ) ) { 921 $booking_form_fields_arr[] = $form_extended; 922 } 923 } 924 } 925 } 926 927 // --------------------------------------------------------------------- 928 // BFB mode: use new resolver-aware logic. 929 // --------------------------------------------------------------------- 930 } else { 931 932 $ctx = wpbc_get_request_form_context(); 933 $ctx['form_status'] = 'published'; 934 935 $form_names = array( 'standard' ); 936 937 if ( 938 class_exists( 'WPBC_FE_Custom_Form_Helper' ) 939 && method_exists( 'WPBC_FE_Custom_Form_Helper', 'get_custom_booking_forms_list' ) 940 ) { 941 $owner_user_id = 0; 942 943 if ( method_exists( 'WPBC_FE_Custom_Form_Helper', 'wpbc_mu__get_current__owner_user_id' ) ) { 944 $owner_user_id = absint( WPBC_FE_Custom_Form_Helper::wpbc_mu__get_current__owner_user_id() ); 945 } 946 947 $ctx['owner_user_id'] = $owner_user_id; 948 949 $forms_list = WPBC_FE_Custom_Form_Helper::get_custom_booking_forms_list( 950 array( 951 'include_standard' => false, 952 'owner_user_id' => $owner_user_id, 953 'statuses' => array( 'published' ), 954 'list_mode' => 'auto', 955 ) 956 ); 957 958 if ( is_array( $forms_list ) ) { 959 foreach ( $forms_list as $form_data ) { 960 961 if ( empty( $form_data['name'] ) ) { 962 continue; 963 } 964 965 $form_name = sanitize_text_field( (string) $form_data['name'] ); 966 967 if ( ( '' !== $form_name ) && ( 'standard' !== $form_name ) ) { 968 $form_names[] = $form_name; 969 } 970 } 971 } 605 972 } else { 606 // Fallback: at least keep content resolved by BFB (you already have this method). 607 if ( method_exists( 'WPBC_BFB_Booking_Data_Content_Resolver', 'maybe_override_booking_form_show_by_bfb' ) ) { 608 $pair['content'] = WPBC_BFB_Booking_Data_Content_Resolver::maybe_override_booking_form_show_by_bfb( 609 $pair['content'], 610 (int) $resource_id, 611 (string) $form_name, 612 '', 613 (is_array( $ctx ) ? $ctx : array()) 614 ); 615 } 616 } 617 } 618 619 // Normalize keys. 620 if ( ! isset( $pair['form'] ) ) { 621 $pair['form'] = ''; 622 } 623 if ( ! isset( $pair['content'] ) ) { 624 $pair['content'] = ''; 625 } 626 627 $pair['form'] = (string) $pair['form']; 628 $pair['content'] = (string) $pair['content']; 629 630 return $pair; 631 } 632 633 /** 634 * Get arr of all Fields Names from all booking forms (including custom) 635 * 636 * @return array = [ 637 0: [ name = "standard", num = 8, listing = [ ... ] ], 638 1: [ 639 name = "minimal" 640 num = 7 641 listing = [ 642 labels = [ 643 0 = " adults" 644 1 = " children" 645 2 = " infants" 646 3 = " gender" 647 4 = " full_name" 648 5 = " email" 649 6 = " phone" 650 fields = {array[7]} 651 0 = " adults" 652 1 = " children" 653 2 = " infants" 654 3 = " gender" 655 4 = " full_name" 656 5 = " email" 657 6 = " phone" 658 fields_type = {array[7]} 659 0 = "select" 660 1 = "select" 661 2 = "select" 662 3 = "radio" 663 4 = "text" 664 5 = "email" 665 6 = "text" 666 ] 667 ] 668 2: [], ... 669 * ] 670 */ 671 function wpbc_get__in_all_forms__field_names_arr() { 672 673 $booking_form_fields_arr = array(); 674 $ctx = wpbc_get_request_form_context(); 675 676 $ctx['form_status'] = 'published'; 677 678 $pair = wpbc_get__booking_form_pair__for_field_names_listing( 1, 'standard', $ctx ); 679 680 $booking_form_fields_arr[] = array( 681 'name' => 'standard', 682 'form' => $pair['form'], 683 'content' => $pair['content'], 684 ); 685 686 /** 687 * Get custom booking form configurations: [ 688 * [ name = "minimal", 689 * form = "[calendar]...", 690 * content = "<div class="payment-content-form"> [name] ..." 691 * ], 692 * ... 693 * ] 694 */ 695 $is_can = apply_bk_filter( 'multiuser_is_user_can_be_here', true, 'only_super_admin' ); 696 if ( ( $is_can ) || ( get_bk_option( 'booking_is_custom_forms_for_regular_users' ) === 'On' ) ) { 697 $booking_forms_extended = get_bk_option( 'booking_forms_extended' ); 698 $booking_forms_extended = maybe_unserialize( $booking_forms_extended ); 699 if ( false !== $booking_forms_extended ) { 700 foreach ( $booking_forms_extended as $form_extended ) { 701 $booking_form_fields_arr[] = $form_extended; 702 } 703 } 704 } 705 973 974 // Fallback to legacy list only if helper is unavailable. 975 $is_can = apply_bk_filter( 'multiuser_is_user_can_be_here', true, 'only_super_admin' ); 976 977 if ( ( $is_can ) || ( get_bk_option( 'booking_is_custom_forms_for_regular_users' ) === 'On' ) ) { 978 979 $booking_forms_extended = get_bk_option( 'booking_forms_extended' ); 980 $booking_forms_extended = maybe_unserialize( $booking_forms_extended ); 981 982 if ( is_array( $booking_forms_extended ) ) { 983 foreach ( $booking_forms_extended as $form_extended_key => $form_extended ) { 984 985 $form_name = ''; 986 987 if ( is_array( $form_extended ) && ! empty( $form_extended['name'] ) ) { 988 $form_name = sanitize_text_field( (string) $form_extended['name'] ); 989 } elseif ( is_string( $form_extended_key ) ) { 990 $form_name = sanitize_text_field( (string) $form_extended_key ); 991 } 992 993 if ( ( '' !== $form_name ) && ( 'standard' !== $form_name ) ) { 994 $form_names[] = $form_name; 995 } 996 } 997 } 998 } 999 } 1000 1001 $form_names = array_values( array_unique( $form_names ) ); 1002 1003 foreach ( $form_names as $form_name ) { 1004 1005 $pair = wpbc_get__booking_form_pair__for_field_names_listing( 1006 wpbc_get_default_resource(), 1007 $form_name, 1008 $ctx 1009 ); 1010 1011 $booking_form_fields_arr[] = array( 1012 'name' => $form_name, 1013 'form' => $pair['form'], 1014 'content' => $pair['content'], 1015 ); 1016 } 1017 } 1018 1019 // --------------------------------------------------------------------- 1020 // Common parser for both legacy and BFB mode. 1021 // --------------------------------------------------------------------- 706 1022 foreach ( $booking_form_fields_arr as $form_key => $booking_form_element ) { 707 1023 708 $booking_form = $booking_form_element['form'];709 710 $types = 'text[*]?|email[*]?|time[*]?|textarea[*]?|select[*]?|selectbox[*]?|checkbox[*]?|radio|acceptance|captchac|captchar|file[*]?|quiz';711 $regex = '%\[\s*(' . $types . ')(\s+[a-zA-Z][0-9a-zA-Z:._-]*)([-0-9a-zA-Z:#_/|\s]*)?((?:\s*(?:"[^"]*"|\'[^\']*\'))*)?\s*\]%';1024 $booking_form = isset( $booking_form_element['form'] ) ? (string) $booking_form_element['form'] : ''; 1025 1026 $types = 'text[*]?|email[*]?|time[*]?|textarea[*]?|select[*]?|selectbox[*]?|checkbox[*]?|radio|acceptance|captchac|captchar|file[*]?|quiz'; 1027 $regex = '%\[\s*(' . $types . ')(\s+[a-zA-Z][0-9a-zA-Z:._-]*)([-0-9a-zA-Z:#_/|\s]*)?((?:\s*(?:"[^"]*"|\'[^\']*\'))*)?\s*\]%'; 712 1028 $regex2 = '%\[\s*(country[*]?|starttime[*]?|endtime[*]?)(\s*[a-zA-Z]*[0-9a-zA-Z:._-]*)([-0-9a-zA-Z:#_/|\s]*)*((?:\s*(?:"[^"]*"|\'[^\']*\'))*)?\s*\]%'; 713 $fields_count = preg_match_all($regex, $booking_form, $fields_matches) ; 714 $fields_count2 = preg_match_all($regex2, $booking_form, $fields_matches2) ; 715 716 //Gathering Together 2 arrays $fields_matches and $fields_matches2 717 foreach ($fields_matches2 as $key => $value) { 718 if ($key == 2) $value = $fields_matches2[1]; 719 foreach ($value as $v) { 720 $fields_matches[$key][count($fields_matches[$key])] = $v; 721 } 722 } 1029 1030 $fields_matches = array(); 1031 $fields_matches2 = array(); 1032 1033 $fields_count = preg_match_all( $regex, $booking_form, $fields_matches ); 1034 $fields_count2 = preg_match_all( $regex2, $booking_form, $fields_matches2 ); 1035 1036 foreach ( $fields_matches2 as $key => $value ) { 1037 1038 if ( 2 === (int) $key ) { 1039 $value = $fields_matches2[1]; 1040 } 1041 1042 if ( ! isset( $fields_matches[ $key ] ) || ! is_array( $fields_matches[ $key ] ) ) { 1043 $fields_matches[ $key ] = array(); 1044 } 1045 1046 foreach ( $value as $single_value ) { 1047 $fields_matches[ $key ][] = $single_value; 1048 } 1049 } 1050 723 1051 $fields_count += $fields_count2; 724 1052 725 1053 $booking_form_fields_arr[ $form_key ]['num'] = $fields_count; 726 $booking_form_fields_arr[ $form_key ]['listing'] = array(); //$fields_matches; 1054 $booking_form_fields_arr[ $form_key ]['listing'] = array(); 1055 1056 if ( ! isset( $fields_matches[1] ) ) { 1057 $fields_matches[1] = array(); 1058 } 1059 if ( ! isset( $fields_matches[2] ) ) { 1060 $fields_matches[2] = array(); 1061 } 727 1062 728 1063 $fields_matches[1] = array_map( 'trim', $fields_matches[1] ); … … 730 1065 731 1066 $booking_form_fields_arr[ $form_key ]['listing']['labels'] = array_map( 'ucfirst', $fields_matches[2] ); 732 $booking_form_fields_arr[ $form_key ]['listing']['fields'] = $fields_matches[2] ;1067 $booking_form_fields_arr[ $form_key ]['listing']['fields'] = $fields_matches[2]; 733 1068 734 1069 foreach ( $fields_matches[1] as $key_fm => $value_fm ) { … … 738 1073 $booking_form_fields_arr[ $form_key ]['listing']['fields_type'] = $fields_matches[1]; 739 1074 740 // Reset741 1075 unset( $booking_form_fields_arr[ $form_key ]['form'] ); 742 1076 unset( $booking_form_fields_arr[ $form_key ]['content'] ); … … 744 1078 745 1079 return $booking_form_fields_arr; 1080 } 1081 1082 /** 1083 * Get options for billing field assignment from all available booking forms. 1084 * 1085 * Important: 1086 * - Collect fields from standard, legacy custom, and BFB forms. 1087 * - Keep option VALUE as plain field name for backwards compatibility. 1088 * - Use the first found label as option title. 1089 * 1090 * @return array 1091 */ 1092 function wpbc_get__field_options__for_billing_assignment() { 1093 1094 $field_options = array( 1095 '' => __( 'Please select', 'booking' ), 1096 ); 1097 1098 $booking_forms = wpbc_get__in_all_forms__field_names_arr(); 1099 1100 if ( empty( $booking_forms ) || ! is_array( $booking_forms ) ) { 1101 return $field_options; 1102 } 1103 1104 $unique_fields = array(); 1105 1106 foreach ( $booking_forms as $single_booking_form ) { 1107 1108 if ( 1109 empty( $single_booking_form['listing'] ) 1110 || ! is_array( $single_booking_form['listing'] ) 1111 || empty( $single_booking_form['listing']['fields'] ) 1112 || ! is_array( $single_booking_form['listing']['fields'] ) 1113 ) { 1114 continue; 1115 } 1116 1117 $field_labels = array(); 1118 1119 if ( 1120 isset( $single_booking_form['listing']['labels'] ) 1121 && is_array( $single_booking_form['listing']['labels'] ) 1122 ) { 1123 $field_labels = $single_booking_form['listing']['labels']; 1124 } 1125 1126 foreach ( $single_booking_form['listing']['fields'] as $field_index => $field_name ) { 1127 1128 $field_name = trim( (string) $field_name ); 1129 1130 if ( '' === $field_name ) { 1131 continue; 1132 } 1133 1134 // Keep first found label/value pair. 1135 if ( isset( $unique_fields[ $field_name ] ) ) { 1136 continue; 1137 } 1138 1139 $field_label = isset( $field_labels[ $field_index ] ) ? trim( (string) $field_labels[ $field_index ] ) : ''; 1140 1141 if ( '' === $field_label ) { 1142 $field_label = $field_name; 1143 } 1144 1145 $unique_fields[ $field_name ] = $field_label; 1146 } 1147 } 1148 1149 foreach ( $unique_fields as $field_name => $field_label ) { 1150 $field_options[ $field_name ] = $field_label; 1151 } 1152 1153 return $field_options; 746 1154 } 747 1155 -
booking/trunk/includes/_functions/str_regex.php
r3291612 r3492420 9 9 * @link https://wpbookingcalendar.com/ 10 10 * @email info@wpbookingcalendar.com 11 * 12 * @file ../includes/_functions/str_regex.php 11 13 * 12 14 * @modified 2024-05-14 -
booking/trunk/includes/page-form-builder/assets/template-records/technical_support_form.php
r3488732 r3492420 22 22 stripcslashes( 23 23 <<<'WPBC_BFB_TEMPLATE_SETTINGS' 24 {\"options\":{\"booking_form_theme\":\"\",\"booking_form_layout_width\":\"100%\",\"booking_type_of_day_selections\":\" single\"},\"css_vars\":[],\"bfb_options\":{\"advanced_mode_source\":\"builder\"}}24 {\"options\":{\"booking_form_theme\":\"\",\"booking_form_layout_width\":\"100%\",\"booking_type_of_day_selections\":\"\"},\"css_vars\":[],\"bfb_options\":{\"advanced_mode_source\":\"builder\"}} 25 25 WPBC_BFB_TEMPLATE_SETTINGS 26 26 ) -
booking/trunk/includes/page-form-builder/assets/template-records/time_slots_20_min_2_steps_wizard.php
r3488732 r3492420 22 22 stripcslashes( 23 23 <<<'WPBC_BFB_TEMPLATE_SETTINGS' 24 {\"options\":{\"booking_form_theme\":\"\",\"booking_form_layout_width\":\"100%\",\"booking_type_of_day_selections\":\" single\"},\"css_vars\":[],\"bfb_options\":{\"advanced_mode_source\":\"builder\"}}24 {\"options\":{\"booking_form_theme\":\"\",\"booking_form_layout_width\":\"100%\",\"booking_type_of_day_selections\":\"\"},\"css_vars\":[],\"bfb_options\":{\"advanced_mode_source\":\"builder\"}} 25 25 WPBC_BFB_TEMPLATE_SETTINGS 26 26 ) -
booking/trunk/includes/page-form-builder/assets/template-records/time_slots_30_min_2_steps_wizard.php
r3488732 r3492420 22 22 stripcslashes( 23 23 <<<'WPBC_BFB_TEMPLATE_SETTINGS' 24 {\"options\":{\"booking_form_theme\":\"\",\"booking_form_layout_width\":\"100%\",\"booking_type_of_day_selections\":\" single\"},\"css_vars\":[],\"bfb_options\":{\"advanced_mode_source\":\"builder\"}}24 {\"options\":{\"booking_form_theme\":\"\",\"booking_form_layout_width\":\"100%\",\"booking_type_of_day_selections\":\"\"},\"css_vars\":[],\"bfb_options\":{\"advanced_mode_source\":\"builder\"}} 25 25 WPBC_BFB_TEMPLATE_SETTINGS 26 26 ) -
booking/trunk/includes/page-form-builder/assets/template-records/time_slots_start_duration_times_selection.php
r3488732 r3492420 22 22 stripcslashes( 23 23 <<<'WPBC_BFB_TEMPLATE_SETTINGS' 24 {\"options\":{\"booking_form_theme\":\"\",\"booking_form_layout_width\":\"100%\",\"booking_type_of_day_selections\":\" single\"},\"css_vars\":[],\"bfb_options\":{\"advanced_mode_source\":\"builder\"}}24 {\"options\":{\"booking_form_theme\":\"\",\"booking_form_layout_width\":\"100%\",\"booking_type_of_day_selections\":\"\"},\"css_vars\":[],\"bfb_options\":{\"advanced_mode_source\":\"builder\"}} 25 25 WPBC_BFB_TEMPLATE_SETTINGS 26 26 ) -
booking/trunk/includes/page-form-builder/assets/template-records/time_slots_start_end_times_1_hour_selection.php
r3488732 r3492420 22 22 stripcslashes( 23 23 <<<'WPBC_BFB_TEMPLATE_SETTINGS' 24 {\"options\":{\"booking_form_theme\":\"\",\"booking_form_layout_width\":\"100%\",\"booking_type_of_day_selections\":\" single\"},\"css_vars\":[],\"bfb_options\":{\"advanced_mode_source\":\"builder\"}}24 {\"options\":{\"booking_form_theme\":\"\",\"booking_form_layout_width\":\"100%\",\"booking_type_of_day_selections\":\"\"},\"css_vars\":[],\"bfb_options\":{\"advanced_mode_source\":\"builder\"}} 25 25 WPBC_BFB_TEMPLATE_SETTINGS 26 26 ) -
booking/trunk/readme.txt
r3491856 r3492420 6 6 Requires PHP: 5.6 7 7 Tested up to: 7.0 8 Stable tag: 10.15. 38 Stable tag: 10.15.4 9 9 License: GPLv2 or later 10 10 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 14 14 == Description == 15 15 16 = Booking Calendar - WordPress Booking Plugin for Appointments, Reservations, Rentals, andEvents =16 = Booking Calendar - Booking Plugin for Appointments, Reservations, Rentals, Events = 17 17 **WP Booking Calendar** is a flexible **WordPress booking plugin** for **appointments**, **reservations**, **rentals**, and **events**. Add a responsive **availability calendar** and **booking form** to your website, accept **online bookings**, and manage them from a modern admin panel. 18 18 … … 54 54 This new functionality brings a more modern, user-friendly, and flexible way to create forms in Booking Calendar, making form setup faster, clearer, and much more convenient for website owners. 55 55 56 > <strong>Full Day Bookings - Drag and Drop Booking Form Builder</strong><br />57 > Easily configure Booking Calendar for full-day bookings with the new Drag and Drop Booking Form Builder. The new Booking Calendar Form Builder makes it much easier to create flexible booking forms without manually editing form code. It is a simple and visual way to build booking forms for different use cases directly inside WordPress.58 59 https://www.youtube.com/watch?v=n_svjKULkc060 61 > <strong>Create a Time Slots Booking Form in minutes with the new Booking Calendar Form Builder.</strong><br />62 63 https://www.youtube.com/watch?v=6hV11Cfc61Q64 65 = Setup Wizard! =66 > <strong>Easy Time Appointments Configuration for your Bookings</strong><br />67 > Set up **appointment booking system** in less than 2.5 minutes. Designed with a user-friendly flow, the wizard takes you step-by-step through key settings, including booking type selection, calendar appearance, availability preferences, and more. This step-by-step setup helps you get your booking system ready for your business quickly and easily.68 69 https://www.youtube.com/watch?v=GYJWZJBFwXw70 71 > <strong>Changeover Multi-Day Bookings - Setup Wizard (Pro)</strong><br />72 > Configure multi-day bookings with specific check-in and check-out days, clearly marked with diagonal or vertical lines. Perfect for bookings that require split days. <br>**Available Pro versions**.73 74 https://www.youtube.com/watch?v=uCQ9JmHR8w475 76 56 = Perfect solution for any booking logic = 77 57 … … 93 73 - Or any other service where booking for a specific time is required 94 74 95 ### Simple steps to get started 96 97 = 1. Add booking form or availability calendar to your page = 75 = Full Day Bookings - Drag and Drop Booking Form Builder = 76 Easily configure Booking Calendar for full-day bookings with the new Drag and Drop Booking Form Builder. The new Booking Calendar Form Builder makes it much easier to create flexible booking forms without manually editing form code. It is a simple and visual way to build booking forms for different use cases directly inside WordPress. 77 78 https://www.youtube.com/watch?v=n_svjKULkc0 79 80 = Appointment Forms with Time Slots or Start Time + Service Duration Selection = 81 Create a time-slot booking form in just a few minutes with the new Booking Calendar Form Builder. Visually add the calendar, time fields, and contact fields, adjust the layout, and preview changes instantly — without manually editing form code. 82 83 https://www.youtube.com/watch?v=6hV11Cfc61Q 84 85 = Changeover Multi-Day Bookings - Setup Wizard (Pro) = 86 Configure multi-day bookings with specific check-in and check-out days, clearly marked with diagonal or vertical lines. Perfect for bookings that require split days. <br>**Available Pro versions**. 87 88 https://www.youtube.com/watch?v=uCQ9JmHR8w4 89 90 == Installation == 91 92 Installing the plugin is easy. Just follow one of the following methods: 93 94 = Install Booking Calendar from within Wordpress = 95 96 1. Visit the plugins page within your dashboard and select ‘Add New’ 97 2. Search for "Booking Calendar by oplugins" 98 3. Activate Booking Calendar from your Plugins page 99 4. You're done! 100 101 102 = Install Booking Calendar Manually = 103 104 1. From the dashboard of your site, navigate to Plugins --> Add New. 105 2. Select the Upload option and hit "Choose File." 106 3. When the popup appears select the booking.zip or booking-x.x.zip file from your desktop. (The 'x.x' will change depending on the current version number). 107 4. Follow the on-screen instructions and wait as the upload completes. 108 5. When it's finished, activate the plugin via the prompt. A message will show confirming activation was successful. 109 110 That's it! Just configure your settings and [insert booking form shortcode](https://wpbookingcalendar.com/faq/insert-booking-calendar-into-page/ ) into a page, and you're on your way to receive the bookings. Need help getting things started? Check out our [FAQ](https://wpbookingcalendar.com/faq/) and [video guides](https://wpbookingcalendar.com/help/) for help with settings and features. 111 112 == Frequently Asked Questions == 113 114 Please see [FAQ](https://wpbookingcalendar.com/faq/). 115 116 = All you need to know about booking process = 117 118 **Step 1: Select your desired date(s)** 119 Customers can select the date(s) they would like to book. The **Booking Calendar** plugin provides an easy-to-use calendar system that displays the availability of your property or service for those dates. 120 121 **Step 2: Select a time-slot (optional)** 122 If you offer appointments or reservations at specific times, you can configure the booking form to allow customers to select an available time-slot. To learn how to set it up, please [watch this video](https://youtu.be/-pOTMiyp6Q8?t=28s "Video guide how to configure time slots in Booking Calendar Free version"). 123 124 **Step 3: Fill in Booking Form Fields** 125 The form will ask for information such as your name, contact information, and other details needed to approve the booking. The booking form fields are customizable, allowing you to configure fields required for the booking. 126 127 **Step 4: Submit your booking and Receive Notification of New Booking** 128 After filling out the booking form, customers can submit the booking. The **Booking Calendar** plugin will notify the administrator about the new booking and send a confirmation email to customers that their booking has been received. 129 130 **Step 5: Manage Bookings** 131 Administrators can manage all reservations from the modern and easy-to-use admin booking panel. Easily find the required bookings, check the booking details, and modify the booking if needed, then approve or decline this reservation. Customers will receive an email confirmation about the approval or cancellation of their booking. 132 133 = Simple steps to get started = 134 **1. Add booking form or availability calendar to your page** 98 135 Easily insert the booking form on any page of your website using WordPress blocks or Booking Calendar widgets for sidebars or configure shortcode block in page builders like Elementor. Read more [here](https://wpbookingcalendar.com/faq/insert-booking-calendar-into-page/ "How to insert the booking form or availability calendar into the page?"). 99 136 100 = 2. Set initial unavailable days with just few clicks = 137 **2. Set initial unavailable days with just few clicks** 101 138 You can **define days availability** in just a 3 mouse clicks at Booking > Availability page. Simply select a range of days on the calendar, choose 'available' or 'unavailable' status, and apply. It’s that simple! 102 139 103 = 3. Configure booking form, email templates and other settings = 140 **3. Configure booking form, email templates and other settings** 104 141 Easily **customize** your **booking form** fields and add **[time slots](https://youtu.be/-pOTMiyp6Q8?t=28s "Video guide how to configure time slots in Booking Calendar Free version")** if needed. Configure **email** notifications and other settings such as the **calendar** appearance, booking admin panel functionality, and more... 105 142 106 = 4. Receive notifications and manage bookings = 143 **4. Receive notifications and manage bookings** 107 144 Get notified about a **new appointments** and manage them in a modern admin panel. **Approve**, **decline**, or **edit** specific bookings. Plus, you can get a complete picture of your schedule with the **calendar overview** in **day**, **week**, or **month** view mode. 108 145 109 = 5. Configure syncing of bookings with other services = 110 **Import** your **Google Calendar** events or make **2 ways sync** of your events by using **.ics feeds** with various services such as Airbnb, Booking.com, VRBO, HomeAway, TripAdvisor, FlipKey, and more... Thanks to native integration with [Booking Manager](https://wordpress.org/plugins/booking-manager/) plugin. 111 112 ### How it works? 113 114 - **Step 1:** Visitor select desired date(s) in calendar 115 - **Step 2:** Visitor selects a time-slot (optional) 116 - **Step 3:** Visitor fills in Booking Form and submits it 117 - **Step 4:** You receive a notification and manage the booking 118 119 ### Awesome features: 120 121 = New = 122 Super **easy set available/unavailable dates** in calendar with just three mouse clicks. 123 124 In Booking Calendar you can define days as available or unavailable in just a few clicks. Simply select a range of days on the calendar, choose 'available' or 'unavailable' status, and apply. It's that simple! 125 126 = General = 146 **5. Configure syncing of bookings with other services** 147 Import your **Google Calendar** events or make **2 ways sync** of your events by using **.ics feeds** with various services such as Airbnb, Booking.com, VRBO, HomeAway, TripAdvisor, FlipKey, and more... Thanks to native integration with [Booking Manager](https://wordpress.org/plugins/booking-manager/) plugin. 148 149 = Awesome features: = 150 151 **Setup Wizard!** 152 - Easy Time Appointments Configuration for your Bookings 153 - Set up **appointment booking system** in less than 2.5 minutes. Designed with a user-friendly flow, the wizard takes you step-by-step through key settings, including booking type selection, calendar appearance, availability preferences, and more. This step-by-step setup helps you get your booking system ready for your business quickly and easily. 154 155 https://www.youtube.com/watch?v=GYJWZJBFwXw 156 157 **Set Days Availability** 158 - Super **easy set available/unavailable dates** in calendar with just three mouse clicks. 159 - In Booking Calendar you can define days as available or unavailable in just a few clicks. Simply select a range of days on the calendar, choose 'available' or 'unavailable' status, and apply. It's that simple! 160 161 **General** 127 162 - **Modern** and **easy to use** interface. 128 163 - The plugin is designed to be a suitable for a vast array of businesses. … … 131 166 - **Multi language** support. Check all available languages at [this page](https://wordpress.org/plugins/booking/#support%20languages%20%28local%29 "Translations"). 132 167 133 = Easy to start using = 134 Booking Calendar is an easy solution to start receiving bookings.135 You can quickly [add the booking calendar](https://wpbookingcalendar.com/faq/insert-booking-calendar-into-page/) to your posts or pages using WordPress blocks or shortcodes. Additionally, you can add the booking calendar as a widget to your site's sidebar.136 Most of the settings come with predefined values and descriptions.137 138 = Bookings = 168 **Easy to start using** 169 - Booking Calendar is an easy solution to start receiving bookings. 170 - You can quickly [add the booking calendar](https://wpbookingcalendar.com/faq/insert-booking-calendar-into-page/) to your posts or pages using WordPress blocks or shortcodes. Additionally, you can add the booking calendar as a widget to your site's sidebar. 171 - Most of the settings come with predefined values and descriptions. 172 173 **Bookings** 139 174 - **Prevention of double bookings** - one booking per day or time slot. 140 175 - Alternatively, you can allow **unlimited bookings for the same date** and time within the same calendar. 141 176 - You can enable **pending bookings as available** in the calendar, which lets you receive multiple bookings for the same date until you manually approve one of them. You can receive as many bookings as you need to and stop receiving bookings on specific dates once you have approved a booking. 142 177 143 = Timeslots bookings = 144 **[Time slot bookings](https://youtu.be/-pOTMiyp6Q8?t=28s "Video guide how to configure time slots in Booking Calendar Free version")** are available in the Booking Calendar Free version, which allows you to receive bookings for available time-slots during a selected day. Customers can select time slots either in a time picker or from a dropdown list, depending on your settings at Settings General page in "Time Slots" section.145 146 = Calendar = 147 - Select a **calendar skin** that matches your website design. 148 - Or customize the calendar colors by [editing the CSS](https://wpbookingcalendar.com/faq/change-skin-and-colors/) styles. 149 - Choose to display [one or several months](https://wpbookingcalendar.com/faq/shortcode-booking-form/#booking-options) in the calendar view. 150 - Easily set the width of the calendar and the number of months in a row, such as [3x2 months](https://wpbookingcalendar.com/faq/shortcode-booking-form/#booking-options). 151 - Choose between **single** day or **multiple days** selection mode. 152 - Set the number of unavailable days in the calendar, starting from today. 153 - Specify particular weekdays as unavailable. 154 - Show a legend on the calendar to help visitors understand the status of each day. 155 156 = Booking Form = 178 **Timeslots bookings** 179 - [Time slot bookings](https://youtu.be/-pOTMiyp6Q8?t=28s "Video guide how to configure time slots in Booking Calendar Free version")** are available in the Booking Calendar Free version, which allows you to receive bookings for available time-slots during a selected day. Customers can select time slots either in a time picker or from a dropdown list, depending on your settings at Settings General page in "Time Slots" section. 180 181 **Calendar** 182 Select a **calendar skin** that matches your website design.<br> 183 Or customize the calendar colors by [editing the CSS](https://wpbookingcalendar.com/faq/change-skin-and-colors/) styles.<br> 184 Choose to display [one or several months](https://wpbookingcalendar.com/faq/shortcode-booking-form/#booking-options) in the calendar view.<br> 185 Easily set the width of the calendar and the number of months in a row, such as [3x2 months](https://wpbookingcalendar.com/faq/shortcode-booking-form/#booking-options).<br> 186 Choose between **single** day or **multiple days** selection mode.<br> 187 Set the number of unavailable days in the calendar, starting from today.<br> 188 Specify particular weekdays as unavailable.<br> 189 Show a legend on the calendar to help visitors understand the status of each day.<br> 190 191 **Booking Form** 157 192 Easily customize your booking form fields to capture all the necessary information for each booking. Choose which fields are required and which are optional, and customize field labels as needed. Plus, the booking form includes **CAPTCHA** support to prevent spam submissions. 158 193 159 = Timeline = 194 **Timeline** 160 195 [Timeline view](https://wpbookingcalendar.com/faq/shortcode-timeline/) allows you to display all your bookings in a yearly, monthly, or daily view on the front-end of your website, giving your visitors a quick and comprehensive overview of your schedule. 161 196 162 = Booking Admin Panel = 197 **Booking Admin Panel** 163 198 - Easily manage your bookings with a modern and clear [Booking Listing](https://ps.w.org/booking/assets/screenshot-03.gif?rev=2870020) panel or with the intuitive [Calendar Overview](https://ps.w.org/booking/assets/screenshot-04.png?rev=2870020) mode. 164 199 - The [Booking Listing](https://ps.w.org/booking/assets/screenshot-03.gif?rev=2870020) makes it very simple to find the required reservations. It provides searching by different criteria and immediate results based on keywords. … … 168 203 - Get the number of new bookings on the **booking dashboard section**. 169 204 170 = Google Calendar Integration = 205 **Google Calendar Integration** 171 206 - [Import events](https://wpbookingcalendar.com/faq/import-gc-events/) from your **Google Calendar** to the Booking Calendar plugin. 172 207 - With just one click, **add bookings to Google Calendar** from the Booking Listing page using export button near each booking(s). 173 208 174 = Sync bookings = 209 **Sync bookings** 175 210 - Easily **import and export** events using .ics feeds or files with native integration with our [Booking Manager](https://wordpress.org/plugins/booking-manager/) plugin. 176 211 - **[Import events](https://wpbookingcalendar.com/faq/#sync)** from various sources, such as Airbnb, Booking.com, HomeAway, TripAdvisor, VRBO, FlipKey, and any other calendar that uses the .ics format. … … 178 213 - **[Export bookings](https://wpbookingcalendar.com/faq/#sync)** by configuring custom URL for your.ics feed. This feed can then be imported into services that use the .ics (iCal) format, such as Google Calendar or Airbnb, etc... 179 214 180 = Email Notifications = 215 **Email Notifications** 181 216 Configure email confirmation to be sent to the site administrator and visitors for specific booking actions, such as new booking creation, approval or decline of bookings. You can customize the content and format of the emails, and also change the administrator email address to receive notifications. 182 217 183 = Other settings = 184 - Customizable **date format** for your bookings. 185 - **Restriction of access** to plugin menus for standard WordPress user roles. 186 218 **Other settings** 219 Customizable **date format** for your bookings.<br> 220 **Restriction of access** to plugin menus for standard WordPress user roles.<br> 221 <br> 187 222 And **much more**... Check ton of features in [premium versions](https://wpbookingcalendar.com/features/ "Booking Calendar Features list") of plugin. 188 223 189 ### Premium Features in paid versions 190 191 = Booking Calendar Personal (or higher versions) = 224 225 = Premium Features in paid versions = 226 227 **Booking Calendar Personal (or higher versions)** 192 228 - [Multiple booking resources (calendars)](https://wpbookingcalendar.com/features/#booking-resources) - create an unlimited number of booking resources (calendars), which can be your services, properties, or any other items that can be booked by visitors in separate unique calendars. 193 229 - [Advanced configuration of booking form and emails](https://wpbookingcalendar.com/features/#booking-form) - fully customize the appearance of your booking form and email templates. 194 230 - [Manage bookings](https://wpbookingcalendar.com/features/#manage-bookings) - perform various actions such as CSV export, adding notes, editing, duplicating, changing resources, and much more... 195 231 196 = Booking Calendar Business Small (or higher versions) = 232 **Booking Calendar Business Small (or higher versions)** 197 233 - [Online Payments](https://wpbookingcalendar.com/features/#payments) - accept online payments for your bookings, with support for various payment gateways like **Stripe, PayPal, Authorize.Net, Redsys**, and more. 198 234 - [Changeover Days](https://wpbookingcalendar.com/features/#change-over-days) - enable **split bookings** marked by vertical or diagonal lines, allowing visitors to check out and check in on the same date. … … 201 237 - [Advanced Hourly Bookings](https://wpbookingcalendar.com/features/#times) - increase the flexibility of your Booking Calendar by allowing visitors to book specific start and end times or duration of time, ensuring precise scheduling for your services. 202 238 203 = Booking Calendar Business Medium (or higher versions) = 239 **Booking Calendar Business Medium (or higher versions)** 204 240 - [Seasonal Prices](https://wpbookingcalendar.com/features/#rates) - customize the daily cost (rates) for different seasons or week days with fixed costs per day or as a percentage from original daily cost. 205 241 - [Multi-Day Pricing](https://wpbookingcalendar.com/features/#valuation-days) - set different cost of booking based on the number of selected days, and the ability to apply these costs only if the "Check In" day falls within a specific season. … … 215 251 - [Unavailable time before or after a booking](https://wpbookingcalendar.com/features/#unavailable-time-after-before-booking) - setting the number of minutes, hours, or days needed for cleaning or other services, applicable to bookings with time slots or change-over days feature. 216 252 217 = Booking Calendar Business Large (or higher versions) = 253 **Booking Calendar Business Large (or higher versions)** 218 254 - [Capacity and Availability](https://wpbookingcalendar.com/features/#capacity) - set the the maximum number of bookings that can be made per full day or time slots in calendar, and ensure that dates in the calendar are only available until the capacity is reached. 219 255 - [Search Availability](https://wpbookingcalendar.com/features/#search) - allows your website visitors to quickly search for available booking resources such as properties or services by entering check-in/out dates and other criteria like the number of guests or specific amenities. … … 221 257 - [Auto-Cancel Pending Bookings](https://wpbookingcalendar.com/features/#pending-available) - enable automatic cancellation of pending bookings for specific dates when you approve booking for the same resource. 222 258 223 = Booking Calendar MultiUser version = 259 **Booking Calendar MultiUser version** 224 260 - [MultiUser Booking Admin Panels](https://wpbookingcalendar.com/features/#multiuser) - enable each registered WordPress user to have their own individual booking admin panel, where they can see and manage only their own bookings, resources, and settings. This includes the ability to configure their own booking form, receive notifications to own separate emails, and activate payment gateways for their own payment accounts. 225 226 == Installation ==227 228 Installing the plugin is easy. Just follow one of the following methods:229 230 = Install Booking Calendar from within Wordpress =231 232 1. Visit the plugins page within your dashboard and select ‘Add New’233 2. Search for "Booking Calendar by oplugins"234 3. Activate Booking Calendar from your Plugins page235 4. You're done!236 237 238 = Install Booking Calendar Manually =239 240 1. From the dashboard of your site, navigate to Plugins --> Add New.241 2. Select the Upload option and hit "Choose File."242 3. When the popup appears select the booking.zip or booking-x.x.zip file from your desktop. (The 'x.x' will change depending on the current version number).243 4. Follow the on-screen instructions and wait as the upload completes.244 5. When it's finished, activate the plugin via the prompt. A message will show confirming activation was successful.245 246 That's it! Just configure your settings and [insert booking form shortcode](https://wpbookingcalendar.com/faq/insert-booking-calendar-into-page/ ) into a page, and you're on your way to receive the bookings. Need help getting things started? Check out our [FAQ](https://wpbookingcalendar.com/faq/) and [video guides](https://wpbookingcalendar.com/help/) for help with settings and features.247 248 == Frequently Asked Questions ==249 250 Please see [FAQ](https://wpbookingcalendar.com/faq/).251 252 = All you need to know about booking process =253 254 **Step 1: Select your desired date(s)**255 Customers can select the date(s) they would like to book. The **Booking Calendar** plugin provides an easy-to-use calendar system that displays the availability of your property or service for those dates.256 257 **Step 2: Select a time-slot (optional)**258 If you offer appointments or reservations at specific times, you can configure the booking form to allow customers to select an available time-slot. To learn how to set it up, please [watch this video](https://youtu.be/-pOTMiyp6Q8?t=28s "Video guide how to configure time slots in Booking Calendar Free version").259 260 **Step 3: Fill in Booking Form Fields**261 The form will ask for information such as your name, contact information, and other details needed to approve the booking. The booking form fields are customizable, allowing you to configure fields required for the booking.262 263 **Step 4: Submit your booking and Receive Notification of New Booking**264 After filling out the booking form, customers can submit the booking. The **Booking Calendar** plugin will notify the administrator about the new booking and send a confirmation email to customers that their booking has been received.265 266 **Step 5: Manage Bookings**267 Administrators can manage all reservations from the modern and easy-to-use admin booking panel. Easily find the required bookings, check the booking details, and modify the booking if needed, then approve or decline this reservation. Customers will receive an email confirmation about the approval or cancellation of their booking.268 261 269 262 = Privacy Notices = … … 316 309 317 310 If you have some questions, which you haven't found at [FAQ](https://wpbookingcalendar.com/faq/) you can post them at [technical help board](https://wpbookingcalendar.com/support/) 318 = Video Tutorials =319 320 Please see [Video Guides](https://wpbookingcalendar.com/help/).321 311 322 312 … … 333 323 334 324 == Changelog == 325 = 10.15.4 = 326 - Changes in **all** versions: 327 * **Fix**: Showing options for the "Booking Quantity Control" field, regarding custom booking forms in the new Forms Builder. This fix related to the Booking Calendar Business Large or higher version. (10.15.4.1) 328 335 329 = 10.15.3 = 336 330 - Changes in **all** versions: -
booking/trunk/wpdev-booking.php
r3491589 r3492420 8 8 Text Domain: booking 9 9 Domain Path: /languages/ 10 Version: 10.15. 310 Version: 10.15.4 11 11 License: GPLv2 or later 12 12 */ … … 35 35 36 36 if ( ! defined( 'WP_BK_VERSION_NUM' ) ) { 37 define( 'WP_BK_VERSION_NUM', '10.15. 3' );37 define( 'WP_BK_VERSION_NUM', '10.15.4' ); 38 38 } 39 39 if ( ! defined( 'WP_BK_MINOR_UPDATE' ) ) {
Note: See TracChangeset
for help on using the changeset viewer.