| 1 |
<?php |
| 2 |
/** |
| 3 |
* Universal Booking Form shortcode renderer. |
| 4 |
* |
| 5 |
* @package Booking Calendar. |
| 6 |
* @author wpdevelop, oplugins |
| 7 |
* @web-site https://wpbookingcalendar.com/ |
| 8 |
* @email info@wpbookingcalendar.com |
| 9 |
* |
| 10 |
* @modified 2025-12-08 |
| 11 |
* @version 1.0 |
| 12 |
* @file: includes/page-form-builder/form-render/bfb-form-render.php |
| 13 |
*/ |
| 14 |
|
| 15 |
if ( ! defined( 'ABSPATH' ) ) { |
| 16 |
exit; // Exit if accessed directly. |
| 17 |
} |
| 18 |
|
| 19 |
/** |
| 20 |
* Universal Booking Form shortcode renderer. |
| 21 |
* |
| 22 |
* - Safe to call from widgets, shortcodes, preview service, etc. |
| 23 |
* |
| 24 |
* @param string $form Raw booking form markup with shortcodes. |
| 25 |
* @param array $args { |
| 26 |
* Optional. Rendering context. |
| 27 |
* |
| 28 |
* @type int|string $booking_type Booking resource ID. |
| 29 |
* @type array $current_edit_booking Parsed booking data for "edit booking" mode. |
| 30 |
* } |
| 31 |
* @return string Parsed HTML of the booking form. |
| 32 |
*/ |
| 33 |
function wpbc_render_booking_form_shortcodes( $form, $args = array(), $req = array() ) { |
| 34 |
|
| 35 |
if ( ! is_string( $form ) || $form === '' ) { |
| 36 |
return ''; |
| 37 |
} |
| 38 |
|
| 39 |
$defaults = array( |
| 40 |
'booking_type' => 1, |
| 41 |
'current_edit_booking' => array(), |
| 42 |
); |
| 43 |
|
| 44 |
$args = wp_parse_args( $args, $defaults ); |
| 45 |
|
| 46 |
$req = wp_parse_args( |
| 47 |
$req, |
| 48 |
array( |
| 49 |
'resource_id' => (int) $args['booking_type'], |
| 50 |
'current_resource_id' => (int) $args['booking_type'], |
| 51 |
'form_slug' => 'standard', |
| 52 |
'current_edit_booking' => array(), |
| 53 |
'current_edit_booking_id' => false, |
| 54 |
) |
| 55 |
); |
| 56 |
|
| 57 |
// Graceful fallback if engine is not loaded for some reason. |
| 58 |
if ( ! class_exists( 'WPBC_BFB_FormShortcodeEngine' ) ) { |
| 59 |
return $form; |
| 60 |
} |
| 61 |
|
| 62 |
$engine = new WPBC_BFB_FormShortcodeEngine(); |
| 63 |
|
| 64 |
// Info: Hook for addons. Filter the engine instance before assigning context. Allows 3rd-party add-ons to wrap / extend the engine. |
| 65 |
$engine = apply_filters( 'wpbc_booking_form_shortcode_engine', $engine, $form, $args ); |
| 66 |
|
| 67 |
// === Pass runtime context regarding, booking editing === |
| 68 |
$engine->current_resource_id = (string) $req['current_resource_id']; |
| 69 |
$engine->current_edit_booking = isset( $req['current_edit_booking'] ) ? (array) $req['current_edit_booking'] : array(); |
| 70 |
|
| 71 |
// Info: Hook for addons. Filter raw form content just before shortcode parsing. |
| 72 |
$form = apply_filters( 'wpbc_booking_form_content__before_shortcodes', $form, $args ); |
| 73 |
|
| 74 |
// === Engine render === |
| 75 |
$html = $engine->render( $form ); |
| 76 |
|
| 77 |
// Re-update HINT shortcodes: [cost_hint], ... add JS for Conditional sections: [condition name="weekday-condition" type="weekday" value="*"] ... [/condition] . |
| 78 |
$html = apply_bk_filter( 'wpbc_update_bookingform_content__after_load', $html, $engine->current_resource_id, $req['form_slug'] ); |
| 79 |
|
| 80 |
// Re-update other hints, such as availability times hint. |
| 81 |
// $html = apply_filters( 'wpbc_booking_form_content__after_load', $html, $engine->current_resource_id, $req['form_slug'] ); // FixIn: 2026-02-20 18:38 runed twice |
| 82 |
|
| 83 |
/** |
| 84 |
* Replace these shortcodes: |
| 85 |
* 0 = "/\[bookingresource\s*show='id'\s*]/" |
| 86 |
* 1 = "/\[bookingresource\s*show='title'\s*]/" |
| 87 |
* 2 = "/\[bookingresource\s*show='cost'\s*]/" |
| 88 |
* 3 = "/\[bookingresource\s*show='capacity'\s*]/" |
| 89 |
* 4 = "/\[bookingresource\s*show='maxvisitors'\s*]/" |
| 90 |
*/ |
| 91 |
$html = wpbc_replace_bookingresource_info_in_form( $html, $engine->current_resource_id ); |
| 92 |
|
| 93 |
// Is this parameter used anywhere ? |
| 94 |
if ( false !== $req['current_edit_booking_id'] ) { |
| 95 |
$html .= '<input name="edit_booking_id" id="edit_booking_id" type="hidden" value="' . esc_attr( $req['current_edit_booking_id'] ) . '">'; |
| 96 |
} |
| 97 |
|
| 98 |
// This parameter used for update AJX cost hints and during creation of booking. |
| 99 |
if ( 'standard' !== $req['form_slug'] ) { |
| 100 |
$html .= '<input name="booking_form_type' . intval( $req['resource_id'] ) . '" id="booking_form_type' . intval( $req['resource_id'] ) . '" type="hidden" value="' . esc_attr( $req['form_slug'] ) . '">'; |
| 101 |
} |
| 102 |
|
| 103 |
// -- Selecting Dates in Calendar ------------------------------------------------------------------ |
| 104 |
if ( false !== $req['current_edit_booking_id'] ) { |
| 105 |
$html .= wpbc_get_dates_selection_js_code( $engine->current_edit_booking['dates'], $req['resource_id'] ); // FixIn: 9.2.3.4. |
| 106 |
} |
| 107 |
|
| 108 |
// ----------------------------------------------------------------------------------------------------------------- |
| 109 |
// Prevent editing, if booked dates already in the past. (Front-end only). |
| 110 |
// ----------------------------------------------------------------------------------------------------------------- |
| 111 |
$admin_uri = ltrim( str_replace( get_site_url( null, '', 'admin' ), '', admin_url( 'admin.php?' ) ), '/' ); // FixIn: 8.8.1.2. |
| 112 |
|
| 113 |
$server_request_uri = ( ( isset( $_SERVER['REQUEST_URI'] ) ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '' ); |
| 114 |
$is_add_booking_admin_context = ( function_exists( 'wpbc_is_new_booking_page_url' ) && wpbc_is_new_booking_page_url( $server_request_uri ) ); |
| 115 |
|
| 116 |
if ( ( strpos( $server_request_uri, $admin_uri ) === false ) && ! $is_add_booking_admin_context ) { // Only in front-end side. |
| 117 |
if ( false !== $req['current_edit_booking_id'] ) { |
| 118 |
foreach ( $engine->current_edit_booking['dates'] as $b_date ) { |
| 119 |
if ( wpbc_is_date_in_past( $b_date ) ) { |
| 120 |
$html = '<div class="wpdevelop"><div class="alert alert-warning alert-danger">' . |
| 121 |
__( 'The booked dates already in the past', 'booking' ) . |
| 122 |
'</div></div>' . |
| 123 |
'<script type="text/javascript">setTimeout( function(){ jQuery( ".hasDatepick" ).hide(); }, 500 );</script>'; |
| 124 |
} |
| 125 |
} |
| 126 |
} |
| 127 |
} |
| 128 |
|
| 129 |
$html = apply_filters( 'wpbc_replace_shortcodes_in_booking_form', $html, $engine->current_resource_id, $req['form_slug'] ); // FixIn: 9.4.3.6. |
| 130 |
|
| 131 |
// Info: Hook for addons. Filter parsed HTML right after shortcode parsing, but before legacy filters like wpbc_update_bookingform_content__after_load. |
| 132 |
$html = apply_filters( 'wpbc_booking_form_content__after_shortcodes', $html, $args ); |
| 133 |
|
| 134 |
return $html; |
| 135 |
} |
| 136 |
|