| @@ -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 | } |