PluginProbe ʕ •ᴥ•ʔ
Everest Forms – Contact Form, Payment Form, Quiz, Survey & Custom Form Builder with AI / 3.5.2
Everest Forms – Contact Form, Payment Form, Quiz, Survey & Custom Form Builder with AI v3.5.2
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 3 weeks ago
class-evf-shortcode-form.php
1486 lines
1 <?php
2
3 /**
4 * Form Shortcode
5 *
6 * Used on the show frontend form.
7 *
8 * @package EverestForms\Shortcodes\Form
9 * @version 1.0.0
10 * @since 1.3.2
11 */
12
13 defined( 'ABSPATH' ) || exit;
14
15 /**
16 * Form Shortcode class.
17 */
18 class EVF_Shortcode_Form {
19
20
21 /**
22 * Contains information for multi-part forms.
23 *
24 * Forms that do not contain parts return false, otherwise returns an array
25 * that contains the number of total parts and part counter used when
26 * displaying part rows.
27 *
28 * @since 1.3.2
29 *
30 * @var array
31 */
32 public static $parts = array();
33
34 /**
35 * Hooks in tab.
36 */
37 public static function hooks() {
38 add_filter( 'amp_skip_post', array( 'EVF_Shortcode_Form', 'amp_skip_post' ) );
39 add_action( 'everest_forms_frontend_output_success', 'evf_print_notices', 10, 2 );
40 add_action( 'everest_forms_frontend_output', array( 'EVF_Shortcode_Form', 'header' ), 5, 4 );
41 add_action( 'everest_forms_frontend_output', array( 'EVF_Shortcode_Form', 'fields' ), 10, 3 );
42 add_action( 'everest_forms_display_field_before', array( 'EVF_Shortcode_Form', 'wrapper_start' ), 5, 2 );
43 add_action( 'everest_forms_display_field_before', array( 'EVF_Shortcode_Form', 'label' ), 15, 2 );
44 add_action( 'everest_forms_display_field_before', array( 'EVF_Shortcode_Form', 'description' ), 20, 2 );
45 add_action( 'everest_forms_display_field_after', array( 'EVF_Shortcode_Form', 'messages' ), 3, 2 );
46 add_action( 'everest_forms_display_field_after', array( 'EVF_Shortcode_Form', 'description' ), 5, 2 );
47 add_action( 'everest_forms_display_field_after', array( 'EVF_Shortcode_Form', 'wrapper_end' ), 15, 2 );
48 add_action( 'everest_forms_frontend_output', array( 'EVF_Shortcode_Form', 'honeypot' ), 15, 3 );
49 add_action( 'everest_forms_frontend_output', array( 'EVF_Shortcode_Form', 'clean_talk' ), 15, 3 );
50 if ( ! apply_filters( 'everest_forms_recaptcha_disabled', false ) ) {
51 add_action( 'everest_forms_frontend_output', array( 'EVF_Shortcode_Form', 'recaptcha' ), 20, 3 );
52 }
53 add_action( 'everest_forms_frontend_output', array( 'EVF_Shortcode_Form', 'footer' ), 25, 3 );
54 add_action( 'everest_forms_frontend_output', array( 'EVF_Shortcode_Form', 'inline_script_to_update_nonce' ), 26, 3 );
55
56 // reCaptcha Language.
57 add_filter( 'everest_forms_frontend_recaptcha_url', array( __CLASS__, 'evf_recaptcha_language' ), 10, 1 );
58
59 // Enable for submission waiting time.
60 add_filter( 'everest_forms_display_fields_before', array( 'EVF_Shortcode_Form', 'evf_form_submission_waiting_time' ) );
61 }
62
63 /**
64 * Get the amp-state ID for a given form.
65 *
66 * @param int $form_id Form ID.
67 * @return string State ID.
68 */
69 protected static function get_form_amp_state_id( $form_id ) {
70 return sprintf( 'evf_form_state_%d', $form_id );
71 }
72
73 /**
74 * Disable AMP if query param is detected.
75 *
76 * This allows the full form to be accessible for Pro users or sites
77 * that do not have SSL.
78 *
79 * @since 1.5.3
80 *
81 * @param bool $skip Skip AMP mode, display full post.
82 *
83 * @return bool
84 */
85 public static function amp_skip_post( $skip ) {
86
87 return isset( $_GET['nonamp'] ) ? true : $skip; // phpcs:ignore WordPress.Security.NonceVerification
88 }
89
90
91 /**
92 * Form footer area.
93 *
94 * @param array $form_data Form data and settings.
95 * @param bool $title Whether to display form title.
96 * @param bool $description Whether to display form description.
97 */
98 public static function footer( $form_data, $title, $description ) {
99 $form_id = absint( $form_data['id'] );
100 $settings = isset( $form_data['settings'] ) ? $form_data['settings'] : array();
101 $submit = apply_filters( 'everest_forms_field_submit', isset( $settings['submit_button_text'] ) ? $settings['submit_button_text'] : __( 'Submit', 'everest-forms' ), $form_data );
102 $submit_btn = evf_string_translation( $form_data['id'], 'submit_button', $submit );
103 $process = '';
104 $classes = isset( $form_data['settings']['submit_button_class'] ) ? evf_sanitize_classes( $form_data['settings']['submit_button_class'] ) : '';
105 $parts = ! empty( self::$parts[ $form_id ] ) ? self::$parts[ $form_id ] : array();
106 $visible = ! empty( $parts ) ? 'style="display:none"' : '';
107 $attrs = array( 'aria-live' => 'assertive' );
108 $data_attrs = array();
109 $evf_amp_classes = array();
110
111 // Visibility class.
112 $visibility_class = apply_filters( 'everest_forms_field_submit_visibility_class', array(), $parts, $form_data );
113
114 // Check for submit button processing-text.
115 if ( ! isset( $settings['submit_button_processing_text'] ) ) {
116 $process = 'data-process-text="' . esc_attr__( 'Processing&hellip;', 'everest-forms' ) . '"';
117 } elseif ( ! empty( $settings['submit_button_processing_text'] ) ) {
118 if ( evf_is_amp() ) {
119 $attrs['[text]'] = sprintf(
120 '%s.submitting ? %s : %s',
121 self::get_form_amp_state_id( $form_id ),
122 wp_json_encode( $settings['submit_button_processing_text'], JSON_UNESCAPED_UNICODE ),
123 wp_json_encode( $submit, JSON_UNESCAPED_UNICODE )
124 );
125 } else {
126 $process = 'data-process-text="' . esc_attr( evf_string_translation( $form_data['id'], 'processing_text', $settings['submit_button_processing_text'] ) ) . '"';
127 }
128 }
129
130 // Submit button area.
131 $conditional_id = 'evf-submit-' . $form_id;
132 if ( isset( $form_data['settings']['submit']['connection_1']['conditional_logic_status'] ) && '1' === $form_data['settings']['submit']['connection_1']['conditional_logic_status'] ) {
133 $con_rules = array(
134 'conditional_option' => isset( $form_data['settings']['submit']['connection_1']['conditional_option'] ) ? $form_data['settings']['submit']['connection_1']['conditional_option'] : '',
135 'conditionals' => isset( $form_data['settings']['submit']['connection_1']['conditionals'] ) ? $form_data['settings']['submit']['connection_1']['conditionals'] : '',
136 );
137 } else {
138 $con_rules = '';
139 }
140
141 $conditional_rules = wp_json_encode( $con_rules );
142
143 echo '<div class="evf-submit-container ' . esc_attr( implode( ' ', $visibility_class ) ) . '" >';
144
145 echo '<input type="hidden" name="everest_forms[id]" value="' . absint( $form_id ) . '">';
146
147 echo '<input type="hidden" name="everest_forms[author]" value="' . absint( get_the_author_meta( 'ID' ) ) . '">';
148
149 if ( is_singular() ) {
150 echo '<input type="hidden" name="everest_forms[post_id]" value="' . absint( get_the_ID() ) . '">';
151 }
152
153 do_action( 'everest_forms_display_submit_before', $form_data );
154
155 printf(
156 "<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>%s</button>",
157 esc_attr( $classes ),
158 esc_attr( $form_id ),
159 ! isset( $settings['submit_button_processing_text'] ) ? 'data-process-text="' . esc_attr__( 'Processing&hellip;', 'everest-forms' ) . '"' : ( ! empty( $settings['submit_button_processing_text'] ) ? 'data-process-text="' . esc_attr( evf_string_translation( $form_data['id'], 'processing_text', $settings['submit_button_processing_text'] ) ) . '"' : '' ),
160 esc_attr( $conditional_rules ),
161 esc_attr( $conditional_id ),
162 ( ! empty( self::$parts[ $form_id ] ) ? 'style="display:none"' : '' ),
163 evf_html_attributes(
164 sprintf( 'evf-submit-%d', absint( $form_id ) ),
165 $evf_amp_classes,
166 $data_attrs,
167 $attrs
168 ),
169 esc_html( $submit_btn )
170 );
171
172 do_action( 'everest_forms_display_submit_after', $form_data );
173
174 echo '</div>';
175
176 if ( evf_is_amp() ) {
177 printf( '<div submit-success><template type="amp-mustache"><div class=" everest-forms-notice everest-forms-notice--success {{#redirecting}}evf-redirection-message{{/redirecting}}">{{{message}}}</div></template></div>' );
178 return;
179 }
180 }
181
182 /**
183 * Message.
184 *
185 * @param array $field Field.
186 * @param array $form_data Form data.
187 */
188 public static function messages( $field, $form_data ) {
189 $error = $field['properties']['error'];
190
191 if ( empty( $error['value'] ) || is_array( $error['value'] ) ) {
192 return;
193 }
194
195 printf(
196 '<label %s>%s</label>',
197 evf_html_attributes( $error['id'], $error['class'], $error['data'], $error['attr'] ),
198 esc_html( $error['value'] )
199 );
200 }
201
202 /**
203 * Description.
204 *
205 * @param array $field Field.
206 * @param array $form_data Form data.
207 */
208 public static function description( $field, $form_data ) {
209 $action = current_action();
210
211 $description = $field['properties']['description'];
212
213 // If the description is empty don't proceed.
214 if ( empty( $description['value'] ) ) {
215 return;
216 }
217
218 // Determine positioning.
219 if ( 'everest_forms_display_field_before' === $action && 'before' !== $description['position'] ) {
220 return;
221 }
222 if ( 'everest_forms_display_field_after' === $action && 'after' !== $description['position'] ) {
223 return;
224 }
225
226 if ( 'before' === $description['position'] ) {
227 $description['class'][] = 'evf-field-description-before';
228 }
229
230 printf(
231 '<div %s>%s</div>',
232 evf_html_attributes( $description['id'], $description['class'], $description['data'], $description['attr'] ),
233 wp_kses_post( evf_string_translation( $form_data['id'], $field['id'], $description['value'], '-description' ) )
234 );
235 }
236
237 /**
238 * Label.
239 *
240 * @param array $field Field.
241 * @param array $form_data Form data.
242 */
243 public static function label( $field, $form_data ) {
244
245 $label = $field['properties']['label'];
246 // If the label is empty or disabled don't proceed.
247 if ( empty( $label['value'] ) || $label['disabled'] ) {
248 return;
249 }
250
251 $required = $label['required'] ? apply_filters( 'everest_forms_field_required_label', '<abbr class="required" title="' . esc_attr__( 'Required', 'everest-forms' ) . '">' . apply_filters( 'everest_form_get_required_type', '*', $field, $form_data ) . '</abbr>' ) : '';
252 $custom_tags = apply_filters( 'everest_forms_field_custom_tags', false, $field, $form_data );
253
254 printf(
255 '<label %s><span class="evf-label">%s</span> %s</label>',
256 evf_html_attributes( $label['id'], $label['class'], $label['data'], $label['attr'] ),
257 wp_kses(
258 evf_string_translation(
259 $form_data['id'],
260 $field['id'],
261 wp_kses(
262 $label['value'],
263 array(
264 'a' => array(
265 'href' => array(),
266 'class' => array(),
267 ),
268 'span' => array(
269 'class' => array(),
270 ),
271 'em' => array(),
272 'small' => array(),
273 'strong' => array(),
274 )
275 )
276 ),
277 array(
278 'a' => array(
279 'href' => array(),
280 'class' => array(),
281 ),
282 'span' => array(
283 'class' => array(),
284 ),
285 'em' => array(),
286 'small' => array(),
287 'strong' => array(),
288 )
289 ),
290 wp_kses_post( $required ),
291 wp_kses_post( $custom_tags )
292 );
293 }
294
295 /**
296 * Wrapper end.
297 *
298 * @param array $field Field.
299 * @param array $form_data Form data.
300 */
301 public static function wrapper_end( $field, $form_data ) {
302 echo '</div>';
303 }
304
305 /**
306 * Wrapper start.
307 *
308 * @param array $field Field.
309 * @param array $form_data Form data.
310 */
311 public static function wrapper_start( $field, $form_data ) {
312 $container = $field['properties']['container'];
313 $container['data']['field-id'] = esc_attr( $field['id'] );
314 printf(
315 '<div %s>',
316 evf_html_attributes( $container['id'], $container['class'], $container['data'], $container['attr'] )
317 );
318 }
319
320 /**
321 * Form header for displaying form title and description if enabled.
322 *
323 * @param array $form_data Form data and settings.
324 * @param bool $title Whether to display form title.
325 * @param bool $description Whether to display form description.
326 * @param array $errors List of all errors during form submission.
327 */
328 public static function header( $form_data, $title, $description, $errors ) {
329 $settings = isset( $form_data['settings'] ) ? $form_data['settings'] : array();
330
331 // Check if title and/or description is enabled.
332 if ( true === $title || true === $description ) {
333 echo '<div class="evf-title-container">';
334
335 if ( true === $title && ! empty( $settings['form_title'] ) ) {
336 echo '<div class="everest-forms--title">' . esc_html( evf_string_translation( $form_data['id'], 'form_title', $settings['form_title'] ) ) . '</div>';
337 }
338
339 if ( true === $description && ! empty( $settings['form_description'] ) ) {
340 echo '<div class="everest-forms--description">' . esc_textarea( evf_string_translation( $form_data['id'], 'form_description', $settings['form_description'] ) ) . '</div>';
341 }
342
343 echo '</div>';
344 }
345
346 // Output header errors if they exist.
347 if ( ! empty( $errors['header'] ) ) {
348 evf_add_notice( $errors['header'], 'error' );
349 }
350 }
351
352 /**
353 * Form field area.
354 *
355 * @param array $form_data Form data and settings.
356 * @param bool $title Whether to display form title.
357 * @param bool $description Whether to display form description.
358 */
359 public static function fields( $form_data, $title, $description ) {
360 $structure = isset( $form_data['structure'] ) ? $form_data['structure'] : array();
361
362 // Bail if empty form fields.
363 if ( empty( $form_data['form_fields'] ) ) {
364 return;
365 }
366
367 // Form fields area.
368 echo '<div class="evf-field-container">';
369
370 wp_nonce_field( 'everest-forms_process_submit', '_wpnonce' . $form_data['id'] );
371
372 /**
373 * Hook: everest_forms_display_fields_before.
374 *
375 * @hooked EverestForms_MultiPart::display_fields_before() Multi-Part markup open.
376 */
377 do_action( 'everest_forms_display_fields_before', $form_data );
378
379 foreach ( $structure as $row_key => $row ) {
380 /**
381 * Hook: everest_forms_display_repeater_fields.
382 *
383 * @hooked EVF_Repeater_Fields->display_repeater_fields() Display Repeater Fields.
384 */
385 $is_repeater = apply_filters( 'everest_forms_display_repeater_fields', false, $row, $form_data, true );
386
387 /**
388 * Hook: everest_forms_display_row_before.
389 */
390 do_action( 'everest_forms_display_row_before', $row_key, $form_data );
391
392 $conditions = array();
393
394 if ( ! empty( $form_data['settings']['form_rows'][ 'connection_' . $row_key ] ) && ! empty( $form_data['settings']['form_rows'][ 'connection_' . $row_key ]['conditional_logic_status'] ) ) {
395 $conditions = ! empty( $form_data['settings']['form_rows'][ 'connection_' . $row_key ] ) ? $form_data['settings']['form_rows'][ 'connection_' . $row_key ] : array();
396 }
397
398 echo '<div class="evf-frontend-row" data-row="' . esc_attr($row_key) . '"' . esc_attr($is_repeater) . ' conditional_rules="' . (isset($conditions) ? esc_attr(wp_json_encode($conditions)) : '') . '">'; // @codingStandardsIgnoreLine
399
400 foreach ( $row as $grid_key => $grid ) {
401 $number_of_grid = count( $row );
402
403 echo '<div class="evf-frontend-grid evf-grid-' . absint( $number_of_grid ) . '" data-grid="' . esc_attr( $grid_key ) . '">';
404
405 if ( ! is_array( $grid ) ) {
406 $grid = array();
407 }
408
409 foreach ( $grid as $field_key ) {
410 $field = isset( $form_data['form_fields'][ $field_key ] ) ? $form_data['form_fields'][ $field_key ] : array();
411 $field = apply_filters( 'everest_forms_field_data', $field, $form_data );
412
413 if ( empty( $field ) || evf_is_field_locked( $field['type'] ) ) {
414 continue;
415 }
416
417 $should_display_field = apply_filters( "everest_forms_should_display_field_{$field['type']}", true, $field, $form_data );
418
419 if ( true !== $should_display_field ) {
420 continue;
421 }
422
423 // Get field attributes.
424 $attributes = self::get_field_attributes( $field, $form_data );
425
426 do_action( 'everest_forms_display_before_field_wrapper', $field, $form_data );
427
428 // Get field properties.
429 $properties = self::get_field_properties( $field, $form_data, $attributes );
430
431 // Add properties to the field so it's available everywhere.
432 $field['properties'] = $properties;
433
434 do_action( 'everest_forms_display_field_before', $field, $form_data );
435
436 do_action( "everest_forms_display_field_{$field['type']}", $field, $attributes, $form_data );
437
438 do_action( 'everest_forms_display_field_after', $field, $form_data );
439
440 do_action( 'everest_forms_display_after_field_wrapper', $field, $form_data );
441 }
442
443 echo '</div>';
444 }
445
446 /**
447 * Hook: everest_forms_add_remove_buttons.
448 *
449 * @hooked EVF_Repeater_Fields->add_remove_buttons() Show Add and Remove buttons.
450 */
451 do_action( 'everest_forms_add_remove_buttons', $row, $form_data, $is_repeater );
452
453 echo '</div>';
454
455 /**
456 * Hook: everest_forms_display_row_after.
457 *
458 * @hooked EverestForms_MultiPart::display_row_after() Multi-Part markup (close previous part, open next).
459 */
460 do_action( 'everest_forms_display_row_after', $row_key, $form_data );
461 }
462
463 /**
464 * Hook: everest_forms_display_fields_after.
465 *
466 * @hooked EverestForms_MultiPart::display_fields_after() Multi-Part markup open.
467 */
468 do_action( 'everest_forms_display_fields_after', $form_data );
469
470 echo '</div>';
471 }
472
473 /**
474 * Anti-spam honeypot output if configured.
475 *
476 * @since 1.4.9
477 * @param array $form_data Form data and settings.
478 */
479 public static function honeypot( $form_data ) {
480 $names = array( 'Name', 'Phone', 'Comment', 'Message', 'Email', 'Website' );
481
482 // Output the honeypot container.
483 if ( isset( $form_data['settings']['honeypot'] ) && '1' === $form_data['settings']['honeypot'] ) {
484 echo '<div class="evf-honeypot-container evf-field-hp">';
485
486 echo '<label for="evf-' . esc_attr( $form_data['id'] ) . '-field-hp" class="evf-field-label">' . esc_attr( $names[ array_rand( $names ) ] ) . '</label>';
487
488 echo '<input type="text" name="everest_forms[hp]" id="evf-' . esc_attr( $form_data['id'] ) . '-field-hp" class="input-text">';
489
490 echo '</div>';
491 }
492 }
493
494 /**
495 * Anti-spam CleanTalk output if configured.
496 *
497 * @since 3.2.2
498 *
499 * @param [type] $form_data Form data.
500 */
501 public static function clean_talk( $form_data ) {
502
503 $is_cleantalk_activated = isset( $form_data['settings']['cleantalk'] ) ? $form_data['settings']['cleantalk'] : false;
504
505 if ( ! $is_cleantalk_activated ) {
506 return;
507 }
508
509 $detector_js_url = 'https://fd.cleantalk.org/ct-bot-detector-wrapper.js';
510 $clean_talk_inline = <<<JS
511 document.addEventListener("DOMContentLoaded", function () {
512 var loadInput = document.querySelector('input[name="everest_forms[evf_form_load_time]"]');
513 if (loadInput) {
514 loadInput.value = Math.floor(Date.now() / 1000);
515 }
516
517 var maxAttempts = 10;
518 var attempts = 0;
519 var token = false;
520 var interval = setInterval( function () {
521 var lStorage = localStorage.getItem('bot_detector_event_token');
522 if ( lStorage !== null ) {
523 try {
524 lStorage = JSON.parse( lStorage );
525 if ( lStorage.hasOwnProperty( 'value' ) && typeof lStorage.value === 'string' ) {
526 token = lStorage.value;
527 }
528 } catch ( e ) {
529 token = null;
530 }
531 }
532 if ( token ) {
533 var eventInput = document.querySelector( 'input[name="everest_forms[evf_event_token]"]' );
534 if ( eventInput ) {
535 eventInput.value = token;
536 }
537 clearInterval( interval );
538 }
539 if ( ++attempts >= maxAttempts ) {
540 clearInterval( interval );
541 }
542 }, 500);
543 });
544 JS;
545
546 // Enqueue cleanTalk scripts.
547 wp_enqueue_script(
548 'evf-clan-talk',
549 $detector_js_url,
550 array( 'jquery' ),
551 EVF_VERSION,
552 true
553 );
554
555 wp_add_inline_script( 'evf-clan-talk', $clean_talk_inline );
556
557 if ( isset( $form_data['settings']['cleantalk'] ) && '1' === $form_data['settings']['cleantalk'] ) {
558 echo '<input type="hidden" name="everest_forms[evf_event_token]" value="">';
559 echo '<input type="hidden" name="everest_forms[evf_form_load_time]" class="evf_form_load_time" value="">';
560 }
561 }
562
563 /**
564 * Google reCAPTCHA output if configured.
565 *
566 * @param array $form_data Form data and settings.
567 */
568 public static function recaptcha( $form_data ) {
569 $recaptcha_type = get_option( 'everest_forms_recaptcha_type', 'v2' );
570 $invisible_recaptcha = get_option( 'everest_forms_recaptcha_v2_invisible', 'no' );
571
572 if ( 'v2' === $recaptcha_type && 'no' === $invisible_recaptcha ) {
573 $site_key = get_option( 'everest_forms_recaptcha_v2_site_key' );
574 $secret_key = get_option( 'everest_forms_recaptcha_v2_secret_key' );
575 } elseif ( 'v2' === $recaptcha_type && 'yes' === $invisible_recaptcha ) {
576 $site_key = get_option( 'everest_forms_recaptcha_v2_invisible_site_key' );
577 $secret_key = get_option( 'everest_forms_recaptcha_v2_invisible_secret_key' );
578 } elseif ( 'v3' === $recaptcha_type ) {
579 $site_key = get_option( 'everest_forms_recaptcha_v3_site_key' );
580 $secret_key = get_option( 'everest_forms_recaptcha_v3_secret_key' );
581 } elseif ( 'hcaptcha' === $recaptcha_type ) {
582 $site_key = get_option( 'everest_forms_recaptcha_hcaptcha_site_key' );
583 $secret_key = get_option( 'everest_forms_recaptcha_hcaptcha_secret_key' );
584 } elseif ( 'turnstile' === $recaptcha_type ) {
585 $site_key = get_option( 'everest_forms_recaptcha_turnstile_site_key' );
586 $secret_key = get_option( 'everest_forms_recaptcha_turnstile_secret_key' );
587 $theme = get_option( 'everest_forms_recaptcha_turnstile_theme' );
588 $lang = get_option( 'everest_forms_recaptcha_recaptcha_language', 'en-GB' );
589 } else {
590 $site_key = '';
591 $secret_key = '';
592 }
593
594 if ( ! $site_key || ! $secret_key ) {
595 return;
596 }
597 // Check that the CAPTCHA is configured for the specific form.
598 if (
599 ! isset( $form_data['settings']['recaptcha_support'] ) ||
600 '1' !== $form_data['settings']['recaptcha_support']
601 ) {
602 return;
603 }
604 if ( evf_is_amp() ) {
605 if ( 'v3' === $recaptcha_type ) {
606 printf(
607 '<amp-recaptcha-input name="everest_forms[recaptcha]" data-sitekey="%s" data-action="%s" layout="nodisplay"></amp-recaptcha-input>',
608 esc_attr( $site_key ),
609 esc_attr( 'evf_' . $form_data['id'] )
610 );
611 }
612 return; // Only v3 is supported in AMP.
613 }
614
615 if ( isset( $form_data['settings']['recaptcha_support'] ) && '1' === $form_data['settings']['recaptcha_support'] ) {
616 $form_id = isset( $form_data['id'] ) ? absint( $form_data['id'] ) : 0;
617 $visible = ! empty( self::$parts[ $form_id ] ) ? 'style="display:none;"' : '';
618 $data = apply_filters(
619 'everest_forms_frontend_recaptcha',
620 array(
621 'sitekey' => trim( sanitize_text_field( $site_key ) ),
622 ),
623 $form_data
624 );
625
626 // Load reCAPTCHA support if form supports it.
627 if ( $site_key && $secret_key ) {
628 if ( 'v2' === $recaptcha_type ) {
629 $recaptcha_api = apply_filters( 'everest_forms_frontend_recaptcha_url', 'https://www.google.com/recaptcha/api.js?onload=EVFRecaptchaLoad&render=explicit', $recaptcha_type, $form_id );
630
631 if ( 'yes' === $invisible_recaptcha ) {
632 $data['size'] = 'invisible';
633 $recaptcha_inline = 'var EVFRecaptchaLoad = function(){jQuery(".g-recaptcha").each(function(index, el){var recaptchaID = grecaptcha.render(el,{callback:function(){EVFRecaptchaCallback(el);}},true); el.closest("form").querySelector("button[type=submit]").recaptchaID = recaptchaID;});};
634 var EVFRecaptchaCallback = function (el) {
635 var $form = el.closest("form");
636 if( typeof jQuery !== "undefined" ){
637 if( "1" === jQuery( $form ).attr( "data-ajax_submission" ) ) {
638 el.closest( "form" ).querySelector( "button[type=submit]" ).recaptchaID = "verified";
639 jQuery( $form ).find( ".evf-submit" ).trigger( "click" );
640 } else {
641 $form.submit();
642 }
643 grecaptcha.reset();
644 }
645 };
646 ';
647 } else {
648 $recaptcha_inline = 'var EVFRecaptchaLoad = function(){jQuery(".g-recaptcha").each(function(index, el){var recaptchaID = grecaptcha.render(el,{callback:function(){EVFRecaptchaCallback(el);}},true);jQuery(el).attr( "data-recaptcha-id", recaptchaID);});};';
649 $recaptcha_inline .= 'var EVFRecaptchaCallback = function(el){jQuery(el).parent().find(".evf-recaptcha-hidden").val("1").trigger("change").valid();};';
650 }
651 } elseif ( 'v3' === $recaptcha_type ) {
652 $recaptcha_api = apply_filters( 'everest_forms_frontend_recaptcha_url', 'https://www.google.com/recaptcha/api.js?render=' . $site_key, $recaptcha_type, $form_id );
653 $recaptcha_inline = 'var EVFRecaptchaLoad = function(){grecaptcha.execute("' . esc_html( $site_key ) . '",{action:"everest_form"}).then(function(token){var f=document.getElementsByName("everest_forms[recaptcha]");for(var i=0;i<f.length;i++){f[i].value = token;}});};grecaptcha.ready(EVFRecaptchaLoad);setInterval(EVFRecaptchaLoad, 110000);';
654 $recaptcha_inline .= 'grecaptcha.ready(function(){grecaptcha.execute("' . esc_html( $site_key ) . '",{action:"everest_form"}).then(function(token){var f=document.getElementsByName("everest_forms[recaptcha]");for(var i=0;i<f.length;i++){f[i].value = token;}});});';
655 } elseif ( 'hcaptcha' === $recaptcha_type ) {
656 $recaptcha_api = apply_filters( 'everest_forms_frontend_recaptcha_url', 'https://hcaptcha.com/1/api.js??onload=EVFRecaptchaLoad&render=explicit', $recaptcha_type, $form_id );
657 $recaptcha_inline = 'var EVFRecaptchaLoad = function(){jQuery(".g-recaptcha").each(function(index, el){var recaptchaID = hcaptcha.render(el,{callback:function(){EVFRecaptchaCallback(el);}},true);jQuery(el).attr( "data-recaptcha-id", recaptchaID);});};';
658 $recaptcha_inline .= 'var EVFRecaptchaCallback = function(el){jQuery(el).parent().find(".evf-recaptcha-hidden").val("1").trigger("change").valid();};';
659 } elseif ( 'turnstile' === $recaptcha_type ) {
660 $recaptcha_api = apply_filters( 'everest_forms_frontend_recaptcha_url', 'https://challenges.cloudflare.com/turnstile/v0/api.js?onload=EVFTurnstileLoad&render=explicit', $recaptcha_type, $form_id );
661 $recaptcha_inline = 'var EVFTurnstileLoad = function(){jQuery(".g-recaptcha").each(function(index, el){var recaptchaID = turnstile.render(el,{theme:"' . $theme . '",language:"' . $lang . '",callback:function(){EVFRecaptchaCallback(el);}},true);jQuery(el).attr( "data-recaptcha-id", recaptchaID);});};';
662 $recaptcha_inline .= 'var EVFRecaptchaCallback = function(el){jQuery(el).parent().find(".evf-recaptcha-hidden").val("1").trigger("change").valid();};';
663 }
664
665 // Enqueue reCaptcha scripts.
666 wp_enqueue_script(
667 'evf-recaptcha',
668 $recaptcha_api,
669 'v3' === $recaptcha_type ? array() : array( 'jquery' ),
670 'v3' === $recaptcha_type ? '3.0.0' : '2.0.0',
671 true
672 );
673
674 // Load reCaptcha callback once.
675 static $count = 1;
676 if ( 1 === $count ) {
677 wp_add_inline_script( 'evf-recaptcha', $recaptcha_inline );
678 $count++;
679 }
680
681 // Output the reCAPTCHA container.
682 $class = ( 'v3' === $recaptcha_type || ( 'v2' === $recaptcha_type && 'yes' === $invisible_recaptcha ) ) ? 'recaptcha-hidden' : '';
683 echo '<div class="evf-recaptcha-container ' . esc_attr( $class ) . '" style="display:' . ( ! empty( self::$parts[ $form_id ] ) ? 'none' : 'block' ) . '">';
684
685 if ( 'v2' === $recaptcha_type || 'hcaptcha' === $recaptcha_type || 'turnstile' === $recaptcha_type ) {
686 echo '<div ' . evf_html_attributes( '', array( 'g-recaptcha' ), $data ) . '></div>';
687
688 if ( 'hcaptcha' === $recaptcha_type && 'no' === $invisible_recaptcha || 'turnstile' === $recaptcha_type ) {
689 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>';
690 }
691 } else {
692 echo '<input type="hidden" name="everest_forms[recaptcha]" value="">';
693 }
694
695 echo '</div>';
696 }
697 }
698 }
699
700 /**
701 * Get field attributes.
702 *
703 * @param array $field Field.
704 * @param array $form_data Form data.
705 *
706 * @return array
707 */
708 private static function get_field_attributes( $field, $form_data ) {
709 $form_id = absint( $form_data['id'] );
710 $field_id = esc_attr( $field['id'] );
711 $attributes = array(
712 'field_class' => array( 'evf-field', 'evf-field-' . sanitize_html_class( $field['type'] ), 'form-row' ),
713 'field_id' => array( sprintf( 'evf-%d-field_%s-container', $form_id, $field_id ) ),
714 'field_style' => '',
715 'label_class' => array( 'evf-field-label' ),
716 'label_id' => '',
717 'description_class' => array( 'evf-field-description' ),
718 'description_id' => array(),
719 'input_id' => array( sprintf( 'evf-%d-field_%s', $form_id, $field_id ) ),
720 'input_class' => array(),
721 'input_data' => array(),
722 );
723
724 // Check user field defined classes.
725 if ( ! empty( $field['css'] ) ) {
726 $attributes['field_class'] = array_merge( $attributes['field_class'], evf_sanitize_classes( $field['css'], true ) );
727 }
728
729 // Check for input column layouts.
730 if ( ! empty( $field['input_columns'] ) ) {
731 if ( 'inline' === $field['input_columns'] ) {
732 $attributes['field_class'][] = 'everest-forms-list-inline';
733 } elseif ( '' !== $field['input_columns'] ) {
734 $attributes['field_class'][] = 'everest-forms-list-' . $field['input_columns'] . '-columns';
735 }
736 }
737
738 // Input class.
739 if ( ! in_array( $field['type'], array( 'checkbox', 'radio', 'payment-checkbox', 'payment-multiple' ), true ) ) {
740 $attributes['input_class'][] = 'input-text';
741 }
742
743 // Check label visibility.
744 if ( ! empty( $field['label_hide'] ) ) {
745 $attributes['label_class'][] = 'evf-label-hide';
746 }
747
748 // Check size.
749 if ( ! empty( $field['size'] ) ) {
750 $attributes['input_class'][] = 'evf-field-' . sanitize_html_class( $field['size'] );
751 }
752
753 // Check if required.
754 if ( ! empty( $field['required'] ) ) {
755 $attributes['field_class'][] = 'validate-required';
756 }
757
758 // Check if extra validation required.
759 if ( in_array( $field['type'], array( 'email', 'phone' ), true ) ) {
760 $attributes['field_class'][] = 'validate-' . esc_attr( $field['type'] );
761 }
762
763 // Check if there are errors.
764 if ( isset( evf()->task->errors[ $form_id ][ $field_id ] ) ) {
765 $attributes['input_class'][] = 'evf-error';
766 $attributes['field_class'][] = 'everest-forms-invalid';
767 }
768
769 // This filter is deprecated, filter the properties (below) instead.
770 $attributes = apply_filters( 'evf_field_atts', $attributes, $field, $form_data );
771
772 return $attributes;
773 }
774
775 /**
776 * Return base properties for a specific field.
777 *
778 * @param array $field Field data and settings.
779 * @param array $form_data Form data and settings.
780 * @param array $attributes List of field attributes.
781 *
782 * @return array
783 */
784 public static function get_field_properties( $field, $form_data, $attributes = array() ) {
785 if ( empty( $attributes ) ) {
786 $attributes = self::get_field_attributes( $field, $form_data );
787 }
788
789 // This filter is for backwards compatibility purposes.
790 $types = array( 'text', 'textarea', 'number', 'email', 'hidden', 'url', 'html', 'title', 'password', 'phone', 'address', 'checkbox', 'radio', 'select' );
791 if ( in_array( $field['type'], $types, true ) ) {
792 $field = apply_filters( "everest_forms_{$field['type']}_field_display", $field, $attributes, $form_data );
793 }
794
795 $form_id = absint( $form_data['id'] );
796 $field_id = sanitize_text_field( $field['id'] );
797
798 // Field container data.
799 $container_data = array();
800
801 // Embed required-field-message to the container if the field is required.
802 if ( isset( $field['required'] ) && ( '1' === $field['required'] || true === $field['required'] ) ) {
803 $has_sub_fields = false;
804 $sub_field_messages = array();
805 $required_validation = get_option( 'everest_forms_required_validation' );
806 if ( in_array( $field['type'], array( 'number', 'email', 'url', 'phone' ), true ) ) {
807 $required_validation = get_option( 'everest_forms_' . $field['type'] . '_validation' );
808 }
809
810 if ( 'likert' === $field['type'] ) {
811 $has_sub_fields = true;
812 $likert_rows = isset( $field['likert_rows'] ) ? $field['likert_rows'] : array();
813 $row_keys = array();
814 foreach ( $likert_rows as $row_key => $row_label ) {
815 $row_keys[] = $row_key;
816 $row_slug = 'required-field-message-' . $row_key;
817
818 $error_message = isset( $field[ $row_slug ] ) ? evf_string_translation( $form_data['id'], $field['id'], $field[ $row_slug ], '-' . $row_slug ) : $required_validation;
819 $sub_field_messages[ $row_key ] = htmlspecialchars( wp_kses( html_entity_decode( $error_message ), array() ) );
820 }
821 $container_data['row-keys'] = wp_json_encode( $row_keys );
822 } elseif ( 'address' === $field['type'] ) {
823 $has_sub_fields = true;
824 $sub_field_messages = array(
825 'address1' => isset( $field['required_field_message_setting'] ) && 'global' === $field['required_field_message_setting'] ? $required_validation : evf_string_translation( $form_data['id'], $field['id'], $field['required-field-message-address1'], '-required-field-message-address1' ),
826 'city' => isset( $field['required_field_message_setting'] ) && 'global' === $field['required_field_message_setting'] ? $required_validation : evf_string_translation( $form_data['id'], $field['id'], $field['required-field-message-city'], '-required-field-message-city' ),
827 'state' => isset( $field['required_field_message_setting'] ) && 'global' === $field['required_field_message_setting'] ? $required_validation : evf_string_translation( $form_data['id'], $field['id'], $field['required-field-message-state'], '-required-field-message-state' ),
828 'postal' => isset( $field['required_field_message_setting'] ) && 'global' === $field['required_field_message_setting'] ? $required_validation : evf_string_translation( $form_data['id'], $field['id'], $field['required-field-message-postal'], '-required-field-message-postal' ),
829 'country' => isset( $field['required_field_message_setting'] ) && 'global' === $field['required_field_message_setting'] ? $required_validation : evf_string_translation( $form_data['id'], $field['id'], $field['required-field-message-country'], '-required-field-message-country' ),
830 );
831 }
832
833 if ( true === $has_sub_fields ) {
834 foreach ( $sub_field_messages as $sub_field_type => $error_message ) {
835 $container_data[ 'required-field-message-' . $sub_field_type ] = htmlspecialchars( wp_kses( html_entity_decode( $error_message ), array() ) );
836 }
837 } else {
838 if ( isset( $field['required_field_message_setting'] ) && 'global' === $field['required_field_message_setting'] ) {
839 $container_data['required-field-message'] = htmlspecialchars( wp_kses( html_entity_decode( $required_validation ), array() ) );
840 } elseif ( isset( $field['required-field-message'] ) && '' !== $field['required-field-message'] ) {
841 $required_data = evf_string_translation( $form_data['id'], $field['id'], $field['required-field-message'], '-required-field-message' );
842 $container_data['required-field-message'] = htmlspecialchars( wp_kses( html_entity_decode( $required_data ), array() ) );
843 } else {
844 $container_data['required-field-message'] = htmlspecialchars( wp_kses( html_entity_decode( $required_validation ), array() ) );
845 }
846 }
847 }
848 $errors = isset( evf()->task->errors[ $form_id ][ $field_id ] ) ? evf()->task->errors[ $form_id ][ $field_id ] : '';
849 $defaults = isset($_POST['everest_forms']['form_fields'][$field_id]) && (! is_array($_POST['everest_forms']['form_fields'][$field_id]) && ! empty($_POST['everest_forms']['form_fields'][$field_id])) ? $_POST['everest_forms']['form_fields'][$field_id] : ''; // @codingStandardsIgnoreLine
850
851 /**
852 * Count the number of smart tags in the default value which contain form fields smart tag.
853 *
854 * @since 3.2.3
855 */
856 $count = 0;
857 $default_value = '';
858
859 if ( isset( $field['default_value'] ) ) {
860 preg_match_all( '/\{field_id="(.+?)"\}/', $field['default_value'], $ids );
861 if ( ! empty( $ids[1] ) ) {
862 $count++;
863 }
864 }
865
866 if ( $count > 0 ) {
867 $is_hidden = isset( $field['hidden_field_visibility'] ) ? evf_string_to_bool( $field['hidden_field_visibility'] ) : ( isset( $field['type'] ) && 'hidden' === $field['type'] ? true : false );
868
869 if ( $is_hidden ) {
870 $default_value = isset( $field['default_value'] ) ? apply_filters( 'everest_forms_process_smart_tags', $field['default_value'], $form_data ) : $defaults;
871 } else {
872 $default_value = isset( $field['default_value'] ) ? '' : $defaults;
873 }
874 } else {
875 $default_value = isset( $field['default_value'] ) ? apply_filters( 'everest_forms_process_smart_tags', $field['default_value'], $form_data ) : $defaults;
876 }
877
878 $properties = apply_filters(
879 'everest_forms_field_properties_' . $field['type'],
880 array(
881 'container' => array(
882 'attr' => array(
883 'style' => $attributes['field_style'],
884 ),
885 'class' => $attributes['field_class'],
886 'data' => $container_data,
887 'id' => implode( '', array_slice( $attributes['field_id'], 0 ) ),
888 ),
889 'label' => array(
890 'attr' => array(
891 'for' => sprintf( 'evf-%d-field_%s', $form_id, $field_id ),
892 ),
893 'class' => $attributes['label_class'],
894 'data' => array(),
895 'disabled' => ! empty( $field['label_disable'] ) ? true : false,
896 'hidden' => ! empty( $field['label_hide'] ) ? true : false,
897 'id' => $attributes['label_id'],
898 'required' => ! empty( $field['required'] ) ? true : false,
899 'value' => ! empty( $field['label'] ) ? $field['label'] : '',
900 ),
901 'inputs' => array(
902 'primary' => array(
903 'attr' => array(
904 'name' => "everest_forms[form_fields][{$field_id}]",
905 'value' => $default_value,
906 'placeholder' => isset( $field['placeholder'] ) ? evf_string_translation( $form_data['id'], $field['id'], $field['placeholder'], '-placeholder' ) : '',
907 ),
908 'class' => $attributes['input_class'],
909 'data' => $attributes['input_data'],
910 'id' => implode( array_slice( $attributes['input_id'], 0 ) ),
911 'required' => ! empty( $field['required'] ) ? 'required' : '',
912 ),
913 ),
914 'error' => array(
915 'attr' => array(
916 'for' => sprintf( 'evf-%d-field_%s', $form_id, $field_id ),
917 ),
918 'class' => array( 'evf-error' ),
919 'data' => array(),
920 'id' => '',
921 'value' => ! empty( $errors ) ? $errors : '',
922 ),
923 'description' => array(
924 'attr' => array(),
925 'class' => $attributes['description_class'],
926 'data' => array(),
927 'id' => implode( '', array_slice( $attributes['description_id'], 0 ) ),
928 'position' => 'after',
929 'value' => ! empty( $field['description'] ) ? $field['description'] : '',
930 ),
931 ),
932 $field,
933 $form_data
934 );
935
936 return apply_filters( 'everest_forms_field_properties', $properties, $field, $form_data );
937 }
938
939 /**
940 * Output the shortcode.
941 *
942 * @param array $atts Attributes.
943 */
944 public static function output( $atts ) {
945 wp_enqueue_script( 'everest-forms' );
946
947 $form_id = isset( $atts['id'] ) ? absint( $atts['id'] ) : 0;
948 $form_fields = evf_get_form_fields( $form_id );
949 $form_data = EVF()->form->get( $form_id, array( 'content_only' => true ) );
950 $form_fields = isset( $form_data['form_fields'] ) ? $form_data['form_fields'] : array();
951
952 foreach ( $form_fields as $form_field ) {
953 if (
954 ( isset( $form_field['type'] ) && in_array( $form_field['type'], array( 'rating', 'likert', 'yes-no', 'scale-rating' ), true ) ) ||
955 ( isset( $form_field['survey_status'] ) && absint( $form_field['survey_status'] ) === 1 ) ||
956 ( isset( $form_field['quiz_status'] ) && absint( $form_field['quiz_status'] ) === 1 )
957 ) {
958 wp_enqueue_script( 'everest-forms-survey-polls-quiz-script' );
959 }
960 }
961
962 // Load jQuery flatpickr libraries. https://github.com/flatpickr/flatpickr.
963 if ( isset( $atts['id'] ) && evf_is_field_exists( $atts['id'], 'date-time' ) ) {
964 wp_enqueue_style( 'flatpickr' );
965 wp_enqueue_script( 'flatpickr' );
966 }
967
968 // Load jQuery mailcheck library - https://github.com/mailcheck/mailcheck.
969 if ( isset( $atts['id'] ) && evf_is_field_exists( $atts['id'], 'email' ) && (bool) apply_filters( 'everest_forms_mailcheck_enabled', true ) ) {
970 wp_enqueue_script( 'mailcheck' );
971 }
972
973 // Add custom CSS/JS
974 if ( isset( $atts['id'] ) ) {
975 self::add_custom_css_js( $atts['id'] );
976 }
977
978 $atts = shortcode_atts(
979 array(
980 'id' => false,
981 'type' => false,
982 'size' => false,
983 'text' => false,
984 'title' => false,
985 'description' => false,
986 'header_title' => false,
987 'footer_title' => false,
988 'header_desc' => false,
989 'footer_desc' => false,
990 ),
991 $atts,
992 'output'
993 );
994
995 // Scripts load action.
996 do_action( 'everest_forms_shortcode_scripts', $atts );
997
998 ob_start();
999 self::view( $atts );
1000 echo ob_get_clean(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1001 }
1002
1003 /**
1004 * Form view.
1005 *
1006 * @param array $atts Attributes.
1007 */
1008 private static function view( $atts ) {
1009 $id = isset( $atts['id'] ) ? $atts['id'] : false;
1010 $title = isset( $atts['title'] ) ? $atts['title'] : false;
1011 $description = isset( $atts['description'] ) ? $atts['description'] : false;
1012 $popup_type = isset( $atts['type'] ) ? $atts['type'] : false;
1013 $popup_text = isset( $atts['text'] ) ? $atts['text'] : false;
1014 if ( empty( $id ) ) {
1015 return;
1016 }
1017
1018 // Grab the form data, if not found then we bail.
1019 $form = evf()->form->get( (int) $id );
1020
1021 if ( empty( $form ) ) {
1022 return;
1023 }
1024
1025 if ( 'publish' !== $form->post_status && 'inactive' !== $form->post_status ) {
1026 return;
1027 }
1028
1029 // Basic form information.
1030 $form_data = apply_filters( 'everest_forms_frontend_form_data', evf_decode( $form->post_content ) );
1031 // For form confirmation backward compatilibity.
1032 $form_data = evf_form_confirmation_backward_compatibility( $form_data );
1033
1034 $form_id = absint( $form->ID );
1035 $settings = isset( $form_data['settings'] ) ? $form_data['settings'] : array();
1036 $action = esc_url_raw( remove_query_arg( 'evf-forms' ) );
1037 $title = filter_var( $title, FILTER_VALIDATE_BOOLEAN );
1038 $description = filter_var( $description, FILTER_VALIDATE_BOOLEAN );
1039 $errors = isset( evf()->task->errors[ $form_id ] ) ? evf()->task->errors[ $form_id ] : array();
1040 $form_enabled = isset( $form_data['form_enabled'] ) ? absint( $form_data['form_enabled'] ) : 1;
1041 $kff_enabled = isset( $settings['keyboard_friendly_form'] ) ? absint( $settings['keyboard_friendly_form'] ) : 0;
1042 $disable_message = isset( $form_data['settings']['form_disable_message'] ) ? evf_string_translation( $form_data['id'], 'form_disable_message', $form_data['settings']['form_disable_message'] ) : __( 'This form is disabled.', 'everest-forms' );
1043 $stripe_via_selector = function_exists( 'evf_is_gateway_in_selector_allowlist' ) && evf_is_gateway_in_selector_allowlist( array( 'form_data' => $form_data, 'gateway' => 'stripe' ) );
1044 $square_via_selector = function_exists( 'evf_is_gateway_in_selector_allowlist' ) && evf_is_gateway_in_selector_allowlist( array( 'form_data' => $form_data, 'gateway' => 'square' ) );
1045 $paypal_via_selector = function_exists( 'evf_is_gateway_in_selector_allowlist' ) && evf_is_gateway_in_selector_allowlist( array( 'form_data' => $form_data, 'gateway' => 'paypal' ) );
1046 if ( ( isset( $form_data['payments']['stripe']['enable_stripe'] ) && '1' === $form_data['payments']['stripe']['enable_stripe'] ) || $stripe_via_selector || ( isset( $form_data['payments']['square']['enable_square'] ) && '1' === $form_data['payments']['square']['enable_square'] ) || $square_via_selector || $paypal_via_selector ) {
1047 $ajax_form_submission = 1;
1048 } else {
1049 $ajax_form_submission = isset( $settings['ajax_form_submission'] ) ? $settings['ajax_form_submission'] : 0;
1050 }
1051
1052 if ( 0 !== evf_string_to_bool( $ajax_form_submission ) ) {
1053 wp_enqueue_script( 'everest-forms-ajax-submission' );
1054 }
1055
1056 // If the form is disabled or does not contain any fields do not proceed.
1057 if ( empty( $form_data['form_fields'] ) ) {
1058 echo '<!-- Everest Forms: no fields, form hidden -->';
1059 return;
1060 } elseif ( 1 !== $form_enabled ) {
1061 if ( ! empty( $disable_message ) ) {
1062 printf( '<p class="everst-forms-form-disable-notice everest-forms-notice everest-forms-notice--info">%s</p>', esc_textarea( $disable_message ) );
1063 }
1064 return;
1065 }
1066
1067 // We need to stop output processing in case we are on AMP page.
1068 if ( evf_is_amp( false ) && ( ! current_theme_supports( 'amp' ) || apply_filters( 'evfforms_amp_pro', class_exists( 'EverestForms_Pro' ) ) || ! is_ssl() || ! defined( 'AMP__VERSION' ) || version_compare( AMP__VERSION, '1.2', '<' ) ) ) {
1069
1070 $full_page_url = home_url( add_query_arg( 'nonamp', '1' ) . '#evfforms-' . absint( $form->ID ) );
1071
1072 /**
1073 * Allow modifying the text or url for the full page on the AMP pages.
1074 *
1075 * @since 1.4.1.1
1076 * @since 1.7.1 Added $form_id, $full_page_url, and $form_data arguments.
1077 *
1078 * @param int $form_id Form id.
1079 * @param array $form_data Form data and settings.
1080 *
1081 * @return string
1082 */
1083 $text = (string) apply_filters(
1084 'evf_frontend_shortcode_amp_text',
1085 sprintf( /* translators: %s - URL to a non-amp version of a page with the form. */
1086 __( '<a href="%s">Go to the full page</a> to view and submit the form.', 'everest-forms' ),
1087 esc_url( $full_page_url )
1088 ),
1089 $form_id,
1090 $full_page_url,
1091 $form_data
1092 );
1093
1094 printf(
1095 '<p class="evf-shortcode-amp-text">%s</p>',
1096 wp_kses_post( $text )
1097 );
1098
1099 return;
1100 }
1101
1102 $message = isset( $form_data['settings']['successful_form_submission_message'] ) ? $form_data['settings']['successful_form_submission_message'] : esc_html__( 'Thanks for contacting us! We will be in touch with you shortly.', 'everest-forms' );
1103
1104 // Before output hook.
1105 do_action( 'everest_forms_frontend_output_before', $form_data, $form );
1106
1107 // Check for return hash.
1108 if (
1109 ! empty( $_GET['everest_forms_return'] ) // phpcs:ignore WordPress.Security.NonceVerification
1110 && evf()->task->is_valid_hash
1111 && absint( evf()->task->form_data['id'] ) === $form_id
1112 ) {
1113 $query_args = base64_decode($_GET['everest_forms_return']); // phpcs:ignore
1114 parse_str( $query_args, $query_arg );
1115 $message = isset( $form_data['settings']['successful_form_submission_message'] ) ? $form_data['settings']['successful_form_submission_message'] : esc_html__( 'Thanks for contacting us! We will be in touch with you shortly.', 'everest-forms' );
1116 $pdf_submission = isset( $form_data['settings']['pdf_submission']['enable_pdf_submission'] ) && 0 !== $form_data['settings']['pdf_submission']['enable_pdf_submission'] ? $form_data['settings']['pdf_submission'] : '';
1117 if ( defined( 'EVF_PDF_SUBMISSION_VERSION' ) && ( 'yes' === get_option( 'everest_forms_pdf_download_after_submit', 'no' ) || ( isset( $pdf_submission['everest_forms_pdf_download_after_submit'] ) && 'yes' === $pdf_submission['everest_forms_pdf_download_after_submit'] ) ) ) {
1118 global $__everest_form_id;
1119 global $__everest_form_entry_id;
1120 $__everest_form_id = $form_id;
1121 $__everest_form_entry_id = isset( $query_arg['entry_id'] ) ? $query_arg['entry_id'] : 0;
1122 }
1123
1124 if ( 'same' === $form_data['settings']['redirect_to'] ) {
1125 evf_add_notice( $message, 'success' );
1126 }
1127
1128 do_action( 'everest_forms_frontend_output_success', evf()->task->form_data, evf()->task->form_fields, evf()->task->entry_id );
1129 return;
1130 }
1131
1132 // Check the form state type
1133 $form_state_type = isset( $form_data['settings']['form_state_type'] ) ? $form_data['settings']['form_state_type'] : 'hide';
1134
1135 if ( 'hide' === $form_state_type ) {
1136 $message_display_location = isset( $form_data['settings']['message_display_location_of_hide'] ) ? $form_data['settings']['message_display_location_of_hide'] : 'hide';
1137 } else {
1138 $message_display_location = isset( $form_data['settings']['message_display_location_of_reset'] ) ? $form_data['settings']['message_display_location_of_reset'] : 'top';
1139 }
1140 // If conditional logic match then getting messag and position.
1141 if ( ! empty( $_REQUEST['evf_popup_message'] ) ) {
1142 $message = sanitize_text_field( $_REQUEST['evf_popup_message'] );
1143 }
1144 if ( ! empty( $_REQUEST['evf_message_display_location'] ) ) {
1145 $message_display_location = sanitize_text_field( $_REQUEST['evf_message_display_location'] );
1146 }
1147
1148 $form_state_type = '';
1149 if ( ! empty( $_REQUEST['evf_form_state_type'] ) ) {
1150 $form_state_type = sanitize_text_field( $_REQUEST['evf_form_state_type'] );
1151 }
1152
1153 $success = apply_filters( 'everest_forms_success', false, $form_id );
1154 if ( $success && ! empty( $form_data ) && 'hide' === $message_display_location ) {
1155 do_action( 'everest_forms_frontend_output_success', $form_data );
1156 return;
1157 }
1158
1159 // Allow filter to return early if some condition is not meet.
1160 if ( ! apply_filters( 'everest_forms_frontend_load', true, $form_data ) ) {
1161 do_action( 'everest_forms_frontend_not_loaded', $form_data, $form );
1162 return;
1163 }
1164
1165 /**
1166 * BW compatiable for multi-parts form.
1167 *
1168 * @todo Remove in Major EVF version 1.6.0
1169 */
1170 if ( defined( 'EVF_MULTI_PART_PLUGIN_FILE' ) ) {
1171 include_once ABSPATH . 'wp-admin/includes/plugin.php';
1172 $plugin_data = get_plugin_data( EVF_MULTI_PART_PLUGIN_FILE, false, false );
1173
1174 if ( version_compare( $plugin_data['Version'], '1.3.0', '<' ) ) {
1175 $settings_defaults = array(
1176 'indicator' => 'progress',
1177 'indicator_color' => '#7e3bd0',
1178 'nav_align' => 'center',
1179 );
1180
1181 if ( isset( $form_data['settings']['enable_multi_part'] ) && evf_string_to_bool( $form_data['settings']['enable_multi_part'] ) ) {
1182 $settings = isset( $form_data['settings']['multi_part'] ) ? $form_data['settings']['multi_part'] : array();
1183
1184 if ( ! empty( $form_data['multi_part'] ) ) {
1185 self::$parts = array(
1186 'total' => count( $form_data['multi_part'] ),
1187 'current' => 1,
1188 'parts' => array_values( $form_data['multi_part'] ),
1189 'settings' => wp_parse_args( $settings, $settings_defaults ),
1190 );
1191 }
1192 } else {
1193 self::$parts = array(
1194 'total' => '',
1195 'current' => '',
1196 'parts' => array(),
1197 'settings' => $settings_defaults,
1198 );
1199 }
1200 }
1201 }
1202
1203 // Allow Multi-Part to be customized.
1204 $parts = ! empty( self::$parts[ $form_id ] ) ? self::$parts[ $form_id ] : array();
1205 self::$parts[ $form_id ] = apply_filters( 'everest_forms_parts_data', $parts, $form_data, $form_id );
1206
1207 // Allow final action to be customized.
1208 $action = apply_filters( 'everest_forms_frontend_form_action', $action, $form_data );
1209
1210 // Allow form container classes to be filtered and user defined classes.
1211 $classes = apply_filters( 'everest_forms_frontend_container_class', array(), $form_data );
1212 if ( ! empty( $settings['form_class'] ) ) {
1213 $classes = array_merge( $classes, explode( ' ', $settings['form_class'] ) );
1214 }
1215 if ( ! empty( $settings['layout_class'] ) ) {
1216 $classes = array_merge( $classes, explode( ' ', $settings['layout_class'] ) );
1217 }
1218 $classes = evf_sanitize_classes( $classes, true );
1219
1220 $form_atts = array(
1221 'id' => sprintf( 'evf-form-%d', absint( $form_id ) ),
1222 'class' => array( 'everest-form' ),
1223 'data' => array(
1224 'formid' => absint( $form_id ),
1225 'ajax_submission' => $ajax_form_submission,
1226 'keyboard_friendly_form' => $kff_enabled,
1227 ),
1228 'atts' => array(
1229 'method' => 'post',
1230 'enctype' => 'multipart/form-data',
1231 'action' => esc_url( $action ),
1232 ),
1233 );
1234
1235 if ( evf_is_amp() ) {
1236
1237 // Set submitting state.
1238 if ( ! isset( $form_atts['atts']['on'] ) ) {
1239 $form_atts['atts']['on'] = '';
1240 } else {
1241 $form_atts['atts']['on'] .= ';';
1242 }
1243 $form_atts['atts']['on'] .= sprintf(
1244 'submit:AMP.setState( %1$s ); submit-success:AMP.setState( %2$s ); submit-error:AMP.setState( %2$s );',
1245 wp_json_encode(
1246 array(
1247 self::get_form_amp_state_id( $form_id ) => array(
1248 'submitting' => true,
1249 ),
1250 )
1251 ),
1252 wp_json_encode(
1253 array(
1254 self::get_form_amp_state_id( $form_id ) => array(
1255 'submitting' => false,
1256 ),
1257 )
1258 )
1259 );
1260
1261 // Upgrade the form to be an amp-form to avoid sanitizer conversion.
1262 if ( isset( $form_atts['atts']['action'] ) ) {
1263 $form_atts['atts']['action-xhr'] = $form_atts['atts']['action'];
1264 unset( $form_atts['atts']['action'] );
1265
1266 $form_atts['atts']['verify-xhr'] = $form_atts['atts']['action-xhr'];
1267 }
1268 }
1269
1270 $form_atts = apply_filters( 'everest_forms_frontend_form_atts', $form_atts, $form_data );
1271 // Begin to build the output.
1272 do_action( 'everest_forms_frontend_output_container_before', $form_data, $form );
1273
1274 printf( '<div class="evf-container %s" id="evf-%d">', esc_attr( $classes ), absint( $form_id ) );
1275
1276 do_action( 'everest_forms_frontend_output_form_before', $form_data, $form, $errors );
1277 if ( isset( $atts['type'] ) && 'popup-button' === $popup_type ) {
1278 printf( "<button class='everest-forms-modal-link everest-forms-modal-link-%s'>%s</button>", esc_attr( $atts['id'] ), esc_html( $popup_text ) );
1279 do_action( 'everest_form_popup', $atts );
1280 } elseif ( isset( $atts['type'] ) && 'popup-link' === $popup_type ) {
1281 printf( "<a href='javascript:void(0);' class='everest-forms-modal-link everest-forms-modal-link-%s'>%s</a>", esc_attr( $atts['id'] ), esc_html( $popup_text ) );
1282 do_action( 'everest_form_popup', $atts );
1283 } elseif ( isset( $atts['type'] ) && 'popup' === $popup_type ) {
1284 do_action( 'everest_form_popup', $atts );
1285 } else {
1286 if ( $success && ! empty( $form_data ) && 'top' === $message_display_location ) {
1287 evf_add_notice( $message, 'success' );
1288 do_action( 'everest_forms_frontend_output_success', $form_data );
1289 } elseif ( $success && ! empty( $form_data ) && 'popup' === $message_display_location ) {
1290 $form_atts['data']['message_location'] = $message_display_location;
1291 $form_atts['data']['message'] = esc_html( $message );
1292 }
1293 // Adding the form state type. hide or reset
1294 $form_atts['data']['form_state_type'] = $form_state_type;
1295
1296 echo '<form ' . evf_html_attributes( $form_atts['id'], $form_atts['class'], $form_atts['data'], $form_atts['atts'] ) . '>';
1297 if ( evf_is_amp() ) {
1298 $state = array(
1299 'submitting' => false,
1300 );
1301 printf(
1302 '<amp-state id="%s"><script type="application/json">%s</script></amp-state>',
1303 self::get_form_amp_state_id( $form_id ), // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1304 wp_json_encode( $state )
1305 );
1306 }
1307 do_action( 'everest_forms_frontend_output', $form_data, $title, $description, $errors );
1308
1309 echo '</form>';
1310
1311 if ( $success && ! empty( $form_data ) && 'bottom' === $message_display_location ) {
1312 do_action( 'everest_forms_frontend_output_success', $form_data );
1313 evf_add_notice( $message, 'success' );
1314 do_action( 'everest_forms_frontend_output_success', $form_data );
1315 }
1316 }
1317
1318 do_action( 'everest_forms_frontend_output_form_after', $form_data, $form );
1319
1320 echo '</div><!-- .evf-container -->';
1321
1322 // After output hook.
1323 do_action( 'everest_forms_frontend_output_after', $form_data, $form );
1324
1325 // Debug information.
1326 if ( is_super_admin() ) {
1327 evf_debug_data( $form_data );
1328 }
1329 }
1330
1331 /**
1332 * ReCaptcha Langauge.
1333 *
1334 * @param url $url Recaptcha URL.
1335 *
1336 * @return $url
1337 */
1338 public static function evf_recaptcha_language( $url ) {
1339 return esc_url_raw( add_query_arg( array( 'hl' => get_option( 'everest_forms_recaptcha_recaptcha_language', 'en-GB' ) ), $url ) );
1340 }
1341
1342 /**
1343 * Adds custom CSS and JavaScript code.
1344 *
1345 * @param int $form_id Form ID.
1346 * @since 2.0.2
1347 * @return void
1348 */
1349 public static function add_custom_css_js( $form_id ) {
1350 $form_id = absint( $form_id );
1351 if ( $form_id <= 0 ) {
1352 return;
1353 }
1354
1355 $form = evf()->form->get( $form_id );
1356 // Check the form_data exist or not.
1357 if ( ! $form ) {
1358 return;
1359 }
1360
1361 $hook = false;
1362
1363 if ( ! did_action( 'wp_head' ) ) {
1364 $hook = 'wp_head';
1365 } elseif ( ! did_action( 'wp_footer' ) ) {
1366 $hook = 'wp_footer';
1367 }
1368
1369 $form_data = apply_filters( 'everest_forms_frontend_form_data', evf_decode( $form->post_content ) );
1370 $settings = isset( $form_data['settings'] ) ? $form_data['settings'] : array();
1371
1372 if ( isset( $settings['evf-enable-custom-css'] ) && evf_string_to_bool( $settings['evf-enable-custom-css'] ) ) {
1373 $custom_css = isset( $settings['evf-custom-css'] ) ? $settings['evf-custom-css'] : '';
1374 $custom_css = preg_match( '#</?\w+#', $custom_css ) ? '' : $custom_css;
1375 if ( ! empty( $custom_css ) ) {
1376 if ( $hook ) {
1377 add_action(
1378 $hook,
1379 function () use ( $custom_css, $form_id ) {
1380 ?>
1381 <style id="<?php echo esc_attr( 'evf-custom-css-' . $form_id ); ?>">
1382 <?php echo esc_attr( $custom_css ); ?>
1383 </style>
1384 <?php
1385 }
1386 );
1387 } else {
1388 ?>
1389 <style id="<?php echo esc_attr( 'evf-custom-css-' . $form_id ); ?>">
1390 <?php echo esc_attr( $custom_css ); ?>
1391 </style>
1392 <?php
1393 }
1394 }
1395 }
1396
1397 if ( isset( $settings['evf-enable-custom-js'] ) && evf_string_to_bool( $settings['evf-enable-custom-js'] ) ) {
1398 $custom_js = isset( $settings['evf-custom-js'] ) ? wp_specialchars_decode( wp_kses_decode_entities( $settings['evf-custom-js'] ) ) : '';
1399 if ( ! empty( $custom_js ) ) {
1400 $custom_js = sprintf(
1401 '( function( $ ) {
1402 $(document).ready( function() {
1403 try {
1404 %s
1405 }
1406 catch( err ) {}
1407 });
1408 })( jQuery )',
1409 $custom_js
1410 );
1411
1412 if ( ! wp_script_is('evf-custom', 'registered') ) {
1413 wp_register_script(
1414 'evf-custom',
1415 '',
1416 array('jquery'),
1417 EVF_VERSION,
1418 true
1419 );
1420 }
1421
1422 if ( ! wp_script_is('evf-custom', 'enqueued' ) ) {
1423 wp_add_inline_script('evf-custom', $custom_js);
1424 wp_enqueue_script('evf-custom');
1425 }
1426 }
1427 }
1428 }
1429
1430 /**
1431 * Function to enable the minimum form submission waiting time.
1432 *
1433 * @since 3.0.2
1434 *
1435 * @param array $form_data Form Data.
1436 */
1437 public static function evf_form_submission_waiting_time( $form_data ) {
1438 $form_submission_waiting_time_enable = isset( $form_data['settings']['form_submission_min_waiting_time'] ) ? $form_data['settings']['form_submission_min_waiting_time'] : '';
1439 $submission_duration = isset( $form_data['settings']['form_submission_min_waiting_time_input'] ) ? $form_data['settings']['form_submission_min_waiting_time_input'] : '';
1440
1441 if ( '1' === $form_submission_waiting_time_enable ) {
1442 echo "<input type='hidden' id='evf_submission_start_time' name='evf_submission_start_time'/>";
1443 } else {
1444 return '';
1445 }
1446 }
1447 /**
1448 * This fuction add the inline script to update the nonce to avoid nonce from caching.
1449 *
1450 * @since 3.3.0
1451 *
1452 * @param [type] $form_data The form data.
1453 * @param [type] $title The title for the form.
1454 * @param [type] $description The Form description.
1455 * @return void
1456 */
1457 public static function inline_script_to_update_nonce( $form_data, $title, $description ) {
1458 $form_id = $form_data['id'];
1459 $form = evf()->form->get( absint( $form_id ) );
1460
1461 if ( empty( $form ) ) {
1462 return;
1463 }
1464
1465 add_action(
1466 'wp_footer',
1467 function () use ( $form_id ) {
1468 echo '<script type="text/javascript">jQuery(function() {'
1469 . 'jQuery.ajax({'
1470 . "url: '" . esc_url( admin_url( 'admin-ajax.php', is_ssl() ? 'https' : 'http' ) ) . "',"
1471 . 'type: "POST",'
1472 . 'data: {'
1473 . 'action: "everest_forms_get_form_update_nonce",'
1474 . 'form_id: "' . (int) $form_id . '",'
1475 . '},'
1476 . 'success: function (response) {'
1477 . "jQuery('#_wpnonce" . (int) $form_id . "').val( response.data );"
1478 . '}'
1479 . '});'
1480 . '})</script>';
1481 },
1482 99
1483 );
1484 }
1485 }
1486