PluginProbe ʕ •ᴥ•ʔ
Everest Forms – Contact Form, Payment Form, Quiz, Survey & Custom Form Builder with AI / 1.6.3
Everest Forms – Contact Form, Payment Form, Quiz, Survey & Custom Form Builder with AI v1.6.3
3.5.2 3.5.1 3.5.0 3.4.8 3.4.7 3.4.6 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.5.1 1.1.6 1.1.7 1.1.8 1.1.9 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.10 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.6.1 1.6.7 1.7.0 1.7.0.1 1.7.0.2 1.7.0.3 1.7.1 1.7.2 1.7.2.1 1.7.2.2 1.7.3 1.7.4 1.7.5 1.7.5.1 1.7.5.2 1.7.6 1.7.7 1.7.7.1 1.7.7.2 1.7.8 1.7.9 1.8.0 1.8.0.1 1.8.1 1.8.2 1.8.2.1 1.8.2.2 1.8.2.3 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.0.1 1.9.1 1.9.2 1.9.3 1.9.4 1.9.4.1 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.0.1 2.0.1 2.0.2 2.0.3 2.0.3.1 2.0.4 2.0.4.1 2.0.5 2.0.6 2.0.7 2.0.8 2.0.8.1 2.0.9 3.0.0 3.0.0.1 3.0.1 3.0.2 3.0.3 3.0.3.1 3.0.4 3.0.4.1 3.0.4.2 3.0.5 3.0.5.1 3.0.5.2 3.0.6 3.0.6.1 3.0.7.1 3.0.8 3.0.8.1 3.0.9 3.0.9.1 3.0.9.2 3.0.9.3 3.0.9.4 3.0.9.5 3.1.0 3.1.1 3.1.2 3.2.0 3.2.1 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.3.0 3.4.0 3.4.1 3.4.2 3.4.2.1 3.4.3 3.4.4 3.4.5 trunk 1.0 1.0.1 1.0.2 1.0.3
everest-forms / includes / shortcodes / class-evf-shortcode-form.php
everest-forms / includes / shortcodes Last commit date
class-evf-shortcode-form.php 6 years ago
class-evf-shortcode-form.php
845 lines
1 <?php
2 /**
3 * Form Shortcode
4 *
5 * Used on the show frontend form.
6 *
7 * @package EverestForms\Shortcodes\Form
8 * @version 1.0.0
9 * @since 1.3.2
10 */
11
12 defined( 'ABSPATH' ) || exit;
13
14 /**
15 * Form Shortcode class.
16 */
17 class EVF_Shortcode_Form {
18
19 /**
20 * Contains information for multi-part forms.
21 *
22 * Forms that do not contain parts return false, otherwise returns an array
23 * that contains the number of total parts and part counter used when
24 * displaying part rows.
25 *
26 * @since 1.3.2
27 *
28 * @var array
29 */
30 public static $parts = array();
31
32 /**
33 * Hooks in tab.
34 */
35 public static function hooks() {
36 add_action( 'everest_forms_frontend_output_success', 'evf_print_notices', 10, 2 );
37 add_action( 'everest_forms_frontend_output', array( 'EVF_Shortcode_Form', 'header' ), 5, 4 );
38 add_action( 'everest_forms_frontend_output', array( 'EVF_Shortcode_Form', 'fields' ), 10, 3 );
39 add_action( 'everest_forms_display_field_before', array( 'EVF_Shortcode_Form', 'wrapper_start' ), 5, 2 );
40 add_action( 'everest_forms_display_field_before', array( 'EVF_Shortcode_Form', 'label' ), 15, 2 );
41 add_action( 'everest_forms_display_field_before', array( 'EVF_Shortcode_Form', 'description' ), 20, 2 );
42 add_action( 'everest_forms_display_field_after', array( 'EVF_Shortcode_Form', 'messages' ), 3, 2 );
43 add_action( 'everest_forms_display_field_after', array( 'EVF_Shortcode_Form', 'description' ), 5, 2 );
44 add_action( 'everest_forms_display_field_after', array( 'EVF_Shortcode_Form', 'wrapper_end' ), 15, 2 );
45 add_action( 'everest_forms_frontend_output', array( 'EVF_Shortcode_Form', 'honeypot' ), 15, 3 );
46 add_action( 'everest_forms_frontend_output', array( 'EVF_Shortcode_Form', 'recaptcha' ), 20, 3 );
47 add_action( 'everest_forms_frontend_output', array( 'EVF_Shortcode_Form', 'footer' ), 25, 3 );
48 }
49
50 /**
51 * Form footer area.
52 *
53 * @param array $form_data Form data and settings.
54 * @param bool $title Whether to display form title.
55 * @param bool $description Whether to display form description.
56 */
57 public static function footer( $form_data, $title, $description ) {
58 $form_id = absint( $form_data['id'] );
59 $settings = isset( $form_data['settings'] ) ? $form_data['settings'] : array();
60 $submit = apply_filters( 'everest_forms_field_submit', isset( $settings['submit_button_text'] ) ? $settings['submit_button_text'] : __( 'Submit', 'everest-forms' ), $form_data );
61 $submit_btn = evf_string_translation( $form_data['id'], 'submit_button', $submit );
62 $process = '';
63 $classes = isset( $form_data['settings']['submit_button_class'] ) ? evf_sanitize_classes( $form_data['settings']['submit_button_class'] ) : '';
64 $parts = ! empty( self::$parts[ $form_id ] ) ? self::$parts[ $form_id ] : array();
65 $visible = ! empty( $parts ) ? 'style="display:none"' : '';
66
67 // Visibility class.
68 $visibility_class = apply_filters( 'everest_forms_field_submit_visibility_class', array(), $parts, $form_data );
69
70 // Check for submit button processing-text.
71 if ( ! isset( $settings['submit_button_processing_text'] ) ) {
72 $process = 'data-process-text="' . esc_attr__( 'Processing&hellip;', 'everest-forms' ) . '"';
73 } elseif ( ! empty( $settings['submit_button_processing_text'] ) ) {
74 $process = 'data-process-text="' . esc_attr( $settings['submit_button_processing_text'] ) . '"';
75 }
76
77 // Submit button area.
78 $conditional_id = 'evf-submit-' . $form_id;
79 if ( isset( $form_data['settings']['submit']['connection_1']['conditional_logic_status'] ) && '1' === $form_data['settings']['submit']['connection_1']['conditional_logic_status'] ) {
80 $con_rules = array(
81 'conditional_option' => isset( $form_data['settings']['submit']['connection_1']['conditional_option'] ) ? $form_data['settings']['submit']['connection_1']['conditional_option'] : '',
82 'conditionals' => isset( $form_data['settings']['submit']['connection_1']['conditionals'] ) ? $form_data['settings']['submit']['connection_1']['conditionals'] : '',
83 );
84 } else {
85 $con_rules = '';
86 }
87
88 $conditional_rules = wp_json_encode( $con_rules );
89
90 echo '<div class="evf-submit-container ' . esc_attr( implode( ' ', $visibility_class ) ) . '" >';
91
92 echo '<input type="hidden" name="everest_forms[id]" value="' . absint( $form_id ) . '">';
93
94 echo '<input type="hidden" name="everest_forms[author]" value="' . absint( get_the_author_meta( 'ID' ) ) . '">';
95
96 if ( is_singular() ) {
97 echo '<input type="hidden" name="everest_forms[post_id]" value="' . get_the_ID() . '">';
98 }
99
100 do_action( 'everest_forms_display_submit_before', $form_data );
101
102 printf(
103 "<button type='submit' name='everest_forms[submit]' class='everest-forms-submit-button button evf-submit %s' id='evf-submit-%d' value='evf-submit' %s conditional_rules='%s' conditional_id='%s' %s>%s</button>",
104 $classes, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
105 $form_id, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
106 $process, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
107 $conditional_rules, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
108 $conditional_id, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
109 $visible, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
110 $submit_btn // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
111 );
112
113 do_action( 'everest_forms_display_submit_after', $form_data );
114
115 echo '</div>';
116 }
117
118 /**
119 * Message.
120 *
121 * @param array $field Field.
122 * @param array $form_data Form data.
123 */
124 public static function messages( $field, $form_data ) {
125 $error = $field['properties']['error'];
126
127 if ( empty( $error['value'] ) || is_array( $error['value'] ) ) {
128 return;
129 }
130
131 printf(
132 '<label %s>%s</label>',
133 evf_html_attributes( $error['id'], $error['class'], $error['data'], $error['attr'] ),
134 esc_html( $error['value'] )
135 );
136 }
137
138 /**
139 * Description.
140 *
141 * @param array $field Field.
142 * @param array $form_data Form data.
143 */
144 public static function description( $field, $form_data ) {
145 $action = current_action();
146
147 $description = $field['properties']['description'];
148
149 // If the description is empty don't proceed.
150 if ( empty( $description['value'] ) ) {
151 return;
152 }
153
154 // Determine positioning.
155 if ( 'everest_forms_display_field_before' === $action && 'before' !== $description['position'] ) {
156 return;
157 }
158 if ( 'everest_forms_display_field_after' === $action && 'after' !== $description['position'] ) {
159 return;
160 }
161
162 if ( 'before' === $description['position'] ) {
163 $description['class'][] = 'evf-field-description-before';
164 }
165
166 printf(
167 '<div %s>%s</div>',
168 evf_html_attributes( $description['id'], $description['class'], $description['data'], $description['attr'] ),
169 evf_string_translation( $form_data['id'], $field['id'], $description['value'] ) // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
170 );
171 }
172
173 /**
174 * Label.
175 *
176 * @param array $field Field.
177 * @param array $form_data Form data.
178 */
179 public static function label( $field, $form_data ) {
180 $label = $field['properties']['label'];
181
182 // If the label is empty or disabled don't proceed.
183 if ( empty( $label['value'] ) || $label['disabled'] ) {
184 return;
185 }
186
187 $required = $label['required'] ? apply_filters( 'everest_forms_field_required_label', '<abbr class="required" title="' . esc_attr__( 'Required', 'everest-forms' ) . '">*</abbr>' ) : '';
188 $custom_tags = apply_filters( 'everest_forms_field_custom_tags', false, $field, $form_data );
189
190 printf(
191 '<label %s><span class="evf-label">%s</span> %s</label>',
192 evf_html_attributes( $label['id'], $label['class'], $label['data'], $label['attr'] ),
193 evf_string_translation( $form_data['id'], $field['id'], esc_html( $label['value'] ) ), // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
194 $required, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
195 $custom_tags // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
196 );
197 }
198
199 /**
200 * Wrapper end.
201 *
202 * @param array $field Field.
203 * @param array $form_data Form data.
204 */
205 public static function wrapper_end( $field, $form_data ) {
206 echo '</div>';
207 }
208
209 /**
210 * Wrapper start.
211 *
212 * @param array $field Field.
213 * @param array $form_data Form data.
214 */
215 public static function wrapper_start( $field, $form_data ) {
216 $container = $field['properties']['container'];
217 $container['data']['field-id'] = esc_attr( $field['id'] );
218 printf(
219 '<div %s>',
220 evf_html_attributes( $container['id'], $container['class'], $container['data'], $container['attr'] )
221 );
222 }
223
224 /**
225 * Form header for displaying form title and description if enabled.
226 *
227 * @param array $form_data Form data and settings.
228 * @param bool $title Whether to display form title.
229 * @param bool $description Whether to display form description.
230 * @param array $errors List of all errors during form submission.
231 */
232 public static function header( $form_data, $title, $description, $errors ) {
233 $settings = isset( $form_data['settings'] ) ? $form_data['settings'] : array();
234
235 // Check if title and/or description is enabled.
236 if ( true === $title || true === $description ) {
237 echo '<div class="evf-title-container">';
238
239 if ( true === $title && ! empty( $settings['form_title'] ) ) {
240 echo '<div class="everest-forms--title">' . esc_html( $settings['form_title'] ) . '</div>';
241 }
242
243 if ( true === $description && ! empty( $settings['form_description'] ) ) {
244 echo '<div class="everest-forms--description">' . esc_textarea( $settings['form_description'] ) . '</div>';
245 }
246
247 echo '</div>';
248 }
249
250 // Output header errors if they exist.
251 if ( ! empty( $errors['header'] ) ) {
252 evf_add_notice( $errors['header'], 'error' );
253 }
254 }
255
256 /**
257 * Form field area.
258 *
259 * @param array $form_data Form data and settings.
260 * @param bool $title Whether to display form title.
261 * @param bool $description Whether to display form description.
262 */
263 public static function fields( $form_data, $title, $description ) {
264 $structure = isset( $form_data['structure'] ) ? $form_data['structure'] : array();
265
266 // Bail if empty form fields.
267 if ( empty( $form_data['form_fields'] ) ) {
268 return;
269 }
270
271 // Form fields area.
272 echo '<div class="evf-field-container">';
273
274 wp_nonce_field( 'everest-forms_process_submit' );
275
276 /**
277 * Hook: everest_forms_display_fields_before.
278 *
279 * @hooked EverestForms_MultiPart::display_fields_before() Multi-Part markup open.
280 */
281 do_action( 'everest_forms_display_fields_before', $form_data );
282
283 foreach ( $structure as $row_key => $row ) {
284
285 /**
286 * Hook: everest_forms_display_row_before.
287 */
288 do_action( 'everest_forms_display_row_before', $row_key, $form_data );
289
290 echo '<div class="evf-frontend-row" data-row="' . esc_attr( $row_key ) . '">';
291
292 foreach ( $row as $grid_key => $grid ) {
293 $number_of_grid = count( $row );
294
295 echo '<div class="evf-frontend-grid evf-grid-' . absint( $number_of_grid ) . '" data-grid="' . esc_attr( $grid_key ) . '">';
296
297 if ( ! is_array( $grid ) ) {
298 $grid = array();
299 }
300
301 foreach ( $grid as $field_key ) {
302 $field = isset( $form_data['form_fields'][ $field_key ] ) ? $form_data['form_fields'][ $field_key ] : array();
303 $field = apply_filters( 'everest_forms_field_data', $field, $form_data );
304
305 if ( empty( $field ) || in_array( $field['type'], evf()->form_fields->get_pro_form_field_types(), true ) ) {
306 continue;
307 }
308
309 // Get field attributes.
310 $attributes = self::get_field_attributes( $field, $form_data );
311
312 // Get field properties.
313 $properties = self::get_field_properties( $field, $form_data, $attributes );
314
315 // Add properties to the field so it's available everywhere.
316 $field['properties'] = $properties;
317
318 do_action( 'everest_forms_display_field_before', $field, $form_data );
319
320 do_action( "everest_forms_display_field_{$field['type']}", $field, $attributes, $form_data );
321
322 do_action( 'everest_forms_display_field_after', $field, $form_data );
323 }
324
325 echo '</div>';
326 }
327
328 echo '</div>';
329
330 /**
331 * Hook: everest_forms_display_row_after.
332 *
333 * @hooked EverestForms_MultiPart::display_row_after() Multi-Part markup (close previous part, open next).
334 */
335 do_action( 'everest_forms_display_row_after', $row_key, $form_data );
336 }
337
338 /**
339 * Hook: everest_forms_display_fields_after.
340 *
341 * @hooked EverestForms_MultiPart::display_fields_after() Multi-Part markup open.
342 */
343 do_action( 'everest_forms_display_fields_after', $form_data );
344
345 echo '</div>';
346 }
347
348 /**
349 * Anti-spam honeypot output if configured.
350 *
351 * @since 1.4.9
352 * @param array $form_data Form data and settings.
353 */
354 public static function honeypot( $form_data ) {
355 $names = array( 'Name', 'Phone', 'Comment', 'Message', 'Email', 'Website' );
356
357 // Output the honeypot container.
358 if ( isset( $form_data['settings']['honeypot'] ) && '1' === $form_data['settings']['honeypot'] ) {
359 echo '<div class="evf-honeypot-container evf-field-hp">';
360
361 echo '<label for="evf-' . $form_data['id'] . '-field-hp" class="evf-field-label">' . $names[ array_rand( $names ) ] . '</label>'; // phpcs:ignore
362
363 echo '<input type="text" name="everest_forms[hp]" id="evf-' . $form_data['id'] . '-field-hp" class="input-text">'; // phpcs:ignore
364
365 echo '</div>';
366 }
367 }
368
369 /**
370 * Google reCAPTCHA output if configured.
371 *
372 * @param array $form_data Form data and settings.
373 */
374 public static function recaptcha( $form_data ) {
375 $recaptcha_type = get_option( 'everest_forms_recaptcha_type', 'v2' );
376 $invisible_recaptcha = get_option( 'everest_forms_recaptcha_v2_invisible', 'no' );
377
378 if ( 'v2' === $recaptcha_type && 'no' === $invisible_recaptcha ) {
379 $site_key = get_option( 'everest_forms_recaptcha_v2_site_key' );
380 $secret_key = get_option( 'everest_forms_recaptcha_v2_secret_key' );
381 } elseif ( 'v2' === $recaptcha_type && 'yes' === $invisible_recaptcha ) {
382 $site_key = get_option( 'everest_forms_recaptcha_v2_invisible_site_key' );
383 $secret_key = get_option( 'everest_forms_recaptcha_v2_invisible_secret_key' );
384 } else {
385 $site_key = get_option( 'everest_forms_recaptcha_v3_site_key' );
386 $secret_key = get_option( 'everest_forms_recaptcha_v3_secret_key' );
387 }
388
389 if ( ! $site_key || ! $secret_key ) {
390 return;
391 }
392
393 if ( isset( $form_data['settings']['recaptcha_support'] ) && '1' === $form_data['settings']['recaptcha_support'] ) {
394 $form_id = isset( $form_data['id'] ) ? absint( $form_data['id'] ) : 0;
395 $visible = ! empty( self::$parts[ $form_id ] ) ? 'style="display:none;"' : '';
396 $data = apply_filters(
397 'everest_forms_frontend_recaptcha',
398 array(
399 'sitekey' => trim( sanitize_text_field( $site_key ) ),
400 ),
401 $form_data
402 );
403
404 // Load reCAPTCHA support if form supports it.
405 if ( $site_key && $secret_key ) {
406 if ( 'v2' === $recaptcha_type ) {
407 $recaptcha_version = '2.0.0';
408 $recaptcha_api = apply_filters( 'everest_forms_frontend_recaptcha_url', 'https://www.google.com/recaptcha/api.js?onload=EVFRecaptchaLoad&render=explicit' );
409 if ( 'yes' === $invisible_recaptcha ) {
410 $recaptcha_inline = 'var EVFRecaptchaLoad = function(){jQuery(".g-recaptcha").each(function(index, el){var recaptchaID = grecaptcha.render(el,{},true); grecaptcha.execute(recaptchaID);});};';
411 } else {
412 $recaptcha_inline = 'var EVFRecaptchaLoad = function(){jQuery(".g-recaptcha").each(function(index, el){grecaptcha.render(el,{callback:function(){EVFRecaptchaCallback(el);}},true);});};';
413 $recaptcha_inline .= 'var EVFRecaptchaCallback = function(el){jQuery(el).parent().find(".evf-recaptcha-hidden").val("1").valid();};';
414 }
415 } else {
416 $recaptcha_version = '3.0.0';
417 $recaptcha_api = apply_filters( 'everest_forms_frontend_recaptcha_url', 'https://www.google.com/recaptcha/api.js?render=' . $site_key );
418 $recaptcha_inline = 'grecaptcha.ready( function() { grecaptcha.execute( "' . $site_key . '", { action: "everest_form" } ).then( function( token ) { jQuery( ".evf-recaptcha-hidden" ).val( token ); } ) } )';
419 }
420
421 // Enqueue reCaptcha scripts.
422 wp_enqueue_script( 'evf-recaptcha', $recaptcha_api, array( 'jquery' ), $recaptcha_version, false );
423
424 // Load reCaptcha callback once.
425 static $count = 1;
426 if ( 1 === $count ) {
427 wp_add_inline_script( 'evf-recaptcha', $recaptcha_inline );
428 $count++;
429 }
430
431 if ( 'v2' === $recaptcha_type && 'yes' === $invisible_recaptcha ) {
432 // Output the reCAPTCHA container.
433 $data['size'] = 'invisible';
434 $data['sitekey'] = $site_key;
435 echo '<div class="evf-recaptcha-container recaptcha-hidden" ' . $visible . '>'; // @codingStandardsIgnoreLine
436 echo '<div ' . evf_html_attributes( '', array( 'g-recaptcha' ), $data ) . '></div>';
437 echo '</div>';
438 } else {
439 // Output the reCAPTCHA container.
440 $class = 'v3' === $recaptcha_type ? 'recaptcha-hidden' : '';
441 echo '<div class="evf-recaptcha-container ' . $class . '" ' . $visible . '>'; // @codingStandardsIgnoreLine
442 echo '<div ' . evf_html_attributes( '', array( 'g-recaptcha' ), $data ) . '></div>';
443 echo '<input type="text" name="g-recaptcha-hidden" class="evf-recaptcha-hidden" style="position:absolute!important;clip:rect(0,0,0,0)!important;height:1px!important;width:1px!important;border:0!important;overflow:hidden!important;padding:0!important;margin:0!important;" required>';
444 echo '</div>';
445 }
446 }
447 }
448 }
449
450 /**
451 * Get field attributes.
452 *
453 * @param array $field Field.
454 * @param array $form_data Form data.
455 *
456 * @return array
457 */
458 private static function get_field_attributes( $field, $form_data ) {
459 $form_id = absint( $form_data['id'] );
460 $field_id = esc_attr( $field['id'] );
461 $attributes = array(
462 'field_class' => array( 'evf-field', 'evf-field-' . sanitize_html_class( $field['type'] ), 'form-row' ),
463 'field_id' => array( sprintf( 'evf-%d-field_%s-container', $form_id, $field_id ) ),
464 'field_style' => '',
465 'label_class' => array( 'evf-field-label' ),
466 'label_id' => '',
467 'description_class' => array( 'evf-field-description' ),
468 'description_id' => array(),
469 'input_id' => array( sprintf( 'evf-%d-field_%s', $form_id, $field_id ) ),
470 'input_class' => array(),
471 'input_data' => array(),
472 );
473
474 // Check user field defined classes.
475 if ( ! empty( $field['css'] ) ) {
476 $attributes['field_class'] = array_merge( $attributes['field_class'], evf_sanitize_classes( $field['css'], true ) );
477 }
478
479 // Check for input column layouts.
480 if ( ! empty( $field['input_columns'] ) ) {
481 if ( 'inline' === $field['input_columns'] ) {
482 $attributes['field_class'][] = 'everest-forms-list-inline';
483 } elseif ( '' !== $field['input_columns'] ) {
484 $attributes['field_class'][] = 'everest-forms-list-' . $field['input_columns'] . '-columns';
485 }
486 }
487
488 // Input class.
489 if ( ! in_array( $field['type'], array( 'checkbox', 'radio', 'payment-checkbox', 'payment-multiple' ), true ) ) {
490 $attributes['input_class'][] = 'input-text';
491 }
492
493 // Check label visibility.
494 if ( ! empty( $field['label_hide'] ) ) {
495 $attributes['label_class'][] = 'evf-label-hide';
496 }
497
498 // Check size.
499 if ( ! empty( $field['size'] ) ) {
500 $attributes['input_class'][] = 'evf-field-' . sanitize_html_class( $field['size'] );
501 }
502
503 // Check if required.
504 if ( ! empty( $field['required'] ) ) {
505 $attributes['field_class'][] = 'validate-required';
506 }
507
508 // Check if extra validation required.
509 if ( in_array( $field['type'], array( 'email', 'phone' ), true ) ) {
510 $attributes['field_class'][] = 'validate-' . esc_attr( $field['type'] );
511 }
512
513 // Check if there are errors.
514 if ( isset( evf()->task->errors[ $form_id ][ $field_id ] ) ) {
515 $attributes['input_class'][] = 'evf-error';
516 $attributes['field_class'][] = 'everest-forms-invalid';
517 }
518
519 // This filter is deprecated, filter the properties (below) instead.
520 $attributes = apply_filters( 'evf_field_atts', $attributes, $field, $form_data );
521
522 return $attributes;
523 }
524
525 /**
526 * Return base properties for a specific field.
527 *
528 * @param array $field Field data and settings.
529 * @param array $form_data Form data and settings.
530 * @param array $attributes List of field attributes.
531 *
532 * @return array
533 */
534 private static function get_field_properties( $field, $form_data, $attributes = array() ) {
535 // This filter is for backwards compatibility purposes.
536 $types = array( 'text', 'textarea', 'number', 'email', 'hidden', 'url', 'html', 'title', 'password', 'phone', 'address', 'checkbox', 'radio', 'select' );
537 if ( in_array( $field['type'], $types, true ) ) {
538 $field = apply_filters( "everest_forms_{$field['type']}_field_display", $field, $attributes, $form_data );
539 }
540
541 $form_id = absint( $form_data['id'] );
542 $field_id = sanitize_text_field( $field['id'] );
543
544 // Field container data.
545 $container_data = array();
546
547 // Embed required-field-message to the container if the field is required.
548 if ( isset( $field['required'] ) && ( '1' === $field['required'] || true === $field['required'] ) ) {
549 $has_sub_fields = false;
550 $sub_field_messages = array();
551
552 $required_validation = get_option( 'everest_forms_required_validation' );
553 if ( in_array( $field['type'], array( 'number', 'email', 'url', 'phone' ), true ) ) {
554 $required_validation = get_option( 'everest_forms_' . $field['type'] . '_validation' );
555 }
556
557 if ( 'likert' === $field['type'] ) {
558 $has_sub_fields = true;
559 $likert_rows = isset( $field['likert_rows'] ) ? $field['likert_rows'] : array();
560 $row_keys = array();
561 foreach ( $likert_rows as $row_key => $row_label ) {
562 $row_keys[] = $row_key;
563 $row_slug = 'required-field-message-' . $row_key;
564 $sub_field_messages[ $row_key ] = isset( $field[ $row_slug ] ) ? $field[ $row_slug ] : $required_validation;
565 }
566 $container_data['row-keys'] = wp_json_encode( $row_keys );
567 } elseif ( 'address' === $field['type'] ) {
568 $has_sub_fields = true;
569 $sub_field_messages = array(
570 'address1' => isset( $field['required-field-message-address1'] ) ? $field['required-field-message-address1'] : '',
571 'city' => isset( $field['required-field-message-city'] ) ? $field['required-field-message-city'] : '',
572 'state' => isset( $field['required-field-message-state'] ) ? $field['required-field-message-state'] : '',
573 'postal' => isset( $field['required-field-message-postal'] ) ? $field['required-field-message-postal'] : '',
574 'country' => isset( $field['required-field-message-country'] ) ? $field['required-field-message-country'] : '',
575 );
576 }
577
578 if ( true === $has_sub_fields ) {
579 foreach ( $sub_field_messages as $sub_field_type => $error_message ) {
580 $container_data[ 'required-field-message-' . $sub_field_type ] = $error_message;
581 }
582 } else {
583 $container_data['required-field-message'] = isset( $field['required-field-message'] ) && '' !== $field['required-field-message'] ? $field['required-field-message'] : $required_validation;
584 }
585 }
586 $errors = isset( evf()->task->errors[ $form_id ][ $field_id ] ) ? evf()->task->errors[ $form_id ][ $field_id ] : '';
587 $properties = apply_filters(
588 'everest_forms_field_properties_' . $field['type'],
589 array(
590 'container' => array(
591 'attr' => array(
592 'style' => $attributes['field_style'],
593 ),
594 'class' => $attributes['field_class'],
595 'data' => $container_data,
596 'id' => implode( '', array_slice( $attributes['field_id'], 0 ) ),
597 ),
598 'label' => array(
599 'attr' => array(
600 'for' => sprintf( 'evf-%d-field_%s', $form_id, $field_id ),
601 ),
602 'class' => $attributes['label_class'],
603 'data' => array(),
604 'disabled' => ! empty( $field['label_disable'] ) ? true : false,
605 'hidden' => ! empty( $field['label_hide'] ) ? true : false,
606 'id' => $attributes['label_id'],
607 'required' => ! empty( $field['required'] ) ? true : false,
608 'value' => ! empty( $field['label'] ) ? $field['label'] : '',
609 ),
610 'inputs' => array(
611 'primary' => array(
612 'attr' => array(
613 'name' => "everest_forms[form_fields][{$field_id}]",
614 'value' => ( isset( $field['default_value'] ) && ! empty( $field['default_value'] ) ) ? apply_filters( 'everest_forms_process_smart_tags', $field['default_value'], $form_data ) : ( isset( $_POST['everest_forms']['form_fields'][ $field_id ] ) ? $_POST['everest_forms']['form_fields'][ $field_id ] : '' ), // @codingStandardsIgnoreLine
615 'placeholder' => ! empty( $field['placeholder'] ) ? evf_string_translation( $form_data['id'], $field['id'], $field['placeholder'] ) : '',
616 ),
617 'class' => $attributes['input_class'],
618 'data' => $attributes['input_data'],
619 'id' => implode( array_slice( $attributes['input_id'], 0 ) ),
620 'required' => ! empty( $field['required'] ) ? 'required' : '',
621 ),
622 ),
623 'error' => array(
624 'attr' => array(
625 'for' => sprintf( 'evf-%d-field_%s', $form_id, $field_id ),
626 ),
627 'class' => array( 'evf-error' ),
628 'data' => array(),
629 'id' => '',
630 'value' => ! empty( $errors ) ? $errors : '',
631 ),
632 'description' => array(
633 'attr' => array(),
634 'class' => $attributes['description_class'],
635 'data' => array(),
636 'id' => implode( '', array_slice( $attributes['description_id'], 0 ) ),
637 'position' => 'after',
638 'value' => ! empty( $field['description'] ) ? $field['description'] : '',
639 ),
640 ),
641 $field,
642 $form_data
643 );
644
645 return apply_filters( 'everest_forms_field_properties', $properties, $field, $form_data );
646 }
647
648 /**
649 * Output the shortcode.
650 *
651 * @param array $atts Attributes.
652 */
653 public static function output( $atts ) {
654 wp_enqueue_script( 'everest-forms' );
655
656 // Load jQuery flatpickr libraries. https://github.com/flatpickr/flatpickr.
657 if ( evf_is_field_exists( $atts['id'], 'date-time' ) ) {
658 wp_enqueue_style( 'flatpickr' );
659 wp_enqueue_script( 'flatpickr' );
660 }
661
662 // Load jQuery mailcheck library - https://github.com/mailcheck/mailcheck.
663 if ( evf_is_field_exists( $atts['id'], 'email' ) && (bool) apply_filters( 'everest_forms_mailcheck_enabled', true ) ) {
664 wp_enqueue_script( 'mailcheck' );
665 }
666
667 $atts = shortcode_atts(
668 array(
669 'id' => false,
670 'title' => false,
671 'description' => false,
672 ),
673 $atts,
674 'output'
675 );
676
677 // Scripts load action.
678 do_action( 'everest_forms_shortcode_scripts', $atts );
679
680 ob_start();
681 self::view( $atts['id'], $atts['title'], $atts['description'] );
682 echo ob_get_clean(); // phpcs:ignore WordPress.Security.EscapeOutput
683 }
684
685 /**
686 * Form view.
687 *
688 * @param int $id Form ID.
689 * @param bool $title Whether to display form title.
690 * @param bool $description Whether to display form description.
691 */
692 private static function view( $id, $title = false, $description = false ) {
693 if ( empty( $id ) ) {
694 return;
695 }
696
697 // Grab the form data, if not found then we bail.
698 $form = evf()->form->get( (int) $id );
699
700 if ( empty( $form ) || 'publish' !== $form->post_status ) {
701 return;
702 }
703
704 // Basic form information.
705 $form_data = apply_filters( 'everest_forms_frontend_form_data', evf_decode( $form->post_content ) );
706 $form_id = absint( $form->ID );
707 $settings = $form_data['settings'];
708 $action = esc_url_raw( remove_query_arg( 'evf-forms' ) );
709 $title = filter_var( $title, FILTER_VALIDATE_BOOLEAN );
710 $description = filter_var( $description, FILTER_VALIDATE_BOOLEAN );
711 $errors = isset( evf()->task->errors[ $form_id ] ) ? evf()->task->errors[ $form_id ] : array();
712 $form_enabled = isset( $form_data['form_enabled'] ) ? absint( $form_data['form_enabled'] ) : 1;
713 $disable_message = isset( $form_data['settings']['form_disable_message'] ) ? $form_data['settings']['form_disable_message'] : __( 'This form is disabled.', 'everest-forms' );
714 $ajax_form_submission = isset( $settings['ajax_form_submission'] ) ? $settings['ajax_form_submission'] : 0;
715
716 if ( 0 !== $ajax_form_submission ) {
717 wp_enqueue_script( 'everest-forms-ajax-submission' );
718 }
719
720 // If the form is disabled or does not contain any fields do not proceed.
721 if ( empty( $form_data['form_fields'] ) ) {
722 echo '<!-- Everest Forms: no fields, form hidden -->';
723 return;
724 } elseif ( 1 !== $form_enabled ) {
725 if ( ! empty( $disable_message ) ) {
726 printf( '<p class="everst-forms-form-disable-notice everest-forms-notice everest-forms-notice--info">%s</p>', esc_textarea( $disable_message ) );
727 }
728 return;
729 }
730
731 // Before output hook.
732 do_action( 'everest_forms_frontend_output_before', $form_data, $form );
733
734 // Allow filter to return early if some condition is not meet.
735 if ( ! apply_filters( 'everest_forms_frontend_load', true, $form_data ) ) {
736 do_action( 'everest_forms_frontend_not_loaded', $form_data, $form );
737 return;
738 }
739
740 $success = apply_filters( 'everest_forms_success', false, $form_id );
741 if ( $success && ! empty( $form_data ) ) {
742 do_action( 'everest_forms_frontend_output_success', $form_data );
743 return;
744 }
745
746 /**
747 * BW compatiable for multi-parts form.
748 *
749 * @todo Remove in Major EVF version 1.6.0
750 */
751 if ( defined( 'EVF_MULTI_PART_PLUGIN_FILE' ) ) {
752 include_once ABSPATH . 'wp-admin/includes/plugin.php';
753 $plugin_data = get_plugin_data( EVF_MULTI_PART_PLUGIN_FILE, false, false );
754
755 if ( version_compare( $plugin_data['Version'], '1.3.0', '<' ) ) {
756 $settings_defaults = array(
757 'indicator' => 'progress',
758 'indicator_color' => '#7e3bd0',
759 'nav_align' => 'center',
760 );
761
762 if ( isset( $form_data['settings']['enable_multi_part'] ) && evf_string_to_bool( $form_data['settings']['enable_multi_part'] ) ) {
763 $settings = isset( $form_data['settings']['multi_part'] ) ? $form_data['settings']['multi_part'] : array();
764
765 if ( ! empty( $form_data['multi_part'] ) ) {
766 self::$parts = array(
767 'total' => count( $form_data['multi_part'] ),
768 'current' => 1,
769 'parts' => array_values( $form_data['multi_part'] ),
770 'settings' => wp_parse_args( $settings, $settings_defaults ),
771 );
772 }
773 } else {
774 self::$parts = array(
775 'total' => '',
776 'current' => '',
777 'parts' => array(),
778 'settings' => $settings_defaults,
779 );
780 }
781 }
782 }
783
784 // Allow Multi-Part to be customized.
785 $parts = ! empty( self::$parts[ $form_id ] ) ? self::$parts[ $form_id ] : array();
786 self::$parts[ $form_id ] = apply_filters( 'everest_forms_parts_data', $parts, $form_data, $form_id );
787
788 // Allow final action to be customized.
789 $action = apply_filters( 'everest_forms_frontend_form_action', $action, $form_data );
790
791 // Allow form container classes to be filtered and user defined classes.
792 $classes = apply_filters( 'everest_forms_frontend_container_class', array(), $form_data );
793 if ( ! empty( $settings['form_class'] ) ) {
794 $classes = array_merge( $classes, explode( ' ', $settings['form_class'] ) );
795 }
796 if ( ! empty( $settings['layout_class'] ) ) {
797 $classes = array_merge( $classes, explode( ' ', $settings['layout_class'] ) );
798 }
799 $classes = evf_sanitize_classes( $classes, true );
800
801 $form_atts = apply_filters(
802 'everest_forms_frontend_form_atts',
803 array(
804 'id' => sprintf( 'evf-form-%d', absint( $form_id ) ),
805 'class' => array( 'everest-form' ),
806 'data' => array(
807 'formid' => absint( $form_id ),
808 'ajax_submission' => $ajax_form_submission,
809 ),
810 'atts' => array(
811 'method' => 'post',
812 'enctype' => 'multipart/form-data',
813 'action' => esc_url( $action ),
814 ),
815 ),
816 $form_data
817 );
818
819 // Begin to build the output.
820 do_action( 'everest_forms_frontend_output_container_before', $form_data, $form );
821
822 printf( '<div class="evf-container %s" id="evf-%d">', esc_attr( $classes ), absint( $form_id ) );
823
824 do_action( 'everest_forms_frontend_output_form_before', $form_data, $form, $errors );
825
826 echo '<form ' . evf_html_attributes( $form_atts['id'], $form_atts['class'], $form_atts['data'], $form_atts['atts'] ) . '>';
827
828 do_action( 'everest_forms_frontend_output', $form_data, $title, $description, $errors );
829
830 echo '</form>';
831
832 do_action( 'everest_forms_frontend_output_form_after', $form_data, $form );
833
834 echo '</div><!-- .evf-container -->';
835
836 // After output hook.
837 do_action( 'everest_forms_frontend_output_after', $form_data, $form );
838
839 // Debug information.
840 if ( is_super_admin() ) {
841 evf_debug_data( $form_data );
842 }
843 }
844 }
845