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