PluginProbe
Booking Calendar / 11.8.1
Booking Calendar v11.8.1
11.9.1 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 All 206 releases
← All changes | includes/_functions/booking_data__parse.php +586 -126 10.10 → 11.8.1 View file →
@@ -1,17 +1,18 @@
1 1 <?php
2 2 /**
3 -* @version 1.0
4 -* @package Booking Calendar
5 -* @subpackage Booking Data Parsing functions
6 -* @category Functions
7 -*
8 -* @author wpdevelop
9 -* @link https://wpbookingcalendar.com/
10 -* @email [email protected]
11 -*
12 -* @modified 2024-05-14
13 -*/
3 + * @version 1.0
4 + * @package Booking Calendar
5 + * @subpackage Booking Data Parsing functions
6 + * @category Functions
7 + *
8 + * @author wpdevelop
9 + * @link https://wpbookingcalendar.com/
10 + * @email [email protected]
11 + *
12 + * @modified 2024-05-14
13 + * @file ../includes/_functions/booking_data__parse.php
14 + */
14 15
15 16 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
16 17
17 18 // =====================================================================================================================
@@ -271,9 +272,9 @@
271 272 'unknown_shortcodes_replace_by' => ''
272 273 );
273 274 $params = wp_parse_args( $params, $defaults );
274 275
275 - $booking_form_show = wpbc_get__booking_form_data_configuration( $resource_id, $form_data );
276 + $booking_form_show = wpbc_get__booking_form_data_configuration( $resource_id, $form_data, $params );
276 277
277 278 $booking_data_arr = wpbc_get_parsed_booking_data_arr( $form_data, $resource_id, array( 'get' => 'value' ) );
278 279
279 280 foreach ( $booking_data_arr as $key_param => $value_param ) { // FixIn: 6.1.1.4.
@@ -364,39 +365,60 @@
364 365 *
365 366 */
366 367 function wpbc_get__booking_form_fields__configuration( $resource_id = 1, $form_name = 'standard' ) {
367 368
368 - if ( ! class_exists( 'wpdev_bk_personal' ) ) {
369 - $booking_form_configuration = wpbc_simple_form__get_booking_form__as_shortcodes();
370 - } else {
371 - $booking_form_configuration = get_bk_option( 'booking_form' );
369 + $pair = wpbc_get__bfb_booking_form_pair__for_field_names_listing( $resource_id, $form_name, wpbc_get_request_form_context() );
372 370
373 - if ( class_exists( 'wpdev_bk_biz_m' ) ) {
371 + // Keep the complete BFB source intact. Languages use separate custom forms.
372 + $booking_form_configuration = isset( $pair['form'] ) ? (string) $pair['form'] : '';
374 373
375 - if ( $form_name != 'standard' ) {
374 + return $booking_form_configuration;
375 +}
376 376
377 - $booking_form_configuration = apply_bk_filter( 'wpdev_get_booking_form', $booking_form_configuration, $form_name );
378 - }
379 377
380 - // Get default Custom Form for resource, if $form_name == '' wpbc_get__booking_form_fields__configuration(1,'')
381 - if ( empty( $form_name ) ) {
378 +/**
379 + * Load BFB preview payload from transient (for booking created inside preview iframe).
380 + *
381 + * @param array $ctx
382 + * @return array|null
383 + */
384 +function wpbc_bfb_preview__maybe_get_payload_from_context( $ctx ) {
382 385
383 - $resource_default_custom_form_name = apply_bk_filter( 'wpbc_get_default_custom_form', 'standard', $resource_id );
386 + $ctx = ( is_array( $ctx ) ) ? $ctx : array();
384 387
385 - $booking_form_configuration = apply_bk_filter( 'wpdev_get_booking_form', $booking_form_configuration, $resource_default_custom_form_name );
386 - }
388 + $user_id = isset( $ctx['user_id'] ) ? absint( $ctx['user_id'] ) : 0;
389 + $form_id = isset( $ctx['wpbc_bfb_preview_form_id'] ) ? absint( $ctx['wpbc_bfb_preview_form_id'] ) : 0;
390 + $token = isset( $ctx['wpbc_bfb_preview_token'] ) ? sanitize_key( $ctx['wpbc_bfb_preview_token'] ) : '';
391 + $nonce = isset( $ctx['wpbc_bfb_preview_nonce'] ) ? sanitize_text_field( $ctx['wpbc_bfb_preview_nonce'] ) : '';
387 392
388 - //MU :: if resource of "Regular User" - then GET STANDARD user form ( if ( get_bk_option( 'booking_is_custom_forms_for_regular_users' ) !== 'On' ) )
389 - $booking_form_configuration = apply_bk_filter( 'wpbc_multiuser_get_booking_form_fields_configuration_of_regular_user', $booking_form_configuration, $resource_id, $form_name ); // FixIn: 8.1.3.19.
393 + if ( $user_id <= 0 || $form_id <= 0 || '' === $token ) {
394 + return null;
395 + }
396 +
397 + // Optional hardening: verify nonce if present.
398 + if ( '' !== $nonce ) {
399 + if ( ! wp_verify_nonce( $nonce, 'wpbc_bfb_preview_' . $token ) ) {
400 + return null;
390 401 }
391 402 }
392 403
393 - // Language
394 - $booking_form_configuration = wpbc_lang( $booking_form_configuration );
404 + // Optional hardening: capability check (preview is admin-only anyway).
405 + $cap = ( function_exists( 'wpbc_bfb_get_manage_cap' ) ) ? wpbc_bfb_get_manage_cap() : 'manage_options';
406 + if ( ! is_user_logged_in() || ! current_user_can( $cap ) ) {
407 + return null;
408 + }
395 409
396 - return $booking_form_configuration;
410 + $transient_key = 'wpbc_bfb_preview_' . $user_id . '_' . $form_id . '_' . $token;
411 +
412 + $data = get_transient( $transient_key );
413 + if ( empty( $data ) || ! is_array( $data ) ) {
414 + return null;
415 + }
416 +
417 + return $data;
397 418 }
398 419
420 +
399 421 /**
400 422 * Get configuration of 'BOOKING FORM DATA' from - Booking > Settings > Form page
401 423 *
402 424 * - 1. <= BS : 'Booking form show' configuration from standard form in versions up to Business Small version ,
@@ -409,50 +431,57 @@
409 431 * @param string $form_data Form data here, required in >= BM, because such form_data can contain fields about used custom booking form
410 432 *
411 433 * @return string
412 434 */
413 -function wpbc_get__booking_form_data_configuration( $resource_id = 1, $form_data = '' ) {
435 +function wpbc_get__booking_form_data_configuration( $resource_id = 1, $form_data = '', $params = array() ) {
414 436
415 - if ( ! class_exists( 'wpdev_bk_personal' ) ) {
437 + // FixIn: 2026-02-05 - allow preview booking submissions to use preview "content_form".
438 + $ctx = wp_parse_args( ( is_array( $params ) ? $params : array() ), wpbc_get_request_form_context() );
416 439
417 - $booking_form_show = wpbc_simple_form__get_form_show__as_shortcodes();
418 - $booking_form_show = wpbc_bf__replace_custom_html_shortcodes( $booking_form_show );
440 + $form_status = ( isset( $ctx['form_status'] ) ) ? sanitize_key( $ctx['form_status'] ) : 'published';
419 441
420 - } else {
442 + if ( 'preview' === $form_status ) {
421 443
422 - $booking_form_show = get_bk_option( 'booking_form_show' );
423 - $booking_form_show = wpbc_bf__replace_custom_html_shortcodes( $booking_form_show );
444 + $payload = wpbc_bfb_preview__maybe_get_payload_from_context( $ctx );
424 445
425 - if ( class_exists( 'wpdev_bk_biz_m' ) ) {
446 + // content_form is exactly the "Booking form show" template exported for preview session.
447 + if ( ! empty( $payload ) && isset( $payload['content_form'] ) && ( '' !== (string) $payload['content_form'] ) ) {
448 + return (string) $payload['content_form'];
449 + }
450 + }
426 451
427 - if ( false !== strpos( $form_data, 'wpbc_custom_booking_form' . $resource_id . '^' ) ) { // FixIn: 9.4.3.12.
452 + $resource_id = (int) $resource_id;
453 + $form_data = (string) $form_data;
454 + $my_booking_form_name = 'standard';
428 455
429 - $custom_booking_form_name = substr( $form_data, strpos( $form_data, 'wpbc_custom_booking_form' . $resource_id . '^' ) + strlen( 'wpbc_custom_booking_form' . $resource_id . '^' ) );
430 - if ( false !== strpos( $custom_booking_form_name, '~' ) ) {
431 - $custom_booking_form_name = substr( $custom_booking_form_name, 0, strpos( $custom_booking_form_name, '~' ) );
432 - }
433 - $booking_form_show = apply_bk_filter( 'wpdev_get_booking_form_content', $booking_form_show, $custom_booking_form_name );
434 - $my_booking_form_name = $custom_booking_form_name;
435 - } else {
456 + // Maybe get name of custom booking form, that was saved in the booking data.
457 + if ( false !== strpos( $form_data, 'wpbc_custom_booking_form' . $resource_id . '^' ) ) { // FixIn: 9.4.3.12.
436 458
437 - // BM :: Get default Custom Form of Resource
438 - $my_booking_form_name = apply_bk_filter( 'wpbc_get_default_custom_form', 'standard', $resource_id );
439 - if ( ( $my_booking_form_name != 'standard' ) && ( ! empty( $my_booking_form_name ) ) ) {
440 - $booking_form_show = apply_bk_filter( 'wpdev_get_booking_form_content', $booking_form_show, $my_booking_form_name );
441 - }
442 - }
459 + $custom_booking_form_name = substr( $form_data, strpos( $form_data, 'wpbc_custom_booking_form' . $resource_id . '^' ) + strlen( 'wpbc_custom_booking_form' . $resource_id . '^' ) );
443 460
444 - //MU :: if resource of "Regular User" - then GET STANDARD user form ( if ( get_bk_option( 'booking_is_custom_forms_for_regular_users' ) !== 'On' ) )
445 - $booking_form_show = apply_bk_filter( 'wpbc_multiuser_get_booking_form_show_of_regular_user', $booking_form_show, $resource_id, $my_booking_form_name ); // FixIn: 8.1.3.19.
461 + if ( false !== strpos( $custom_booking_form_name, '~' ) ) {
462 + $custom_booking_form_name = substr( $custom_booking_form_name, 0, strpos( $custom_booking_form_name, '~' ) );
446 463 }
464 + if ( ! empty( $custom_booking_form_name ) ) {
465 + $my_booking_form_name = $custom_booking_form_name;
466 + }
447 467 }
448 468
449 - // Language
450 - $booking_form_show = wpbc_lang( $booking_form_show );
451 469
470 + if ( 'standard' === $my_booking_form_name || '' === $my_booking_form_name ) {
471 + $resource_default_custom_form_name = apply_bk_filter( 'wpbc_get_default_custom_form', 'standard', $resource_id );
472 + if ( ! empty( $resource_default_custom_form_name ) ) {
473 + $my_booking_form_name = $resource_default_custom_form_name;
474 + }
475 + }
476 +
477 + $booking_form_show = WPBC_BFB_Booking_Data_Content_Resolver::maybe_override_booking_form_show_by_bfb( '', $resource_id, $my_booking_form_name, $form_data, $ctx );
478 +
479 + // Keep the complete BFB content template intact. Languages use separate custom forms.
452 480 return $booking_form_show;
453 481 }
454 482
483 +
455 484 // -------------------------------------------------------------------------------------------------------------
456 485
457 486 /**
458 487 * Replace resource_ID of booking in 'form_data'
@@ -472,99 +501,365 @@
472 501
473 502 return $new__form_data__str;
474 503 }
475 504
505 +// FixIn: 10.15.4.1.
506 +/**
507 + * Extract "advanced_form" from BFB loader result.
508 + *
509 + * @param mixed $bfb_pair
510 + *
511 + * @return string
512 + */
513 +function wpbc_extract__advanced_form_from_bfb_pair__for_field_names_listing( $bfb_pair ) {
476 514
515 + $containers = array();
516 +
517 + if ( ! is_array( $bfb_pair ) ) {
518 + return '';
519 + }
520 +
521 + /**
522 + * Safety:
523 + * Do not override if loader already fell back to legacy.
524 + */
525 + if ( isset( $bfb_pair['source'] ) && ( 'builder' !== $bfb_pair['source'] ) ) {
526 + return '';
527 + }
528 +
529 + $containers[] = $bfb_pair;
530 +
531 + if ( isset( $bfb_pair['pair'] ) && is_array( $bfb_pair['pair'] ) ) {
532 + $containers[] = $bfb_pair['pair'];
533 + }
534 +
535 + if ( isset( $bfb_pair['form'] ) && is_array( $bfb_pair['form'] ) ) {
536 + $containers[] = $bfb_pair['form'];
537 + }
538 +
539 + foreach ( $containers as $container ) {
540 +
541 + if ( isset( $container['form'] ) && is_string( $container['form'] ) ) {
542 + return (string) $container['form'];
543 + }
544 +
545 + if ( isset( $container['advanced_form'] ) && is_string( $container['advanced_form'] ) ) {
546 + return (string) $container['advanced_form'];
547 + }
548 + }
549 +
550 + return '';
551 +}
552 +
553 +
477 554 /**
478 - * Get arr of all Fields Names from all booking forms (including custom)
555 + * Extract "content_form" from BFB loader result.
479 556 *
480 - * @return array = [
481 - 0: [ name = "standard", num = 8, listing = [ ... ] ],
482 - 1: [
483 - name = "minimal"
484 - num = 7
485 - listing = [
486 - labels = [
487 - 0 = " adults"
488 - 1 = " children"
489 - 2 = " infants"
490 - 3 = " gender"
491 - 4 = " full_name"
492 - 5 = " email"
493 - 6 = " phone"
494 - fields = {array[7]}
495 - 0 = " adults"
496 - 1 = " children"
497 - 2 = " infants"
498 - 3 = " gender"
499 - 4 = " full_name"
500 - 5 = " email"
501 - 6 = " phone"
502 - fields_type = {array[7]}
503 - 0 = "select"
504 - 1 = "select"
505 - 2 = "select"
506 - 3 = "radio"
507 - 4 = "text"
508 - 5 = "email"
509 - 6 = "text"
510 - ]
511 - ]
512 - 2: [], ...
513 - * ]
557 + * @param mixed $bfb_pair
558 + *
559 + * @return string
514 560 */
515 -function wpbc_get__in_all_forms__field_names_arr() {
561 +function wpbc_extract__content_form_from_bfb_pair__for_field_names_listing( $bfb_pair ) {
516 562
517 - $booking_form_fields_arr = array();
518 - $booking_form_fields_arr[] = array( 'name' => 'standard', 'form' => wpbc_bf__replace_custom_html_shortcodes( get_bk_option( 'booking_form' ) ), 'content' => wpbc_bf__replace_custom_html_shortcodes( get_bk_option( 'booking_form_show' ) ) );
563 + $containers = array();
519 564
565 + if ( ! is_array( $bfb_pair ) ) {
566 + return '';
567 + }
568 +
520 569 /**
521 - * Get custom booking form configurations: [
522 - * [ name = "minimal",
523 - * form = "[calendar]...",
524 - * content = "<div class="payment-content-form"> [name] ..."
525 - * ],
526 - * ...
527 - * ]
570 + * Safety:
571 + * Do not override if loader already fell back to legacy.
528 572 */
529 - $is_can = apply_bk_filter( 'multiuser_is_user_can_be_here', true, 'only_super_admin' );
530 - if ( ( $is_can ) || ( get_bk_option( 'booking_is_custom_forms_for_regular_users' ) === 'On' ) ) {
531 - $booking_forms_extended = get_bk_option( 'booking_forms_extended' );
532 - $booking_forms_extended = maybe_unserialize( $booking_forms_extended );
533 - if ( false !== $booking_forms_extended ) {
534 - foreach ( $booking_forms_extended as $form_extended ) {
535 - $booking_form_fields_arr[] = $form_extended;
573 + if ( isset( $bfb_pair['source'] ) && ( 'builder' !== $bfb_pair['source'] ) ) {
574 + return '';
575 + }
576 +
577 + $containers[] = $bfb_pair;
578 +
579 + if ( isset( $bfb_pair['pair'] ) && is_array( $bfb_pair['pair'] ) ) {
580 + $containers[] = $bfb_pair['pair'];
581 + }
582 +
583 + if ( isset( $bfb_pair['form'] ) && is_array( $bfb_pair['form'] ) ) {
584 + $containers[] = $bfb_pair['form'];
585 + }
586 +
587 + foreach ( $containers as $container ) {
588 +
589 + if ( isset( $container['content'] ) && is_string( $container['content'] ) ) {
590 + return (string) $container['content'];
591 + }
592 +
593 + if ( isset( $container['content_form'] ) && is_string( $container['content_form'] ) ) {
594 + return (string) $container['content_form'];
595 + }
596 + }
597 +
598 + return '';
599 +}
600 +
601 +
602 +/**
603 + * Maybe get booking form pair from BFB using the same resolver chain as front-end rendering.
604 + *
605 + * @param int $resource_id
606 + * @param string $form_name
607 + * @param array $ctx
608 + *
609 + * @return array
610 + */
611 +function wpbc_get__bfb_booking_form_pair__for_field_names_listing( $resource_id = 1, $form_name = 'standard', $ctx = array() ) {
612 +
613 + $resource_id = absint( $resource_id );
614 + $form_name = sanitize_text_field( (string) $form_name );
615 + $ctx = ( is_array( $ctx ) ) ? $ctx : array();
616 +
617 + if ( '' === $form_name ) {
618 + $form_name = 'standard';
619 + }
620 +
621 + $owner_user_id = isset( $ctx['owner_user_id'] ) ? absint( $ctx['owner_user_id'] ) : null;
622 +
623 + if ( ! class_exists( 'WPBC_FE_Form_Source_Resolver' ) ) {
624 + return array();
625 + }
626 +
627 + if ( ! function_exists( 'wpbc_bfb_get_booking_form_pair' ) ) {
628 + return array();
629 + }
630 +
631 + $form_status = isset( $ctx['form_status'] ) ? sanitize_key( $ctx['form_status'] ) : 'published';
632 +
633 + if ( in_array( $form_status, array( 'publish', 'published' ), true ) ) {
634 + $form_status = 'published';
635 + }
636 + if ( 'preview' !== $form_status ) {
637 + $form_status = 'published';
638 + }
639 +
640 + /**
641 + * Preview payload shortcut.
642 + */
643 + if (
644 + ( 'preview' === $form_status )
645 + && function_exists( 'wpbc_bfb_preview__maybe_get_payload_from_context' )
646 + ) {
647 + $payload = wpbc_bfb_preview__maybe_get_payload_from_context( $ctx );
648 +
649 + if ( ! empty( $payload ) && is_array( $payload ) ) {
650 +
651 + $pair = array(
652 + 'form' => isset( $payload['advanced_form'] ) ? (string) $payload['advanced_form'] : '',
653 + 'content' => isset( $payload['content_form'] ) ? (string) $payload['content_form'] : '',
654 + );
655 +
656 + if ( ( '' !== trim( $pair['form'] ) ) || ( '' !== trim( $pair['content'] ) ) ) {
657 + return $pair;
536 658 }
537 659 }
538 660 }
539 661
662 + $req = array(
663 + 'resource_id' => $resource_id,
664 + 'form_slug' => $form_name,
665 + 'form_status' => $form_status,
666 + 'custom_params' => array(),
667 + 'legacy_instance' => null,
668 + 'ctx' => $ctx,
669 + );
670 +
671 + if ( null !== $owner_user_id ) {
672 + $req['owner_user_id'] = $owner_user_id;
673 + }
674 +
675 + $resolved = WPBC_FE_Form_Source_Resolver::resolve( $req );
676 +
677 + // Same behavior as your content resolver: preview can fallback to published.
678 + if (
679 + ( empty( $resolved['engine'] ) || ( 'bfb_db' !== $resolved['engine'] ) )
680 + && ( 'preview' === $form_status )
681 + ) {
682 + $req['form_status'] = 'published';
683 + $resolved = WPBC_FE_Form_Source_Resolver::resolve( $req );
684 + }
685 +
686 + if ( empty( $resolved['engine'] ) || ( 'bfb_db' !== $resolved['engine'] ) ) {
687 + return array();
688 + }
689 +
690 + $bfb_loader_args = array();
691 +
692 + if ( ! empty( $resolved['bfb_loader_args'] ) && is_array( $resolved['bfb_loader_args'] ) ) {
693 + $bfb_loader_args = $resolved['bfb_loader_args'];
694 + }
695 +
696 + $bfb_pair = wpbc_bfb_get_booking_form_pair( $bfb_loader_args );
697 +
698 + $pair = array(
699 + 'form' => wpbc_extract__advanced_form_from_bfb_pair__for_field_names_listing( $bfb_pair ),
700 + 'content' => wpbc_extract__content_form_from_bfb_pair__for_field_names_listing( $bfb_pair ),
701 + );
702 +
703 + if ( '' === trim( $pair['form'] ) && '' === trim( $pair['content'] ) ) {
704 + return array();
705 + }
706 +
707 + return $pair;
708 +}
709 +
710 +
711 +/**
712 + * Get booking form pair (fields + show template) for listing/inspection purposes.
713 + *
714 + * Uses BFB resolver and returns advanced_form + content_form.
715 + *
716 + * @param int $resource_id
717 + * @param string $form_name
718 + * @param array $ctx
719 + *
720 + * @return array
721 + */
722 +function wpbc_get__booking_form_pair__for_field_names_listing( $resource_id = 1, $form_name = 'standard', $ctx = array() ) {
723 +
724 + $resource_id = absint( $resource_id );
725 + $form_name = sanitize_text_field( (string) $form_name );
726 + $ctx = ( is_array( $ctx ) ) ? $ctx : array();
727 +
728 + if ( '' === $form_name ) {
729 + $form_name = 'standard';
730 + }
731 +
732 + $bfb_pair = wpbc_get__bfb_booking_form_pair__for_field_names_listing( $resource_id, $form_name, $ctx );
733 + $pair = is_array( $bfb_pair ) ? $bfb_pair : array();
734 + $pair = wp_parse_args( $pair, array( 'form' => '', 'content' => '' ) );
735 +
736 + $pair['form'] = wpbc_bf__replace_custom_html_shortcodes( (string) $pair['form'] );
737 + $pair['content'] = wpbc_bf__replace_custom_html_shortcodes( (string) $pair['content'] );
738 +
739 + // Do not interpret inline [lang=LOCALE] markers as whole-form language blocks.
740 + return $pair;
741 +}
742 +
743 +/**
744 + * Get arr of all fields names from all booking forms (including custom).
745 + *
746 + * Load form names through BFB helpers and inspect each stored form pair.
747 + *
748 + * @return array
749 + */
750 +function wpbc_get__in_all_forms__field_names_arr() {
751 +
752 + $booking_form_fields_arr = array();
753 +
754 + $ctx = wpbc_get_request_form_context();
755 + $ctx['form_status'] = 'published';
756 +
757 + $form_names = array( 'standard' );
758 +
759 + if (
760 + class_exists( 'WPBC_FE_Custom_Form_Helper' )
761 + && method_exists( 'WPBC_FE_Custom_Form_Helper', 'get_custom_booking_forms_list' )
762 + ) {
763 + $owner_user_id = 0;
764 +
765 + if ( method_exists( 'WPBC_FE_Custom_Form_Helper', 'wpbc_mu__get_current__owner_user_id' ) ) {
766 + $owner_user_id = absint( WPBC_FE_Custom_Form_Helper::wpbc_mu__get_current__owner_user_id() );
767 + }
768 +
769 + $ctx['owner_user_id'] = $owner_user_id;
770 +
771 + $forms_list = WPBC_FE_Custom_Form_Helper::get_custom_booking_forms_list(
772 + array(
773 + 'include_standard' => false,
774 + 'owner_user_id' => $owner_user_id,
775 + 'statuses' => array( 'published' ),
776 + 'list_mode' => 'bfb',
777 + )
778 + );
779 +
780 + if ( is_array( $forms_list ) ) {
781 + foreach ( $forms_list as $form_data ) {
782 +
783 + if ( empty( $form_data['name'] ) ) {
784 + continue;
785 + }
786 +
787 + $form_name = sanitize_text_field( (string) $form_data['name'] );
788 +
789 + if ( ( '' !== $form_name ) && ( 'standard' !== $form_name ) ) {
790 + $form_names[] = $form_name;
791 + }
792 + }
793 + }
794 + }
795 +
796 + $form_names = array_values( array_unique( $form_names ) );
797 +
798 + foreach ( $form_names as $form_name ) {
799 +
800 + $pair = wpbc_get__booking_form_pair__for_field_names_listing(
801 + wpbc_get_default_resource(),
802 + $form_name,
803 + $ctx
804 + );
805 +
806 + $booking_form_fields_arr[] = array(
807 + 'name' => $form_name,
808 + 'form' => $pair['form'],
809 + 'content' => $pair['content'],
810 + );
811 + }
812 +
813 + // ---------------------------------------------------------------------
814 + // Common parser.
815 + // ---------------------------------------------------------------------
540 816 foreach ( $booking_form_fields_arr as $form_key => $booking_form_element ) {
541 817
542 - $booking_form = $booking_form_element['form'];
818 + $booking_form = isset( $booking_form_element['form'] ) ? (string) $booking_form_element['form'] : '';
543 819
544 - $types = 'text[*]?|email[*]?|time[*]?|textarea[*]?|select[*]?|selectbox[*]?|checkbox[*]?|radio|acceptance|captchac|captchar|file[*]?|quiz';
545 - $regex = '%\[\s*(' . $types . ')(\s+[a-zA-Z][0-9a-zA-Z:._-]*)([-0-9a-zA-Z:#_/|\s]*)?((?:\s*(?:"[^"]*"|\'[^\']*\'))*)?\s*\]%';
820 + $types = 'text[*]?|email[*]?|time[*]?|textarea[*]?|select[*]?|selectbox[*]?|checkbox[*]?|radio|acceptance|captchac|captchar|file[*]?|quiz';
821 + $regex = '%\[\s*(' . $types . ')(\s+[a-zA-Z][0-9a-zA-Z:._-]*)([-0-9a-zA-Z:#_/|\s]*)?((?:\s*(?:"[^"]*"|\'[^\']*\'))*)?\s*\]%';
546 822 $regex2 = '%\[\s*(country[*]?|starttime[*]?|endtime[*]?)(\s*[a-zA-Z]*[0-9a-zA-Z:._-]*)([-0-9a-zA-Z:#_/|\s]*)*((?:\s*(?:"[^"]*"|\'[^\']*\'))*)?\s*\]%';
547 - $fields_count = preg_match_all($regex, $booking_form, $fields_matches) ;
548 - $fields_count2 = preg_match_all($regex2, $booking_form, $fields_matches2) ;
549 823
550 - //Gathering Together 2 arrays $fields_matches and $fields_matches2
551 - foreach ($fields_matches2 as $key => $value) {
552 - if ($key == 2) $value = $fields_matches2[1];
553 - foreach ($value as $v) {
554 - $fields_matches[$key][count($fields_matches[$key])] = $v;
824 + $fields_matches = array();
825 + $fields_matches2 = array();
826 +
827 + $fields_count = preg_match_all( $regex, $booking_form, $fields_matches );
828 + $fields_count2 = preg_match_all( $regex2, $booking_form, $fields_matches2 );
829 +
830 + foreach ( $fields_matches2 as $key => $value ) {
831 +
832 + if ( 2 === (int) $key ) {
833 + $value = $fields_matches2[1];
555 834 }
835 +
836 + if ( ! isset( $fields_matches[ $key ] ) || ! is_array( $fields_matches[ $key ] ) ) {
837 + $fields_matches[ $key ] = array();
838 + }
839 +
840 + foreach ( $value as $single_value ) {
841 + $fields_matches[ $key ][] = $single_value;
842 + }
556 843 }
844 +
557 845 $fields_count += $fields_count2;
558 846
559 847 $booking_form_fields_arr[ $form_key ]['num'] = $fields_count;
560 - $booking_form_fields_arr[ $form_key ]['listing'] = array(); //$fields_matches;
848 + $booking_form_fields_arr[ $form_key ]['listing'] = array();
561 849
850 + if ( ! isset( $fields_matches[1] ) ) {
851 + $fields_matches[1] = array();
852 + }
853 + if ( ! isset( $fields_matches[2] ) ) {
854 + $fields_matches[2] = array();
855 + }
856 +
562 857 $fields_matches[1] = array_map( 'trim', $fields_matches[1] );
563 858 $fields_matches[2] = array_map( 'trim', $fields_matches[2] );
564 859
565 860 $booking_form_fields_arr[ $form_key ]['listing']['labels'] = array_map( 'ucfirst', $fields_matches[2] );
566 - $booking_form_fields_arr[ $form_key ]['listing']['fields'] = $fields_matches[2] ;
861 + $booking_form_fields_arr[ $form_key ]['listing']['fields'] = $fields_matches[2];
567 862
568 863 foreach ( $fields_matches[1] as $key_fm => $value_fm ) {
569 864 $fields_matches[1][ $key_fm ] = trim( str_replace( '*', '', $value_fm ) );
570 865 }
@@ -570,9 +865,8 @@
570 865 }
571 866
572 867 $booking_form_fields_arr[ $form_key ]['listing']['fields_type'] = $fields_matches[1];
573 868
574 - // Reset
575 869 unset( $booking_form_fields_arr[ $form_key ]['form'] );
576 870 unset( $booking_form_fields_arr[ $form_key ]['content'] );
577 871 }
578 872
@@ -578,8 +872,82 @@
578 872
579 873 return $booking_form_fields_arr;
580 874 }
581 875
876 +/**
877 + * Get options for billing field assignment from all available booking forms.
878 + *
879 + * Important:
880 + * - Collect fields from standard, legacy custom, and BFB forms.
881 + * - Keep option VALUE as plain field name for backwards compatibility.
882 + * - Use the first found label as option title.
883 + *
884 + * @return array
885 + */
886 +function wpbc_get__field_options__for_billing_assignment() {
887 +
888 + $field_options = array(
889 + '' => __( 'Please select', 'booking' ),
890 + );
891 +
892 + $booking_forms = wpbc_get__in_all_forms__field_names_arr();
893 +
894 + if ( empty( $booking_forms ) || ! is_array( $booking_forms ) ) {
895 + return $field_options;
896 + }
897 +
898 + $unique_fields = array();
899 +
900 + foreach ( $booking_forms as $single_booking_form ) {
901 +
902 + if (
903 + empty( $single_booking_form['listing'] )
904 + || ! is_array( $single_booking_form['listing'] )
905 + || empty( $single_booking_form['listing']['fields'] )
906 + || ! is_array( $single_booking_form['listing']['fields'] )
907 + ) {
908 + continue;
909 + }
910 +
911 + $field_labels = array();
912 +
913 + if (
914 + isset( $single_booking_form['listing']['labels'] )
915 + && is_array( $single_booking_form['listing']['labels'] )
916 + ) {
917 + $field_labels = $single_booking_form['listing']['labels'];
918 + }
919 +
920 + foreach ( $single_booking_form['listing']['fields'] as $field_index => $field_name ) {
921 +
922 + $field_name = trim( (string) $field_name );
923 +
924 + if ( '' === $field_name ) {
925 + continue;
926 + }
927 +
928 + // Keep first found label/value pair.
929 + if ( isset( $unique_fields[ $field_name ] ) ) {
930 + continue;
931 + }
932 +
933 + $field_label = isset( $field_labels[ $field_index ] ) ? trim( (string) $field_labels[ $field_index ] ) : '';
934 +
935 + if ( '' === $field_label ) {
936 + $field_label = $field_name;
937 + }
938 +
939 + $unique_fields[ $field_name ] = $field_label;
940 + }
941 + }
942 +
943 + foreach ( $unique_fields as $field_name => $field_label ) {
944 + $field_options[ $field_name ] = $field_label;
945 + }
946 +
947 + return $field_options;
948 +}
949 +
582 950 // -------------------------------------------------------------------------------------------------------------
583 951
584 952 /**
585 953 * Get arr with booking form fields values, after parsing form_data. Avoid to use this function in a future.
@@ -705,14 +1073,27 @@
705 1073 $booking_form_show = str_replace( '[' . $type_name . ']', $value, $booking_form_show );
706 1074 }
707 1075 }
708 1076
709 - if (! isset($all_fields_array_without_types[ 'booking_resource_id' ])) $all_fields_array_without_types[ 'booking_resource_id' ] = $bktype;
710 - if (! isset($all_fields_array_without_types[ 'resource_id' ])) $all_fields_array_without_types[ 'resource_id' ] = $bktype;
711 - if (! isset($all_fields_array_without_types[ 'type_id' ])) $all_fields_array_without_types[ 'type_id' ] = $bktype;
1077 + if ( ! isset( $all_fields_array_without_types['booking_resource_id'] ) ) {
1078 + $all_fields_array_without_types['booking_resource_id'] = $bktype;
1079 + }
1080 + if ( ! isset( $all_fields_array_without_types['resource_id'] ) ) {
1081 + $all_fields_array_without_types['resource_id'] = $bktype;
1082 + }
1083 + if ( ! isset( $all_fields_array_without_types['type_id'] ) ) {
1084 + $all_fields_array_without_types['type_id'] = $bktype;
1085 + }
712 1086
713 - if (! isset($all_fields_array_without_types[ 'type' ])) $all_fields_array_without_types[ 'type' ] = $bktype;
714 - if (! isset($all_fields_array_without_types[ 'resource' ])) $all_fields_array_without_types[ 'resource' ] = $bktype;
1087 + if ( ! isset( $all_fields_array_without_types['type'] ) ) {
1088 + $all_fields_array_without_types['type'] = $bktype;
1089 + }
1090 + if ( ! isset( $all_fields_array_without_types['resource'] ) ) {
1091 + $all_fields_array_without_types['resource'] = wpbc_get_resource_title( $bktype );
1092 + }
1093 + if ( ! isset( $all_fields_array_without_types['resource_title'] ) ) {
1094 + $all_fields_array_without_types['resource_title'] = wpbc_get_resource_title( $bktype );
1095 + }
715 1096
716 1097 foreach ($extended_params as $key_param=>$value_param) {
717 1098 if (! isset($all_fields_array_without_types[ $key_param ])) $all_fields_array_without_types[ $key_param ] = $value_param;
718 1099 }
@@ -755,5 +1136,84 @@
755 1136 }
756 1137 }
757 1138
758 1139 return $return_array;
1140 +}
1141 +
1142 +
1143 +/**
1144 + * Check whether custom booking forms are enabled for the current user.
1145 + *
1146 + * This function determines if the current user is allowed to access custom booking forms
1147 + * based on plugin version and user permissions. It checks:
1148 + * - If the business version of the plugin is active (`wpdev_bk_biz_m` class exists).
1149 + * - If the user is a super admin (via `multiuser_is_user_can_be_here` filter).
1150 + * - If regular users are allowed to use custom forms (via `booking_is_custom_forms_for_regular_users` option).
1151 + *
1152 + * @return bool True if custom forms are enabled for the current user; false otherwise.
1153 + */
1154 +function wpbc_is_custom_forms_enabled() {
1155 +
1156 + if ( ! class_exists( 'wpdev_bk_biz_m' ) ) {
1157 + return false;
1158 + }
1159 +
1160 + $is_super_admin = apply_bk_filter( 'multiuser_is_user_can_be_here', true, 'only_super_admin' );
1161 + $custom_forms_allowed = ( 'On' === get_bk_option( 'booking_is_custom_forms_for_regular_users' ) );
1162 +
1163 + return $is_super_admin || $custom_forms_allowed;
1164 +}
1165 +
1166 +// ---------------------------------------------------------------------------------------------------------------------
1167 +// == Shortcode Replacers ==
1168 +// ---------------------------------------------------------------------------------------------------------------------
1169 +/**
1170 + * Replace folowing shortcodes in the booking form at Booking > Settings > Fields page:
1171 + * [bookingresource show='id'] - to booking resource ID
1172 + * [bookingresource show='title'] - to booking resource Title
1173 + * [bookingresource show='cost'] - to booking resource Cost
1174 + * [bookingresource show='capacity'] - to booking resource Capacity
1175 + *
1176 + * @param string $return_form
1177 + * @param int $resource_id
1178 + *
1179 + * @return string
1180 + */
1181 +function wpbc_replace_bookingresource_info_in_form( $return_form, $resource_id ) { // FixIn: 5.4.5.4.
1182 +
1183 + $patterns = array();
1184 +
1185 + $parameters = array( 'id', 'title', 'cost', 'capacity' );
1186 + foreach ( $parameters as $parameter ) {
1187 + $patterns[] = '/\[bookingresource\s*show=\'' . $parameter . '\'\\s*]/';
1188 + }
1189 +
1190 + $replaced_form = $return_form;
1191 +
1192 + $replacements = array( $resource_id );
1193 +
1194 + if ( function_exists( 'get_booking_resource_attr' ) ) {
1195 + $booking_resource_attr = get_booking_resource_attr( $resource_id );
1196 +
1197 + if ( ! empty( $booking_resource_attr ) ) {
1198 +
1199 + if ( isset( $booking_resource_attr->title ) ) {
1200 + $bk_res_title = wpbc_lang( $booking_resource_attr->title );
1201 + $replacements[] = $bk_res_title;
1202 + } else {
1203 + $replacements[] = '';
1204 + }
1205 +
1206 + if ( ( class_exists( 'wpdev_bk_biz_s' ) ) && ( isset ( $booking_resource_attr->cost ) ) ) {
1207 +
1208 + $replacements[] = wpbc_get_cost_with_currency_for_user( $booking_resource_attr->cost, $resource_id );
1209 +
1210 + } else {
1211 + $replacements[] = '';
1212 + }
1213 + }
1214 + $replaced_form = preg_replace( $patterns, $replacements, $return_form );
1215 + }
1216 +
1217 +
1218 + return $replaced_form;
759 1219 }