PluginProbe
Booking Calendar / 11.8.2
Booking Calendar v11.8.2
11.8.2 11.8.1 11.8 11.7 11.6.1 11.6 11.5 11.4.3 11.4.2 11.4.1 11.4 11.3 11.2.1 11.2 11.1 11.0 10.15.7 10.15.6 10.1.3 10.10 10.10.1 10.10.2 10.11 10.11.2 10.11.3 All 202 releases
← All changes | includes/_functions/booking_data__parse.php +572 -129 10.1011.8.2 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 info@wpbookingcalendar.com
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 info@wpbookingcalendar.com
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,348 @@
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
540 - foreach ( $booking_form_fields_arr as $form_key => $booking_form_element ) {
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 + );
541 670
542 - $booking_form = $booking_form_element['form'];
671 + if ( null !== $owner_user_id ) {
672 + $req['owner_user_id'] = $owner_user_id;
673 + }
543 674
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*\]%';
546 - $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) ;
675 + $resolved = WPBC_FE_Form_Source_Resolver::resolve( $req );
549 676
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;
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 + }
555 792 }
556 793 }
557 - $fields_count += $fields_count2;
794 + }
558 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 + // ---------------------------------------------------------------------
816 + foreach ( $booking_form_fields_arr as $form_key => $booking_form_element ) {
817 +
818 + $booking_form = isset( $booking_form_element['form'] ) ? (string) $booking_form_element['form'] : '';
819 +
820 + // Keep field-assignment inventories aligned with the shared shortcode parser. Builder choice fields can
821 + // contain named attributes such as default="1", which the former duplicate regex did not recognize.
822 + $parsed_booking_fields = '' !== trim( $booking_form ) ? wpbc_get_fields_from_booking_form( $booking_form ) : false;
823 + $fields_count = 0;
824 + $fields_matches = array_fill( 0, 5, array() );
825 +
826 + if ( false !== $parsed_booking_fields ) {
827 + list( $fields_count, $fields_matches ) = $parsed_booking_fields;
828 + }
829 +
559 830 $booking_form_fields_arr[ $form_key ]['num'] = $fields_count;
560 - $booking_form_fields_arr[ $form_key ]['listing'] = array(); //$fields_matches;
831 + $booking_form_fields_arr[ $form_key ]['listing'] = array();
561 832
833 + if ( ! isset( $fields_matches[1] ) ) {
834 + $fields_matches[1] = array();
835 + }
836 + if ( ! isset( $fields_matches[2] ) ) {
837 + $fields_matches[2] = array();
838 + }
839 +
562 840 $fields_matches[1] = array_map( 'trim', $fields_matches[1] );
563 841 $fields_matches[2] = array_map( 'trim', $fields_matches[2] );
564 842
565 843 $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] ;
844 + $booking_form_fields_arr[ $form_key ]['listing']['fields'] = $fields_matches[2];
567 845
568 846 foreach ( $fields_matches[1] as $key_fm => $value_fm ) {
569 847 $fields_matches[1][ $key_fm ] = trim( str_replace( '*', '', $value_fm ) );
570 848 }
@@ -570,9 +848,8 @@
570 848 }
571 849
572 850 $booking_form_fields_arr[ $form_key ]['listing']['fields_type'] = $fields_matches[1];
573 851
574 - // Reset
575 852 unset( $booking_form_fields_arr[ $form_key ]['form'] );
576 853 unset( $booking_form_fields_arr[ $form_key ]['content'] );
577 854 }
578 855
@@ -578,8 +855,82 @@
578 855
579 856 return $booking_form_fields_arr;
580 857 }
581 858
859 +/**
860 + * Get options for billing field assignment from all available booking forms.
861 + *
862 + * Important:
863 + * - Collect fields from standard, legacy custom, and BFB forms.
864 + * - Keep option VALUE as plain field name for backwards compatibility.
865 + * - Use the first found label as option title.
866 + *
867 + * @return array
868 + */
869 +function wpbc_get__field_options__for_billing_assignment() {
870 +
871 + $field_options = array(
872 + '' => __( 'Please select', 'booking' ),
873 + );
874 +
875 + $booking_forms = wpbc_get__in_all_forms__field_names_arr();
876 +
877 + if ( empty( $booking_forms ) || ! is_array( $booking_forms ) ) {
878 + return $field_options;
879 + }
880 +
881 + $unique_fields = array();
882 +
883 + foreach ( $booking_forms as $single_booking_form ) {
884 +
885 + if (
886 + empty( $single_booking_form['listing'] )
887 + || ! is_array( $single_booking_form['listing'] )
888 + || empty( $single_booking_form['listing']['fields'] )
889 + || ! is_array( $single_booking_form['listing']['fields'] )
890 + ) {
891 + continue;
892 + }
893 +
894 + $field_labels = array();
895 +
896 + if (
897 + isset( $single_booking_form['listing']['labels'] )
898 + && is_array( $single_booking_form['listing']['labels'] )
899 + ) {
900 + $field_labels = $single_booking_form['listing']['labels'];
901 + }
902 +
903 + foreach ( $single_booking_form['listing']['fields'] as $field_index => $field_name ) {
904 +
905 + $field_name = trim( (string) $field_name );
906 +
907 + if ( '' === $field_name ) {
908 + continue;
909 + }
910 +
911 + // Keep first found label/value pair.
912 + if ( isset( $unique_fields[ $field_name ] ) ) {
913 + continue;
914 + }
915 +
916 + $field_label = isset( $field_labels[ $field_index ] ) ? trim( (string) $field_labels[ $field_index ] ) : '';
917 +
918 + if ( '' === $field_label ) {
919 + $field_label = $field_name;
920 + }
921 +
922 + $unique_fields[ $field_name ] = $field_label;
923 + }
924 + }
925 +
926 + foreach ( $unique_fields as $field_name => $field_label ) {
927 + $field_options[ $field_name ] = $field_label;
928 + }
929 +
930 + return $field_options;
931 +}
932 +
582 933 // -------------------------------------------------------------------------------------------------------------
583 934
584 935 /**
585 936 * Get arr with booking form fields values, after parsing form_data. Avoid to use this function in a future.
@@ -705,14 +1056,27 @@
705 1056 $booking_form_show = str_replace( '[' . $type_name . ']', $value, $booking_form_show );
706 1057 }
707 1058 }
708 1059
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;
1060 + if ( ! isset( $all_fields_array_without_types['booking_resource_id'] ) ) {
1061 + $all_fields_array_without_types['booking_resource_id'] = $bktype;
1062 + }
1063 + if ( ! isset( $all_fields_array_without_types['resource_id'] ) ) {
1064 + $all_fields_array_without_types['resource_id'] = $bktype;
1065 + }
1066 + if ( ! isset( $all_fields_array_without_types['type_id'] ) ) {
1067 + $all_fields_array_without_types['type_id'] = $bktype;
1068 + }
712 1069
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;
1070 + if ( ! isset( $all_fields_array_without_types['type'] ) ) {
1071 + $all_fields_array_without_types['type'] = $bktype;
1072 + }
1073 + if ( ! isset( $all_fields_array_without_types['resource'] ) ) {
1074 + $all_fields_array_without_types['resource'] = wpbc_get_resource_title( $bktype );
1075 + }
1076 + if ( ! isset( $all_fields_array_without_types['resource_title'] ) ) {
1077 + $all_fields_array_without_types['resource_title'] = wpbc_get_resource_title( $bktype );
1078 + }
715 1079
716 1080 foreach ($extended_params as $key_param=>$value_param) {
717 1081 if (! isset($all_fields_array_without_types[ $key_param ])) $all_fields_array_without_types[ $key_param ] = $value_param;
718 1082 }
@@ -755,5 +1119,84 @@
755 1119 }
756 1120 }
757 1121
758 1122 return $return_array;
1123 +}
1124 +
1125 +
1126 +/**
1127 + * Check whether custom booking forms are enabled for the current user.
1128 + *
1129 + * This function determines if the current user is allowed to access custom booking forms
1130 + * based on plugin version and user permissions. It checks:
1131 + * - If the business version of the plugin is active (`wpdev_bk_biz_m` class exists).
1132 + * - If the user is a super admin (via `multiuser_is_user_can_be_here` filter).
1133 + * - If regular users are allowed to use custom forms (via `booking_is_custom_forms_for_regular_users` option).
1134 + *
1135 + * @return bool True if custom forms are enabled for the current user; false otherwise.
1136 + */
1137 +function wpbc_is_custom_forms_enabled() {
1138 +
1139 + if ( ! class_exists( 'wpdev_bk_biz_m' ) ) {
1140 + return false;
1141 + }
1142 +
1143 + $is_super_admin = apply_bk_filter( 'multiuser_is_user_can_be_here', true, 'only_super_admin' );
1144 + $custom_forms_allowed = ( 'On' === get_bk_option( 'booking_is_custom_forms_for_regular_users' ) );
1145 +
1146 + return $is_super_admin || $custom_forms_allowed;
1147 +}
1148 +
1149 +// ---------------------------------------------------------------------------------------------------------------------
1150 +// == Shortcode Replacers ==
1151 +// ---------------------------------------------------------------------------------------------------------------------
1152 +/**
1153 + * Replace folowing shortcodes in the booking form at Booking > Settings > Fields page:
1154 + * [bookingresource show='id'] - to booking resource ID
1155 + * [bookingresource show='title'] - to booking resource Title
1156 + * [bookingresource show='cost'] - to booking resource Cost
1157 + * [bookingresource show='capacity'] - to booking resource Capacity
1158 + *
1159 + * @param string $return_form
1160 + * @param int $resource_id
1161 + *
1162 + * @return string
1163 + */
1164 +function wpbc_replace_bookingresource_info_in_form( $return_form, $resource_id ) { // FixIn: 5.4.5.4.
1165 +
1166 + $patterns = array();
1167 +
1168 + $parameters = array( 'id', 'title', 'cost', 'capacity' );
1169 + foreach ( $parameters as $parameter ) {
1170 + $patterns[] = '/\[bookingresource\s*show=\'' . $parameter . '\'\\s*]/';
1171 + }
1172 +
1173 + $replaced_form = $return_form;
1174 +
1175 + $replacements = array( $resource_id );
1176 +
1177 + if ( function_exists( 'get_booking_resource_attr' ) ) {
1178 + $booking_resource_attr = get_booking_resource_attr( $resource_id );
1179 +
1180 + if ( ! empty( $booking_resource_attr ) ) {
1181 +
1182 + if ( isset( $booking_resource_attr->title ) ) {
1183 + $bk_res_title = wpbc_lang( $booking_resource_attr->title );
1184 + $replacements[] = $bk_res_title;
1185 + } else {
1186 + $replacements[] = '';
1187 + }
1188 +
1189 + if ( ( class_exists( 'wpdev_bk_biz_s' ) ) && ( isset ( $booking_resource_attr->cost ) ) ) {
1190 +
1191 + $replacements[] = wpbc_get_cost_with_currency_for_user( $booking_resource_attr->cost, $resource_id );
1192 +
1193 + } else {
1194 + $replacements[] = '';
1195 + }
1196 + }
1197 + $replaced_form = preg_replace( $patterns, $replacements, $return_form );
1198 + }
1199 +
1200 +
1201 + return $replaced_form;
759 1202 }