PluginProbe
Booking Calendar / 11.2
Booking Calendar v11.2
11.9 11.8.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 All 205 releases
booking / includes / page-form-builder / field-packs / email / field-email-wptpl.php

field-email-wptpl.php in Booking Calendar 11.2, at includes/page-form-builder/field-packs/email/field-email-wptpl.php

392 lines 16.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * WPBC BFB Pack: Email Field (WP-template–driven with Inspector)
4 *
5 * Purpose:
6 * - Adds an "email" field pack whose Inspector UI and Preview are rendered via wp.template().
7 * - Exports to Booking Calendar shortcode format like:
8 * [email email]
9 * [email email 3/10 id:someID class:someCSSclass "[email protected]"]
10 *
11 * Loading:
12 * - This pack assumes you do NOT load another "email" pack simultaneously.
13 *
14 * Contracts:
15 * - Filter: wpbc_bfb_register_field_packs
16 * - Action: wpbc_enqueue_js_field_pack
17 * - Action: wpbc_bfb_palette_register_items (optional palette registration)
18 * - Filter: wpbc_bfb_export_field_to_shortcode (optional — if present in core)
19 *
20 * Notes:
21 * - Keep JS get_defaults() in sync with schema defaults below.
22 * - Palette item may set data-usagenumber="1" through UsageLimitService if you want to limit to a single email field.
23 *
24 * File: ../includes/page-form-builder/field-packs/email/field-email-wptpl.php
25 *
26 * @package Booking Calendar
27 * @author wpdevelop, oplugins
28 * @since 11.0.0
29 * @modified 2025-10-18
30 * @version 1.0.0
31 */
32
33 if ( ! defined( 'ABSPATH' ) ) {
34 exit;
35 }
36
37 /**
38 * Register the "email" field pack (WP-template–driven Inspector).
39 *
40 * @param array $packs Accumulated packs from other modules.
41 * @return array Modified packs with "email" field included.
42 */
43 function wpbc_bfb_register_field_packs__field_email_wptpl( $packs ) {
44
45 $packs['email'] = array(
46 'kind' => 'field',
47 'type' => 'email',
48 'label' => __( 'Email', 'booking' ),
49 'icon' => 'wpbc_icn_alternate_email',
50 'usage_key' => 'email', // Optional: limit via UsageLimitService.
51
52 // Schema drives coercion/defaults/serialization.
53 'schema' => array(
54 'props' => array(
55 'label' => array( 'type' => 'string', 'default' => __( 'Email', 'booking' ) ),
56 'name' => array( 'type' => 'string', 'default' => 'email' ),
57 'html_id' => array( 'type' => 'string', 'default' => '' ),
58 'placeholder' => array( 'type' => 'string', 'default' => '' ),
59 'required' => array( 'type' => 'boolean', 'default' => true ),
60 'help' => array( 'type' => 'string', 'default' => __( 'Enter your email address.', 'booking' ) ),
61 // 'minlength' => array( 'type' => 'number', 'default' => null, 'min' => 0 ),
62 // 'maxlength' => array( 'type' => 'number', 'default' => null, 'min' => 0 ),
63 'cssclass' => array( 'type' => 'string', 'default' => '' ),
64 'default_value' => array( 'type' => 'string', 'default' => '' ),
65 'readonly' => array( 'type' => 'boolean', 'default' => true ),
66 ),
67 ),
68
69 // Ask core to print the two wp.template() blocks for this pack.
70 'templates_printer' => 'wpbc_bfb_field_email_wptpl_print_templates'
71 );
72
73 return $packs;
74 }
75 add_filter( 'wpbc_bfb_register_field_packs', 'wpbc_bfb_register_field_packs__field_email_wptpl' );
76
77 /**
78 * Enqueue the Email (WP-template) pack JS for the Builder page.
79 *
80 * Hook runs on Builder; attaches the pack renderer file.
81 *
82 * @param string $page Current admin page slug (from core).
83 * @return void
84 */
85 function wpbc_bfb_enqueue__field_email_wptpl_js( $page ) {
86
87 wp_enqueue_script(
88 'wpbc-bfb_field_email_wptpl',
89 wpbc_plugin_url( '/includes/page-form-builder/field-packs/email/_out/field-email-wptpl.js' ),
90 array( 'wp-util', 'wpbc-bfb' ),
91 WP_BK_VERSION_NUM,
92 true
93 );
94 }
95 add_action( 'wpbc_enqueue_js_field_pack', 'wpbc_bfb_enqueue__field_email_wptpl_js', 10, 1 );
96
97 /**
98 * Print wp.template() blocks for the Email field:
99 * - Canvas Preview: tmpl-wpbc-bfb-field-email
100 * - Inspector: tmpl-wpbc-bfb-inspector-email
101 *
102 * Uses {{ ... }} (escaped).
103 *
104 * @param string $page The current page slug (core passes the Builder slug here).
105 * @return void
106 */
107 function wpbc_bfb_field_email_wptpl_print_templates( $page ) {
108
109 if ( WPBC_BFB_BUILDER_PAGE_SLUG !== $page ) {
110 return;
111 }
112
113 // ============ Canvas Preview Template ============
114 ?>
115 <script type="text/html" id="tmpl-wpbc-bfb-field-email">
116 <span class="wpbc_bfb__noaction wpbc_bfb__no-drag-zone" inert="">
117 <# var is_req = ( true === data.required || 'true' === data.required || 1 === data.required || '1' === data.required ); #>
118
119 <# if ( data.label && data.label !== '' ) { #>
120 <label class="wpbc_bfb__field-label" <# if ( data.html_id ) { #> for="{{ data.html_id }}" <# } #>>
121 {{ data.label }} <# if ( is_req ) { #>*<# } #>
122 </label>
123 <# } #>
124
125 <# var name_cls = ( data.name || 'email' ); #>
126 <span class="wpbc_wrap_text wpdev-form-control-wrap {{ name_cls }}">
127 <input type="email"
128 class="wpbc_bfb__preview-input {{ data.cssclass || '' }} wpdev-validates-as-email <# if ( is_req ) { #>wpdev-validates-as-required<# } #>"
129 placeholder="{{ data.placeholder || '' }}"
130 name="{{ name_cls }}"
131 autocomplete="email"
132 tabindex="-1"
133 readonly aria-readonly="true"
134 size="40"
135 <# if ( data.html_id ) { #> id="{{ data.html_id }}" <# } #>
136 <# if ( data.default_value != null && data.default_value !== '' ) { #> value="{{ data.default_value }}" <# } #>
137 <# if ( is_req ) { #> required aria-required="true" <# } #>
138 <?php /* ?>
139 <# if ( data.minlength != null && data.minlength !== '' && isFinite( Number( data.minlength ) ) ) { #> minlength="{{ Number( data.minlength ) }}" <# } #>
140 <# if ( data.maxlength != null && data.maxlength !== '' && isFinite( Number( data.maxlength ) ) ) { #> maxlength="{{ Number( data.maxlength ) }}" <# } #>
141 <?php */ ?>
142 />
143 </span>
144
145 <# if ( data.help ) { #>
146 <div class="wpbc_bfb__help">{{ data.help }}</div>
147 <# } #>
148 </span>
149 </script>
150 <?php
151
152 // ============ Inspector Template ============
153 ?>
154 <script type="text/html" id="tmpl-wpbc-bfb-inspector-email">
155 <div class="wpbc_bfb__inspector__head">
156 <div class="header_container">
157 <div class="header_title_content">
158 <h3 class="title"><?php echo esc_html__( 'Email', 'booking' ); ?></h3>
159 <div class="desc"><?php echo esc_html__( 'Configure an email input field.', 'booking' ); ?></div>
160 </div>
161 <div class="actions wpbc_ajx_toolbar wpbc_no_borders">
162 <div class="ui_container ui_container_small">
163 <div class="ui_group">
164 <div class="ui_element">
165 <button type="button" class="button button-secondary wpbc_ui_control wpbc_ui_button"
166 data-action="deselect" aria-label="<?php echo esc_attr__( 'Deselect', 'booking' ); ?>">
167 <i class="menu_icon icon-1x wpbc_icn_remove_done"></i>
168 </button>
169 <button type="button" class="button button-secondary wpbc_ui_control wpbc_ui_button"
170 data-action="scrollto" aria-label="<?php echo esc_attr__( 'Scroll to field', 'booking' ); ?>">
171 <i class="menu_icon icon-1x wpbc_icn_ads_click filter_center_focus"></i>
172 </button>
173 </div>
174 <div class="ui_element">
175 <button type="button" class="button button-secondary wpbc_ui_control wpbc_ui_button"
176 data-action="move-up" aria-label="<?php echo esc_attr__( 'Move up', 'booking' ); ?>">
177 <i class="menu_icon icon-1x wpbc_icn_arrow_upward"></i>
178 </button>
179 <button type="button" class="button button-secondary wpbc_ui_control wpbc_ui_button"
180 data-action="move-down" aria-label="<?php echo esc_attr__( 'Move down', 'booking' ); ?>">
181 <i class="menu_icon icon-1x wpbc_icn_arrow_downward"></i>
182 </button>
183 </div>
184 <div class="ui_element">
185 <?php /* ?>
186 <button data-action="duplicate" aria-label="<?php echo esc_attr__( 'Duplicate', 'booking' ); ?>"
187 type="button" class="button button-secondary wpbc_ui_control wpbc_ui_button">
188 <i class="menu_icon icon-1x wpbc_icn_content_copy"></i>
189 </button>
190 <?php */ ?>
191 <button data-action="delete" aria-label="<?php echo esc_attr__( 'Delete', 'booking' ); ?>"
192 type="button" class="button button-secondary wpbc_ui_control wpbc_ui_button wpbc_ui_button_danger button-link-delete" >
193 <span class="in-button-text"><?php echo esc_html__( 'Delete', 'booking' ); ?></span>&nbsp;&nbsp;
194 <i class="menu_icon icon-1x wpbc_icn_delete_outline"></i>
195 </button>
196 </div>
197 </div><!-- .ui_group -->
198 </div><!-- .ui_container -->
199 </div><!-- .actions -->
200 </div><!-- .header_container -->
201 </div><!-- .wpbc_bfb__inspector__head -->
202
203 <div class="wpbc_bfb__inspector__body">
204
205 <section class="wpbc_bfb__inspector__group wpbc_ui__collapsible_group is-open" data-group="basic">
206 <button type="button" class="group__header">
207 <h3><?php echo esc_html__( 'Basic', 'booking' ); ?></h3>
208 <i class="wpbc_ui_el__vert_menu_root_section_icon menu_icon icon-1x wpbc-bi-chevron-right"></i>
209 </button>
210 <div class="group__fields">
211 <div class="inspector__row">
212 <label class="inspector__label"><?php echo esc_html__( 'Label', 'booking' ); ?></label>
213 <div class="inspector__control">
214 <input type="text" class="inspector__input" data-inspector-key="label"
215 value="{{ data.label || '<?php echo esc_js( __( 'Email', 'booking' ) ); ?>' }}">
216 </div>
217 </div>
218
219 <div class="inspector__row">
220 <label class="inspector__label"><?php echo esc_html__( 'Name', 'booking' ); ?></label>
221 <div class="inspector__control">
222 <input type="text" class="inspector__input inspector__input--readonly"
223 data-inspector-key="name"
224 placeholder="<?php esc_attr_e( 'auto — from label', 'booking' ); ?>"
225 value="{{ data.name || '' }}"
226 readonly aria-readonly="true">
227 </div>
228 </div>
229
230 <div class="inspector__row">
231 <label class="inspector__label"><?php echo esc_html__( 'Placeholder', 'booking' ); ?></label>
232 <div class="inspector__control">
233 <input type="text" class="inspector__input" data-inspector-key="placeholder" value="{{ data.placeholder || '' }}">
234 </div>
235 </div>
236
237 <div class="inspector__row">
238 <label class="inspector__label"><?php echo esc_html__( 'Default value', 'booking' ); ?></label>
239 <div class="inspector__control">
240 <input type="email" class="inspector__input" data-inspector-key="default_value" value="{{ data.default_value || '' }}">
241 </div>
242 </div>
243 <?php /* ?>
244 <div class="inspector__row">
245 <label class="inspector__label"><?php echo esc_html__( 'Required', 'booking' ); ?></label>
246 <div class="inspector__control">
247 <input type="checkbox" class="inspector__checkbox" data-inspector-key="required"
248 <# if ( true === data.required || 'true' === data.required || 1 === data.required || '1' === data.required ) { #> checked="checked" <# } #> >
249 </div>
250 </div>
251 <?php */ ?>
252 <div class="inspector__row">
253 <label class="inspector__label"><?php echo esc_html__( 'Help text', 'booking' ); ?></label>
254 <div class="inspector__control">
255 <textarea class="inspector__textarea" rows="3" data-inspector-key="help">{{ data.help || '<?php echo esc_js( __( 'Enter your email address.', 'booking' ) ); ?>' }}</textarea>
256 </div>
257 </div>
258 </div>
259 </section>
260 <?php /* ?>
261 <section class="wpbc_bfb__inspector__group wpbc_ui__collapsible_group" data-group="validation">
262 <button type="button" class="group__header">
263 <h3><?php echo esc_html__( 'Validation', 'booking' ); ?></h3>
264 <i class="wpbc_ui_el__vert_menu_root_section_icon menu_icon icon-1x wpbc-bi-chevron-right"></i>
265 </button>
266 <div class="group__fields">
267 <div class="inspector__row">
268 <label class="inspector__label"><?php echo esc_html__( 'Min length', 'booking' ); ?></label>
269 <div class="inspector__control">
270 <input type="number" min="0" class="inspector__input" data-inspector-key="minlength" value="{{ data.minlength || '' }}">
271 </div>
272 </div>
273
274 <div class="inspector__row">
275 <label class="inspector__label"><?php echo esc_html__( 'Max length', 'booking' ); ?></label>
276 <div class="inspector__control">
277 <input type="number" min="0" class="inspector__input" data-inspector-key="maxlength" value="{{ data.maxlength || '' }}">
278 </div>
279 </div>
280 </div>
281 </section>
282 <?php */ ?>
283 <section class="wpbc_bfb__inspector__group wpbc_ui__collapsible_group" data-group="appearance">
284 <button type="button" class="group__header">
285 <h3><?php echo esc_html__( 'Appearance', 'booking' ); ?></h3>
286 <i class="wpbc_ui_el__vert_menu_root_section_icon menu_icon icon-1x wpbc-bi-chevron-right"></i>
287 </button>
288 <div class="group__fields">
289 <div class="inspector__row">
290 <label class="inspector__label"><?php echo esc_html__( 'CSS class', 'booking' ); ?></label>
291 <div class="inspector__control">
292 <input type="text" class="inspector__input" data-inspector-key="cssclass" value="{{ data.cssclass || '' }}">
293 </div>
294 </div>
295
296 <div class="inspector__row">
297 <label class="inspector__label"><?php echo esc_html__( 'HTML ID', 'booking' ); ?></label>
298 <div class="inspector__control">
299 <input type="text" class="inspector__input" data-inspector-key="html_id" value="{{ data.html_id || '' }}">
300 </div>
301 </div>
302 </div>
303 </section>
304
305 </div><!-- .wpbc_bfb__inspector__body -->
306 </script>
307 <?php
308 }
309
310 /**
311 * (Optional) Register the "Email" palette item in "general/bottom".
312 *
313 * @param string $group Palette group: 'general' | 'advanced' | ...
314 * @param string $position Position: 'top' | 'bottom'
315 * @return void
316 */
317 function wpbc_bfb_palette_register_items__email_wptpl( $group, $position ) {
318
319 if ( 'essentials' !== $group || 'top' !== $position ) {
320 return;
321 }
322
323 ?>
324 <li class="wpbc_bfb__field"
325 data-id="email"
326 data-type="email"
327 data-usage_key="email"
328 data-label="<?php echo esc_attr( __( 'Email', 'booking' ) ); ?>"
329 data-usagenumber="1"
330 >
331 <i class="menu_icon icon-1x wpbc-bi-envelope"></i>
332 <span class="wpbc_bfb__field-label"><?php echo esc_html( __( 'Email', 'booking' ) ); ?></span>
333 <span class="wpbc_bfb__field-type">email</span>
334 </li>
335 <?php
336 }
337 add_action( 'wpbc_bfb_palette_register_items', 'wpbc_bfb_palette_register_items__email_wptpl', 10, 2 );
338
339
340 //TODO:
341 /**
342 * (Optional) Export "email" field to Booking Calendar shortcode.
343 * If your core provides the 'wpbc_bfb_export_field_to_shortcode' filter, this handler will format:
344 * [email name 3/10 id:HTML_ID class:CSSCLASS "[email protected]"]
345 *
346 * @param string $shortcode Previously generated shortcode (or empty).
347 * @param array $field Field array with 'type' and 'props'.
348 * @param array $ctx Export context (optional).
349 * @return string Shortcode for this field type, or original string for other types.
350 */
351 function wpbc_bfb_export_field__email_to_shortcode( $shortcode, $field, $ctx = array() ) {
352
353 if ( empty( $field['type'] ) || 'email' !== $field['type'] ) {
354 return $shortcode;
355 }
356
357 $props = isset( $field['props'] ) && is_array( $field['props'] ) ? $field['props'] : array();
358 $name = isset( $props['name'] ) && '' !== $props['name'] ? $props['name'] : ( isset( $field['id'] ) ? $field['id'] : 'email' );
359 $html_id = isset( $props['html_id'] ) ? trim( $props['html_id'] ) : '';
360 $cssclass = isset( $props['cssclass'] ) ? trim( $props['cssclass'] ) : '';
361 // $minlength = ( isset( $props['minlength'] ) && '' !== $props['minlength'] ) ? intval( $props['minlength'] ) : null;
362 // $maxlength = ( isset( $props['maxlength'] ) && '' !== $props['maxlength'] ) ? intval( $props['maxlength'] ) : null;
363 $default = isset( $props['default_value'] ) ? $props['default_value'] : '';
364
365 $len = '';
366 // if ( null !== $minlength || null !== $maxlength ) {
367 // $len = sprintf( '%s/%s',
368 // ( null !== $minlength ? max( 0, $minlength ) : '' ),
369 // ( null !== $maxlength ? max( 0, $maxlength ) : '' )
370 // );
371 // $len = trim( $len, '/' );
372 // }
373
374 $parts = array( 'email', $name );
375 if ( '' !== $len ) {
376 $parts[] = $len;
377 }
378 if ( '' !== $html_id ) {
379 $parts[] = 'id:' . $html_id;
380 }
381 if ( '' !== $cssclass ) {
382 $parts[] = 'class:' . $cssclass;
383 }
384 if ( '' !== $default ) {
385 // Wrap default in quotes; keep inner quotes untouched (exporter typically prints raw).
386 $parts[] = '"' . str_replace( '"', '\"', $default ) . '"';
387 }
388
389 return '[' . implode( ' ', $parts ) . ']';
390 }
391 add_filter( 'wpbc_bfb_export_field_to_shortcode', 'wpbc_bfb_export_field__email_to_shortcode', 10, 3 );
392