PluginProbe
Booking Calendar / 11.4
Booking Calendar v11.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 10.10.2 10.11 10.11.2 All 203 releases
booking / includes / page-form-builder / bfb-bootstrap.php

bfb-bootstrap.php in Booking Calendar 11.4, at includes/page-form-builder/bfb-bootstrap.php

351 lines 17.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Hybrid++ Bootstrap: collect packs, localize schemas, print pack templates.
4 *
5 * @package Booking Calendar.
6 * @author wpdevelop, oplugins
7 * @web-site https://wpbookingcalendar.com/
8 * @email info@wpbookingcalendar.com
9 *
10 * @since 11.0.0
11 * @modified 2025-08-29
12 * @version 1.0
13 */
14
15 // ---------------------------------------------------------------------------------------------------------------------
16 // == File bfb-bootstrap.php == Time point: 2025-08-29 12:25
17 // ---------------------------------------------------------------------------------------------------------------------
18 if ( ! defined( 'ABSPATH' ) ) {
19 exit;
20 }
21
22
23 class WPBC_BFB_Bootstrap {
24
25 /**
26 * Guard flag.
27 *
28 * @var bool
29 */
30 protected static $packs_collected = false;
31
32 /**
33 * Guard flag.
34 *
35 * @var bool
36 */
37 protected static $templates_printed = false;
38
39 /**
40 * Packs keyed by type.
41 *
42 * @var array
43 */
44 protected static $packs_by_type = array();
45
46
47 /**
48 * Init all hooks for the current request.
49 *
50 * @return void
51 */
52 public static function init() {
53
54 // 1) Enqueue BFB scripts, after enqueued basic WPBC scripts (EXTERNAL HOOK). Localize schemas, etc...
55 add_action( 'wpbc_enqueue_js_files', array( __CLASS__, 'on_admin_enqueue__js_files' ), 50 );
56
57 // 2) Enqueue BFB CSS, after basic WPBC scripts are enqueued (EXTERNAL HOOK).
58 add_action( 'wpbc_enqueue_css_files', array( __CLASS__, 'on_admin_enqueue__css_files' ), 50 );
59
60 // 3) Primary: print templates at the end of the page using custom footer hook. The hook passes the slug; we only print when it equals our builder slug.
61 add_action( 'wpbc_hook_settings_page_footer', array( __CLASS__, 'on_settings_page_footer' ), 10, 1 );
62
63 // 4) Fallback printer (for the URL path) so templates still print if the custom footer hook isn’t fired.
64 add_action( 'admin_print_footer_scripts', array( __CLASS__, 'fallback_print_on_admin_footer' ), 20 );
65 }
66
67
68 /**
69 * Enqueue JS files and Localize them.
70 *
71 * @param sring $where_to_load - parameter from root JS loader script. Value can be: 'both', 'client', 'admin'. In this method can be ignore, because we check via self::is_builder_by_request().
72 *
73 * @return void
74 */
75 public static function on_admin_enqueue__js_files( $where_to_load ) {
76
77 if ( ! self::is_builder_by_request() ) {
78 // Might still reach the page via the custom footer hook path; in that case we'll only print templates there.
79 return;
80 }
81 $in_footer = true;
82 $core_handle = apply_filters( 'wpbc_bfb_inspector_script_handle', 'wpbc-bfb' );
83
84 // --- Vendor ---
85 wp_enqueue_script( 'wpbc-sortable', wpbc_plugin_url( '/vendors/sortablejs/Sortable.min.js' ), array( 'wpbc_all' ), WP_BK_VERSION_NUM, $in_footer );
86
87 // --- Color picker (Coloris) --- Load BEFORE core BFB scripts so the Inspector can detect window.Coloris during first render.
88 wp_enqueue_style( 'coloris', wpbc_plugin_url( '/vendors/coloris/dist/coloris.min.css' ), array(), WP_BK_VERSION_NUM );
89 wp_enqueue_script( 'coloris', wpbc_plugin_url( '/vendors/coloris/dist/coloris.min.js' ), array(), WP_BK_VERSION_NUM, $in_footer );
90
91
92 // -- Admin WP Templates Helper (for modals etc..).
93 wp_enqueue_script( 'wpbc-bfb-templates', wpbc_plugin_url( '/includes/page-form-builder/admin-page-tpl/_out/bfb-templates.js' ), array( 'wp-util' ), WP_BK_VERSION_NUM, $in_footer );
94
95 // --- Support Functions ---
96 wp_enqueue_script( 'wpbc-bfb_support_functions', wpbc_plugin_url( '/includes/page-form-builder/_src/support_functions.js' ), array(), WP_BK_VERSION_NUM, $in_footer );
97
98 // --- All Core BFB Scripts ---
99 wp_enqueue_script( $core_handle, wpbc_plugin_url( '/_dist/bfb/_out/wpbc_bfb.js' ), array( 'wpbc-bfb_support_functions', 'wpbc-sortable', 'wp-util', 'wpbc-bfb-templates', 'coloris' ), WP_BK_VERSION_NUM, $in_footer );
100
101 // 2) --- Time Utils ---
102 wp_enqueue_script( 'wpbc-bfb-time-utils', wpbc_plugin_url( '/includes/page-form-builder/_out/bfb-time-utils.js' ), array( $core_handle ), WP_BK_VERSION_NUM, $in_footer );
103
104 // 3) --- Field packs (they can now safely reference wpbc_bfb_inspector_factory_slots/value_from)
105 do_action( 'wpbc_enqueue_js_field_pack', WPBC_BFB_BUILDER_PAGE_SLUG );
106
107 // 5) --- Builder ---
108 wp_enqueue_script( 'wpbc-bfb_builder', wpbc_plugin_url( '/includes/page-form-builder/_out/bfb-builder.js' ), array( $core_handle ), WP_BK_VERSION_NUM, $in_footer );
109
110 // -------------------------------------------------------------------------------------------------------------
111 // == Self attached modules here == - (AFTER builder, because it auto-attaches via wpbc_bfb_api.ready) ---
112 // -------------------------------------------------------------------------------------------------------------
113 // --- Modals, such as page deleteing etc..
114 wp_enqueue_script( 'wpbc-bfb_modal__form_templates', wpbc_plugin_url( '/includes/page-form-builder/admin-page-tpl/_out/modal__form_templates.js' ), array( 'wpbc-bfb_builder' ), WP_BK_VERSION_NUM, $in_footer );
115 wp_enqueue_script( 'wpbc-bfb_modal_page_delete', wpbc_plugin_url( '/includes/page-form-builder/admin-page-tpl/_out/modal_page_delete.js' ), array( 'wpbc-bfb_builder' ), WP_BK_VERSION_NUM, $in_footer );
116 wp_enqueue_script( 'wpbc-bfb_modal_item_delete', wpbc_plugin_url( '/includes/page-form-builder/admin-page-tpl/_out/modal_item_delete.js' ), array( 'wpbc-bfb_builder' ), WP_BK_VERSION_NUM, $in_footer );
117 wp_enqueue_script( 'wpbc-bfb_modal__form_add_new', wpbc_plugin_url( '/includes/page-form-builder/admin-page-tpl/_out/modal__form_add_new.js' ), array( 'wpbc-bfb_builder', 'wpbc-bfb_modal__form_templates' ), WP_BK_VERSION_NUM, $in_footer );
118 wp_enqueue_script( 'wpbc-bfb_modal__form_save_as', wpbc_plugin_url( '/includes/page-form-builder/admin-page-tpl/_out/modal__form_save_as.js' ), array( 'wpbc-bfb_builder' ), WP_BK_VERSION_NUM, $in_footer );
119 wp_enqueue_script( 'wpbc-bfb_modal__form_open', wpbc_plugin_url( '/includes/page-form-builder/admin-page-tpl/_out/modal__form_open.js' ), array( 'wpbc-bfb_builder' ), WP_BK_VERSION_NUM, $in_footer );
120 wp_enqueue_script( 'wpbc-bfb_modal__apply_template', wpbc_plugin_url( '/includes/page-form-builder/admin-page-tpl/_out/modal__form_apply_template.js' ), array( 'wpbc-bfb_builder', 'wpbc-bfb_modal__form_templates' ), WP_BK_VERSION_NUM, $in_footer );
121
122 // Form Settings.
123 // // FixIn: 2026-01-24 wp_enqueue_script( 'wpbc-bfb-so', wpbc_plugin_url( '/includes/page-form-builder/settings-options/_out/bfb-so.js' ), array( 'jquery', 'wp-util', 'wpbc-save-load-option' ), WP_BK_VERSION_NUM, $in_footer );
124 wp_enqueue_script( 'wpbc-bfb-form_settings', wpbc_plugin_url( '/includes/page-form-builder/form-settings/_out/settings.js' ), array( 'jquery', 'wp-util', 'wpbc-save-load-option', 'coloris' ), WP_BK_VERSION_NUM, $in_footer );
125 wp_enqueue_script( 'wpbc-bfb-global_save_behavior', wpbc_plugin_url( '/includes/page-form-builder/form-settings/_out/global_save_behavior.js' ), array( 'wpbc-bfb-form_settings' ), WP_BK_VERSION_NUM, $in_footer );
126 wp_enqueue_script( 'wpbc-bfb-form_settings_effects', wpbc_plugin_url( '/includes/page-form-builder/form-settings/_out/settings_effects.js' ), array( 'wpbc-bfb-form_settings' ), WP_BK_VERSION_NUM, $in_footer );
127 $wpbc_bfb_form_style = wpbc_bfb_settings__get_current_form_style();
128 $wpbc_bfb_form_style_preset = wpbc_bfb_settings__get_form_style_preset( $wpbc_bfb_form_style );
129 $wpbc_bfb_custom_form_style = wpbc_bfb_settings__get_custom_form_style_options();
130 $wpbc_bfb_form_style_vars = wpbc_bfb_settings__get_form_style_css_vars( $wpbc_bfb_form_style, $wpbc_bfb_custom_form_style );
131 $wpbc_bfb_container_style = isset( $wpbc_bfb_form_style_preset['container_style'] ) ? (string) $wpbc_bfb_form_style_preset['container_style'] : 'bordered';
132 $wpbc_bfb_theme_class = isset( $wpbc_bfb_form_style_preset['theme_class'] ) ? (string) $wpbc_bfb_form_style_preset['theme_class'] : '';
133 $wpbc_bfb_legacy_appearance = array(
134 'booking_form_theme' => $wpbc_bfb_theme_class,
135 'booking_form_container_style' => $wpbc_bfb_container_style,
136 'booking_form_background_color' => isset( $wpbc_bfb_form_style_vars['--wpbc-bfb-form-background'] ) ? $wpbc_bfb_form_style_vars['--wpbc-bfb-form-background'] : '#ffffff',
137 'booking_form_border_color' => isset( $wpbc_bfb_form_style_vars['--wpbc-bfb-form-border-color'] ) ? $wpbc_bfb_form_style_vars['--wpbc-bfb-form-border-color'] : '#cccccc',
138 'booking_form_border_width' => isset( $wpbc_bfb_form_style_vars['--wpbc-bfb-form-border-width'] ) ? $wpbc_bfb_form_style_vars['--wpbc-bfb-form-border-width'] : '1px',
139 'booking_form_border_radius' => isset( $wpbc_bfb_form_style_vars['--wpbc-bfb-form-border-radius'] ) ? $wpbc_bfb_form_style_vars['--wpbc-bfb-form-border-radius'] : '2px',
140 'booking_form_padding' => isset( $wpbc_bfb_form_style_vars['--wpbc-bfb-form-padding'] ) ? $wpbc_bfb_form_style_vars['--wpbc-bfb-form-padding'] : '10px 30px',
141 'booking_form_text_color' => isset( $wpbc_bfb_form_style_vars['--wpbc_form-label-color'] ) ? $wpbc_bfb_form_style_vars['--wpbc_form-label-color'] : '',
142 'booking_form_field_background_color' => isset( $wpbc_bfb_form_style_vars['--wpbc_form-field-background-color'] ) ? $wpbc_bfb_form_style_vars['--wpbc_form-field-background-color'] : '',
143 'booking_form_field_text_color' => isset( $wpbc_bfb_form_style_vars['--wpbc_form-field-text-color'] ) ? $wpbc_bfb_form_style_vars['--wpbc_form-field-text-color'] : '',
144 'booking_form_field_border_color' => isset( $wpbc_bfb_form_style_vars['--wpbc_form-field-border-color'] ) ? $wpbc_bfb_form_style_vars['--wpbc_form-field-border-color'] : '',
145 );
146 wp_localize_script(
147 'wpbc-bfb-form_settings',
148 'wpbc_bfb_settings_vars',
149 array(
150 'global_form_style' => array_merge(
151 array(
152 'booking_form_style' => $wpbc_bfb_form_style,
153 'theme_class' => $wpbc_bfb_theme_class,
154 'container_style' => $wpbc_bfb_container_style,
155 'css_vars' => $wpbc_bfb_form_style_vars,
156 ),
157 $wpbc_bfb_custom_form_style
158 ),
159 'form_style_options' => wpbc_bfb_settings__get_form_style_options(),
160 'form_style_presets' => wpbc_bfb_settings__get_form_style_presets(),
161 'form_style_css_var_names' => wpbc_bfb_settings__get_form_style_css_var_names(),
162 'form_style_option_keys' => wpbc_bfb_settings__get_form_json_style_option_keys(),
163 'custom_form_style_defaults' => wpbc_bfb_settings__get_default_custom_form_style_options(),
164 'global_appearance' => $wpbc_bfb_legacy_appearance,
165 )
166 );
167
168 // Form Details.
169 wp_enqueue_script( 'wpbc-bfb-form_details_ui', wpbc_plugin_url( '/includes/page-form-builder/form-details/_out/current-form-details-ui.js' ), array( 'wpbc-bfb-form_settings' ), WP_BK_VERSION_NUM, $in_footer );
170 wp_enqueue_script( 'wpbc-bfb-form_details_save_delete', wpbc_plugin_url( '/includes/page-form-builder/form-details/_out/current-form-details-save_delete.js' ), array( 'wpbc-bfb-form_settings' ), WP_BK_VERSION_NUM, $in_footer );
171
172
173
174 wp_enqueue_script( 'wpbc-bfb-top-tabs', wpbc_plugin_url( '/includes/page-form-builder/ui-parts/_out/bfb-top-tabs.js' ), array(), WP_BK_VERSION_NUM, true );
175
176 // --- Ajax for Save / Load ---
177 wp_enqueue_script( 'wpbc-bfb_save_load_ajax', wpbc_plugin_url( '/includes/page-form-builder/ajax/_out/bfb-ajax.js' ), array( 'wpbc-bfb_builder' ), WP_BK_VERSION_NUM, $in_footer );
178
179 // --- Exporter ---
180 wp_enqueue_script( 'wpbc-bfb_exporter', wpbc_plugin_url( '/includes/page-form-builder/_out/export/builder-exporter.js' ), array( 'wpbc-bfb_builder' ), WP_BK_VERSION_NUM, $in_footer );
181 wp_enqueue_script( 'wpbc-bfb_debug_ui', wpbc_plugin_url( '/includes/page-form-builder/_out/export/debug-ui.js' ), array( 'wpbc-bfb_exporter' ), WP_BK_VERSION_NUM, $in_footer );
182
183
184
185 // -- Templates (optional tools) --
186 wp_enqueue_script( 'wpbc-bfb_form_templates', wpbc_plugin_url( '/includes/page-form-builder/_out/form_templates.js' ), array( 'wpbc-bfb_builder' ), WP_BK_VERSION_NUM, $in_footer );
187
188 // --- Right Tabs ---
189 wp_enqueue_script( 'wpbc-bfb_rightbar_tabs', wpbc_plugin_url( '/includes/page-form-builder/_out/bfb-rightbar-tabs.js' ), array( $core_handle ), WP_BK_VERSION_NUM, $in_footer );
190
191 // Enqueue phase: collect & localize schemas if we're on the Builder screen (by URL fallback).
192 self::collect_packs_once();
193 self::localize_schemas_to_inspector();
194
195 //wpbc_load_js__required_for_modals();
196 wpbc_load_js__required_for_media_upload();
197
198
199 // Loaded JavaScript files for this settings page.
200 do_action( 'wpbc_enqueue_js_files_on_page_done', WPBC_BFB_BUILDER_PAGE_SLUG );
201 }
202
203
204 /**
205 * Enqueue CSS files.
206 *
207 * @param sring $where_to_load - parameter from root JS loader script. Value can be: 'both', 'client', 'admin'. In this method can be ignore, because we check via self::is_builder_by_request().
208 *
209 * @return void
210 */
211 public static function on_admin_enqueue__css_files() {
212
213 if ( ! self::is_builder_by_request() ) {
214 // Might still reach the page via the custom footer hook path; in that case we'll only print templates there.
215 return;
216 }
217
218 wp_enqueue_style( 'wpbc-ajx__builder_booking_form_page', wpbc_plugin_url( '/includes/page-form-builder/_out/builder-form-page.css' ), array(), WP_BK_VERSION_NUM );
219
220 // CSS.
221 wpbc_enqueue_styles__front_end();
222 wpbc_enqueue_styles__calendar();
223 }
224
225
226 /**
227 * Custom footer hook — primary place to print pack templates.
228 *
229 * @param string $page Page slug passed by the hook (expected: 'wpbc-ajx_booking_builder_booking_form', e.g. - WPBC_BFB_BUILDER_PAGE_SLUG ).
230 * @return void
231 */
232 public static function on_settings_page_footer( $page ) {
233
234 if ( WPBC_BFB_BUILDER_PAGE_SLUG !== $page ) {
235 return;
236 }
237
238 // Optional. Doucle ensure packs & schemas ready even if enqueue path didn’t run.
239 self::collect_packs_once();
240 self::localize_schemas_to_inspector();
241
242 self::print_pack_templates_once( $page );
243 }
244
245
246 /**
247 * Fallback printer (for the URL path) so templates still print if the custom footer hook isn’t fired.
248 *
249 * @return void
250 */
251 public static function fallback_print_on_admin_footer() {
252
253 if ( self::$templates_printed ) {
254 return;
255 }
256 if ( ! self::is_builder_by_request() ) {
257 return;
258 }
259 // Ensure packs & localization are ready.
260 self::collect_packs_once();
261 self::localize_schemas_to_inspector();
262
263 // Print pack templates once.
264 self::print_pack_templates_once( WPBC_BFB_BUILDER_PAGE_SLUG );
265 }
266
267
268 // -- PROTECTED --
269
270 /**
271 * Collect packs via filter (only once).
272 *
273 * @return void
274 */
275 protected static function collect_packs_once() {
276 if ( self::$packs_collected ) {
277 return;
278 }
279 $packs_raw = apply_filters( 'wpbc_bfb_register_field_packs', array() );
280 $packs_raw = is_array( $packs_raw ) ? $packs_raw : array();
281 self::$packs_by_type = WPBC_BFB_Schemas_Util::merge_packs( $packs_raw );
282 self::$packs_collected = true;
283 }
284
285 /**
286 * Localize schemas to the inspector script handle.
287 *
288 * @return void
289 */
290 protected static function localize_schemas_to_inspector() {
291
292 $handle = apply_filters( 'wpbc_bfb_inspector_script_handle', 'wpbc-bfb' );
293
294 // If the handle isn't registered yet, try again later in the same request (once).
295 if ( ! wp_script_is( $handle, 'registered' ) && ! wp_script_is( $handle, 'enqueued' ) ) {
296 // As a last resort, hook wp_print_scripts for this page load so we don't miss it.
297 add_action( 'admin_print_scripts', function () use ( $handle ) {
298 if ( wp_script_is( $handle, 'registered' ) || wp_script_is( $handle, 'enqueued' ) ) {
299 WPBC_BFB_Bootstrap::do_localize( $handle );
300 }
301 }, 100 );
302 return;
303 }
304
305 self::do_localize( $handle );
306 }
307
308 /**
309 * Perform the actual localization.
310 *
311 * @param string $handle
312 * @return void
313 */
314 protected static function do_localize( $handle ) {
315 $js_payload = WPBC_BFB_Schemas_Util::extract_schemas_for_js( self::$packs_by_type );
316 wp_localize_script( $handle, 'WPBC_BFB_Schemas', $js_payload );
317 }
318
319 /**
320 * Print templates for all collected packs (only once).
321 *
322 * @param string $page
323 * @return void
324 */
325 protected static function print_pack_templates_once( $page ) {
326
327 if ( self::$templates_printed ) {
328 return;
329 }
330 foreach ( self::$packs_by_type as $pack ) {
331 if ( isset( $pack['templates_printer'] ) && is_callable( $pack['templates_printer'] ) ) {
332 call_user_func( $pack['templates_printer'], $page );
333 }
334 }
335 self::$templates_printed = true;
336 }
337
338 /**
339 * Request-based detection of the Builder settings tab: page=wpbc-settings&tab=builder_booking_form
340 *
341 * @return bool
342 */
343 protected static function is_builder_by_request() {
344
345 $page = isset( $_GET['page'] ) ? sanitize_key( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
346 $tab = isset( $_GET['tab'] ) ? sanitize_key( wp_unslash( $_GET['tab'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
347
348 return ( 'wpbc-settings' === $page && 'builder_booking_form' === $tab );
349 }
350 }
351