PluginProbe
Booking Calendar / 11.6.1
Booking Calendar v11.6.1
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 / save-load / bfb-form-loader.php

bfb-form-loader.php in Booking Calendar 11.6.1, at includes/page-form-builder/save-load/bfb-form-loader.php

407 lines 12.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Booking Form Loader (Builder storage only).
4 *
5 * This helper:
6 * - Accepts a logical form identifier (form_slug) + status (and optional form_id).
7 * - Asks the Booking Form Builder (BFB) for exported form/content.
8 *
9 * It only returns the **source strings** (shortcodes):
10 * - "booking form" (form) – the main form shortcodes.
11 * - "Content of booking fields data" (content) – email/content template.
12 *
13 * Rendering/parsing of shortcodes stays in WPBC_BFB_FormShortcodeEngine.
14 *
15 * @package Booking Calendar
16 * @subpackage Form Builder
17 * @file includes/page-form-builder/save-load/bfb-form-loader.php
18 *
19 * @since 11.0.0
20 */
21
22 if ( ! defined( 'ABSPATH' ) ) {
23 exit;
24 }
25
26 /**
27 * Basically it is wrapper to call this function: wpbc_bfb__load_from_bfb_table() for loading data from DB
28 */
29
30 /**
31 * Central helper for resolving which booking form configuration
32 * should be used on the front-end.
33 */
34 class WPBC_BFB_Form_Loader {
35
36 /**
37 * Singleton instance.
38 *
39 * @var WPBC_BFB_Form_Loader|null
40 */
41 protected static $instance = null;
42
43 /**
44 * Protect direct construction – use get_instance().
45 */
46 protected function __construct() {}
47
48 /**
49 * Prevent cloning.
50 */
51 protected function __clone() {}
52
53 /**
54 * Prevent unserializing.
55 */
56 public function __wakeup() { // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
57 _doing_it_wrong( __METHOD__, 'Unserializing WPBC_BFB_Form_Loader is not allowed.', '11.0.0' );
58 }
59
60 /**
61 * Get singleton instance.
62 *
63 * @return WPBC_BFB_Form_Loader
64 */
65 public static function get_instance() {
66
67 if ( null === self::$instance ) {
68 self::$instance = new self();
69 }
70
71 return self::$instance;
72 }
73
74 /**
75 * Get booking form (shortcodes string) by form slug / ID.
76 *
77 * This returns the main "Booking form" configuration in shortcodes format.
78 * It does NOT parse shortcodes, only returns the source string.
79 *
80 * @param array $args {
81 * Optional. Arguments for resolving the form.
82 *
83 * @type string $form_slug Logical form identifier. Examples:
84 * 'standard', 'appointments-services-1'.
85 * Empty string or 'auto' means: resolve using
86 * legacy default custom form for $resource_id.
87 * @type int $form_id Optional. Numeric ID of the Builder form
88 * (booking_form_id in booking_form_structures).
89 * If provided, Builder may prefer it over form_slug.
90 * @type string $status Desired Builder status. Examples:
91 * 'published', 'preview', 'draft', 'archived'.
92 * Legacy fallback ignores it.
93 * @type string $bfb_form_status Optional alias for $status used in shortcodes,
94 * e.g. bfb_form_status="preview".
95 * @type int $resource_id Booking resource ID. Used when resolving the
96 * default custom form in legacy code.
97 * @type int $user_id Optional user ID. Mostly for MultiUser; legacy
98 * get_bk_option() already respects the current user.
99 * }
100 *
101 * @return string Booking form in shortcodes format.
102 */
103 public static function get_form( $args = array() ) {
104
105 return self::get_instance()->get_value_internal( 'form', $args );
106 }
107
108 /**
109 * Get "Content of booking fields data" template (shortcodes string)
110 * by form slug / ID.
111 *
112 * @param array $args See WPBC_BFB_Form_Loader::get_form().
113 *
114 * @return string Content template in shortcodes format.
115 */
116 public static function get_content( $args = array() ) {
117
118 return self::get_instance()->get_value_internal( 'content', $args );
119 }
120
121 /**
122 * Get both booking form and content template at once.
123 *
124 * @param array $args See WPBC_BFB_Form_Loader::get_form().
125 *
126 * @return array {
127 * @type string $form Booking form in shortcodes format.
128 * @type string $content "Content of booking fields data" in shortcodes format.
129 * @type string $source 'builder' or 'legacy'.
130 * @type string $form_slug Resolved form slug that was actually used.
131 * }
132 */
133 public static function get_pair( $args = array() ) {
134
135 return self::get_instance()->get_pair_internal( $args );
136 }
137
138 /**
139 * Internal router for single value.
140 *
141 * @param string $what 'form' or 'content'.
142 * @param array $args Arguments.
143 *
144 * @return string
145 */
146 protected function get_value_internal( $what, $args ) {
147
148 $pair = $this->get_pair_internal( $args );
149
150 if ( 'content' === $what ) {
151 return isset( $pair['content'] ) ? $pair['content'] : '';
152 }
153
154 return isset( $pair['form'] ) ? $pair['form'] : '';
155 }
156
157 /**
158 * Internal logic for resolving Builder form.
159 *
160 * @param array $args Arguments.
161 *
162 * @return array See self::get_pair().
163 */
164 protected function get_pair_internal( $args ) {
165
166 $defaults = array(
167 'form_slug' => '',
168 'form_id' => 0,
169 'status' => 'published',
170 'bfb_form_status' => '',
171 'resource_id' => 0,
172 'user_id' => 0,
173 );
174
175 $args = wp_parse_args( $args, $defaults );
176
177 // Normalize types.
178 $args['form_id'] = isset( $args['form_id'] ) ? intval( $args['form_id'] ) : 0;
179 $args['resource_id'] = isset( $args['resource_id'] ) ? intval( $args['resource_id'] ) : 0;
180 $args['user_id'] = isset( $args['user_id'] ) ? intval( $args['user_id'] ) : 0;
181
182 // Map BFB alias into status if provided (e.g. bfb_form_status="preview").
183 if ( ! empty( $args['bfb_form_status'] ) ) {
184 $args['status'] = $args['bfb_form_status'];
185 }
186 unset( $args['bfb_form_status'] );
187
188 // Normalize status to a known set where possible (DB uses e.g. active/preview).
189 $args['status'] = $this->normalize_status( $args['status'] );
190
191 /**
192 * Filter the raw arguments before any resolution.
193 *
194 * Can be used to:
195 * - Map resource_id -> default form_slug.
196 * - Inject MultiUser scopes.
197 *
198 * @param array $args Arguments passed to the loader.
199 */
200 $args = apply_filters( 'wpbc_bfb_form_loader_args', $args );
201
202 // Resolve empty / "auto" slug into concrete value using existing legacy logic.
203 $resolved_slug = $this->resolve_form_slug( $args );
204 $args['form_slug'] = $resolved_slug;
205
206 // ---------------------------------------------------------------------
207 // 1. Try to load from Builder table via filter.
208 // ---------------------------------------------------------------------
209 $builder_pair = $this->maybe_load_from_builder( $args );
210
211 if ( is_array( $builder_pair ) ) {
212 $builder_form = isset( $builder_pair['form'] ) ? $builder_pair['form'] : '';
213 $builder_content = isset( $builder_pair['content'] ) ? $builder_pair['content'] : '';
214 $builder_settings_json = isset( $builder_pair['settings_json'] ) ? (string) $builder_pair['settings_json'] : '';
215
216 if ( ( '' !== trim( $builder_form ) ) || ( '' !== trim( $builder_content ) ) ) {
217 return array(
218 'form' => $builder_form,
219 'content' => $builder_content,
220 'settings_json' => $builder_settings_json,
221 'source' => 'builder',
222 'form_slug' => $resolved_slug,
223 );
224 }
225 }
226
227 return array(
228 'form' => '',
229 'content' => '',
230 'settings_json' => '',
231 'source' => 'builder',
232 'form_slug' => $resolved_slug,
233 );
234 }
235
236 /**
237 * Normalize loader status to match DB semantics.
238 *
239 * Maps generic or legacy-like values (e.g. 'publish') to actual statuses
240 * used in booking_form_structures ('published', 'preview', 'draft', 'archived').
241 *
242 * @param string $status Raw status.
243 *
244 * @return string Normalized status.
245 */
246 protected function normalize_status( $status ) {
247
248 $status = strtolower( trim( (string) $status ) );
249
250 if ( '' === $status ) {
251 $status = 'published';
252 }
253
254 // Map some common aliases.
255 if ( in_array( $status, array( 'publish', 'published' ), true ) ) {
256 $status = 'published';
257 }
258
259 return $status;
260 }
261
262 /**
263 * Resolve empty or special slugs into real form names.
264 *
265 * Examples:
266 * - '' or 'auto' => current default custom form for $resource_id (or 'standard').
267 * - 'standard' => keep as is.
268 *
269 * @param array $args Loader arguments.
270 *
271 * @return string Resolved form slug.
272 */
273 protected function resolve_form_slug( $args ) {
274
275 $slug = isset( $args['form_slug'] ) ? trim( (string) $args['form_slug'] ) : '';
276
277 if ( '' !== $slug && 'auto' !== $slug ) {
278 return $slug;
279 }
280
281 $resource_id = isset( $args['resource_id'] ) ? intval( $args['resource_id'] ) : 0;
282
283 // Existing logic for resolving default custom form for specific resource.
284 if ( $resource_id > 0 ) {
285 $default_slug = apply_bk_filter( 'wpbc_get_default_custom_form', 'standard', $resource_id );
286 } else {
287 $default_slug = 'standard';
288 }
289
290 if ( empty( $default_slug ) ) {
291 $default_slug = 'standard';
292 }
293
294 return $default_slug;
295 }
296
297 /**
298 * Try to get form + content from the new Builder storage.
299 *
300 * The actual lookup is delegated to a filter so that this class
301 * does not depend on any concrete BFB DB schema.
302 *
303 * If the table is missing or the requested slug/ID does not exist, the
304 * filter should return the $empty value.
305 *
306 * @param array $args Loader arguments.
307 *
308 * @return array {
309 * @type string $form Optional. Booking form in shortcodes format.
310 * @type string $content Optional. Content of booking fields data in shortcodes format.
311 * }
312 */
313 protected function maybe_load_from_builder( $args ) {
314
315 $empty = array(
316 'form' => '',
317 'content' => '',
318 'settings_json' => '',
319 );
320
321 /**
322 * Allows the Booking Form Builder module to provide form/content strings.
323 *
324 * Typical implementation in BFB (pseudo-code):
325 *
326 * function my_bfb_loader( $empty, $args ) {
327 * // 1) Verify Builder is active and table exists.
328 * // 2) If $args['form_id'] > 0:
329 * // SELECT row FROM {$wpdb->prefix}booking_form_structures
330 * // WHERE booking_form_id = $args['form_id']
331 * // AND status = $args['status'];
332 * // else:
333 * // SELECT row FROM {$wpdb->prefix}booking_form_structures
334 * // WHERE form_slug = $args['form_slug']
335 * // AND status = $args['status'];
336 * // 3) If found, return array(
337 * // 'form' => $row->advanced_form,
338 * // 'content' => $row->content_form,
339 * // );
340 * // 4) On any error or no row found, return $empty.
341 * }
342 *
343 * @param array $empty Default empty value.
344 * @param array $args Loader arguments (form_slug, form_id, status, resource_id, user_id).
345 */
346 $pair = apply_filters( 'wpbc_bfb_form_loader_from_builder', $empty, $args );
347
348 if ( ! is_array( $pair ) ) {
349 return $empty;
350 }
351
352 // Normalize to have both keys.
353 $pair = wp_parse_args(
354 $pair,
355 array(
356 'form' => '',
357 'content' => '',
358 'settings_json' => '',
359 )
360 );
361
362 return $pair;
363 }
364
365 }
366
367
368
369
370 /**
371 * Wrapper: get booking form (shortcodes) by slug/status.
372 *
373 * This is a convenience function for use in templates or older code.
374 *
375 * @param array $args See WPBC_BFB_Form_Loader::get_form().
376 *
377 * @return string
378 */
379 function wpbc_bfb_get_booking_form_source( $args = array() ) {
380
381 return WPBC_BFB_Form_Loader::get_form( $args );
382 }
383
384 /**
385 * Wrapper: get "Content of booking fields data" (shortcodes) by slug/status.
386 *
387 * @param array $args See WPBC_BFB_Form_Loader::get_form().
388 *
389 * @return string
390 */
391 function wpbc_bfb_get_booking_content_source( $args = array() ) {
392
393 return WPBC_BFB_Form_Loader::get_content( $args );
394 }
395
396 /**
397 * Wrapper: get both booking form and content template at once.
398 *
399 * @param array $args See WPBC_BFB_Form_Loader::get_form().
400 *
401 * @return array See WPBC_BFB_Form_Loader::get_pair().
402 */
403 function wpbc_bfb_get_booking_form_pair( $args = array() ) {
404
405 return WPBC_BFB_Form_Loader::get_pair( $args );
406 }
407