PluginProbe ʕ •ᴥ•ʔ
Everest Forms – Contact Form, Payment Form, Quiz, Survey & Custom Form Builder with AI / 1.9.9
Everest Forms – Contact Form, Payment Form, Quiz, Survey & Custom Form Builder with AI v1.9.9
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 years ago
class-evf-shortcode-form.php
1143 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 }
509
510 if ( ! $site_key || ! $secret_key ) {
511 return;
512 }
513 // Check that the CAPTCHA is configured for the specific form.
514 if (
515 ! isset( $form_data['settings']['recaptcha_support'] ) ||
516 '1' !== $form_data['settings']['recaptcha_support']
517 ) {
518 return;
519 }
520 if ( evf_is_amp() ) {
521 if ( 'v3' === $recaptcha_type ) {
522 printf(
523 '<amp-recaptcha-input name="everest_forms[recaptcha]" data-sitekey="%s" data-action="%s" layout="nodisplay"></amp-recaptcha-input>',
524 esc_attr( $site_key ),
525 esc_attr( 'evf_' . $form_data['id'] )
526 );
527 }
528 return; // Only v3 is supported in AMP.
529 }
530
531 if ( isset( $form_data['settings']['recaptcha_support'] ) && '1' === $form_data['settings']['recaptcha_support'] ) {
532 $form_id = isset( $form_data['id'] ) ? absint( $form_data['id'] ) : 0;
533 $visible = ! empty( self::$parts[ $form_id ] ) ? 'style="display:none;"' : '';
534 $data = apply_filters(
535 'everest_forms_frontend_recaptcha',
536 array(
537 'sitekey' => trim( sanitize_text_field( $site_key ) ),
538 ),
539 $form_data
540 );
541
542 // Load reCAPTCHA support if form supports it.
543 if ( $site_key && $secret_key ) {
544 if ( 'v2' === $recaptcha_type ) {
545 $recaptcha_api = apply_filters( 'everest_forms_frontend_recaptcha_url', 'https://www.google.com/recaptcha/api.js?onload=EVFRecaptchaLoad&render=explicit', $recaptcha_type, $form_id );
546
547 if ( 'yes' === $invisible_recaptcha ) {
548 $data['size'] = 'invisible';
549 $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;});};
550 var EVFRecaptchaCallback = function (el) {
551 var $form = el.closest("form");
552 if( typeof jQuery !== "undefined" ){
553 if( "1" === jQuery( $form ).attr( "data-ajax_submission" ) ) {
554 el.closest( "form" ).querySelector( "button[type=submit]" ).recaptchaID = "verified";
555 jQuery( $form ).find( ".evf-submit" ).trigger( "click" );
556 } else {
557 $form.submit();
558 }
559 grecaptcha.reset();
560 }
561 };
562 ';
563 } else {
564 $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);});};';
565 $recaptcha_inline .= 'var EVFRecaptchaCallback = function(el){jQuery(el).parent().find(".evf-recaptcha-hidden").val("1").trigger("change").valid();};';
566 }
567 } elseif ( 'v3' === $recaptcha_type ) {
568 $recaptcha_api = apply_filters( 'everest_forms_frontend_recaptcha_url', 'https://www.google.com/recaptcha/api.js?render=' . $site_key, $recaptcha_type, $form_id );
569 $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);';
570 $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;}});});';
571 } elseif ( 'hcaptcha' === $recaptcha_type ) {
572 $recaptcha_api = apply_filters( 'everest_forms_frontend_recaptcha_url', 'https://hcaptcha.com/1/api.js??onload=EVFRecaptchaLoad&render=explicit', $recaptcha_type, $form_id );
573 $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);});};';
574 $recaptcha_inline .= 'var EVFRecaptchaCallback = function(el){jQuery(el).parent().find(".evf-recaptcha-hidden").val("1").trigger("change").valid();};';
575 }
576
577 // Enqueue reCaptcha scripts.
578 wp_enqueue_script(
579 'evf-recaptcha',
580 $recaptcha_api,
581 'v3' === $recaptcha_type ? array() : array( 'jquery' ),
582 'v3' === $recaptcha_type ? '3.0.0' : '2.0.0',
583 true
584 );
585
586 // Load reCaptcha callback once.
587 static $count = 1;
588 if ( 1 === $count ) {
589 wp_add_inline_script( 'evf-recaptcha', $recaptcha_inline );
590 $count++;
591 }
592
593 // Output the reCAPTCHA container.
594 $class = ( 'v3' === $recaptcha_type || ( 'v2' === $recaptcha_type && 'yes' === $invisible_recaptcha ) ) ? 'recaptcha-hidden' : '';
595 echo '<div class="evf-recaptcha-container ' . esc_attr( $class ) . '" style="display:' . ( ! empty( self::$parts[ $form_id ] ) ? 'none' : 'block' ) . '">';
596
597 if ( 'v2' === $recaptcha_type || 'hcaptcha' === $recaptcha_type ) {
598 echo '<div ' . evf_html_attributes( '', array( 'g-recaptcha' ), $data ) . '></div>';
599
600 if ( 'hcaptcha' === $recaptcha_type && 'no' === $invisible_recaptcha ) {
601 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>';
602 }
603 } else {
604 echo '<input type="hidden" name="everest_forms[recaptcha]" value="">';
605 }
606
607 echo '</div>';
608 }
609 }
610 }
611
612 /**
613 * Get field attributes.
614 *
615 * @param array $field Field.
616 * @param array $form_data Form data.
617 *
618 * @return array
619 */
620 private static function get_field_attributes( $field, $form_data ) {
621 $form_id = absint( $form_data['id'] );
622 $field_id = esc_attr( $field['id'] );
623 $attributes = array(
624 'field_class' => array( 'evf-field', 'evf-field-' . sanitize_html_class( $field['type'] ), 'form-row' ),
625 'field_id' => array( sprintf( 'evf-%d-field_%s-container', $form_id, $field_id ) ),
626 'field_style' => '',
627 'label_class' => array( 'evf-field-label' ),
628 'label_id' => '',
629 'description_class' => array( 'evf-field-description' ),
630 'description_id' => array(),
631 'input_id' => array( sprintf( 'evf-%d-field_%s', $form_id, $field_id ) ),
632 'input_class' => array(),
633 'input_data' => array(),
634 );
635
636 // Check user field defined classes.
637 if ( ! empty( $field['css'] ) ) {
638 $attributes['field_class'] = array_merge( $attributes['field_class'], evf_sanitize_classes( $field['css'], true ) );
639 }
640
641 // Check for input column layouts.
642 if ( ! empty( $field['input_columns'] ) ) {
643 if ( 'inline' === $field['input_columns'] ) {
644 $attributes['field_class'][] = 'everest-forms-list-inline';
645 } elseif ( '' !== $field['input_columns'] ) {
646 $attributes['field_class'][] = 'everest-forms-list-' . $field['input_columns'] . '-columns';
647 }
648 }
649
650 // Input class.
651 if ( ! in_array( $field['type'], array( 'checkbox', 'radio', 'payment-checkbox', 'payment-multiple' ), true ) ) {
652 $attributes['input_class'][] = 'input-text';
653 }
654
655 // Check label visibility.
656 if ( ! empty( $field['label_hide'] ) ) {
657 $attributes['label_class'][] = 'evf-label-hide';
658 }
659
660 // Check size.
661 if ( ! empty( $field['size'] ) ) {
662 $attributes['input_class'][] = 'evf-field-' . sanitize_html_class( $field['size'] );
663 }
664
665 // Check if required.
666 if ( ! empty( $field['required'] ) ) {
667 $attributes['field_class'][] = 'validate-required';
668 }
669
670 // Check if extra validation required.
671 if ( in_array( $field['type'], array( 'email', 'phone' ), true ) ) {
672 $attributes['field_class'][] = 'validate-' . esc_attr( $field['type'] );
673 }
674
675 // Check if there are errors.
676 if ( isset( evf()->task->errors[ $form_id ][ $field_id ] ) ) {
677 $attributes['input_class'][] = 'evf-error';
678 $attributes['field_class'][] = 'everest-forms-invalid';
679 }
680
681 // This filter is deprecated, filter the properties (below) instead.
682 $attributes = apply_filters( 'evf_field_atts', $attributes, $field, $form_data );
683
684 return $attributes;
685 }
686
687 /**
688 * Return base properties for a specific field.
689 *
690 * @param array $field Field data and settings.
691 * @param array $form_data Form data and settings.
692 * @param array $attributes List of field attributes.
693 *
694 * @return array
695 */
696 public static function get_field_properties( $field, $form_data, $attributes = array() ) {
697 if ( empty( $attributes ) ) {
698 $attributes = self::get_field_attributes( $field, $form_data );
699 }
700
701 // This filter is for backwards compatibility purposes.
702 $types = array( 'text', 'textarea', 'number', 'email', 'hidden', 'url', 'html', 'title', 'password', 'phone', 'address', 'checkbox', 'radio', 'select' );
703 if ( in_array( $field['type'], $types, true ) ) {
704 $field = apply_filters( "everest_forms_{$field['type']}_field_display", $field, $attributes, $form_data );
705 }
706
707 $form_id = absint( $form_data['id'] );
708 $field_id = sanitize_text_field( $field['id'] );
709
710 // Field container data.
711 $container_data = array();
712
713 // Embed required-field-message to the container if the field is required.
714 if ( isset( $field['required'] ) && ( '1' === $field['required'] || true === $field['required'] ) ) {
715 $has_sub_fields = false;
716 $sub_field_messages = array();
717 $required_validation = get_option( 'everest_forms_required_validation' );
718 if ( in_array( $field['type'], array( 'number', 'email', 'url', 'phone' ), true ) ) {
719 $required_validation = get_option( 'everest_forms_' . $field['type'] . '_validation' );
720 }
721
722 if ( 'likert' === $field['type'] ) {
723 $has_sub_fields = true;
724 $likert_rows = isset( $field['likert_rows'] ) ? $field['likert_rows'] : array();
725 $row_keys = array();
726 foreach ( $likert_rows as $row_key => $row_label ) {
727 $row_keys[] = $row_key;
728 $row_slug = 'required-field-message-' . $row_key;
729 $sub_field_messages[ $row_key ] = isset( $field[ $row_slug ] ) ? evf_string_translation( $form_data['id'], $field['id'], $field[ $row_slug ], '-' . $row_slug ) : $required_validation;
730 }
731 $container_data['row-keys'] = wp_json_encode( $row_keys );
732 } elseif ( 'address' === $field['type'] ) {
733 $has_sub_fields = true;
734 $sub_field_messages = array(
735 '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' ),
736 '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' ),
737 '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' ),
738 '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' ),
739 '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' ),
740 );
741 }
742
743 if ( true === $has_sub_fields ) {
744 foreach ( $sub_field_messages as $sub_field_type => $error_message ) {
745 $container_data[ 'required-field-message-' . $sub_field_type ] = $error_message;
746 }
747 } else {
748
749 if ( isset( $field['required_field_message_setting'] ) && 'global' === $field['required_field_message_setting'] ) {
750 $container_data['required-field-message'] = $required_validation;
751 } elseif ( isset( $field['required-field-message'] ) && '' !== $field['required-field-message'] ) {
752 $container_data['required-field-message'] = evf_string_translation( $form_data['id'], $field['id'], $field['required-field-message'], '-required-field-message' );
753 } else {
754 $container_data['required-field-message'] = $required_validation;
755 }
756 }
757 }
758 $errors = isset( evf()->task->errors[ $form_id ][ $field_id ] ) ? evf()->task->errors[ $form_id ][ $field_id ] : '';
759 $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
760 $properties = apply_filters(
761 'everest_forms_field_properties_' . $field['type'],
762 array(
763 'container' => array(
764 'attr' => array(
765 'style' => $attributes['field_style'],
766 ),
767 'class' => $attributes['field_class'],
768 'data' => $container_data,
769 'id' => implode( '', array_slice( $attributes['field_id'], 0 ) ),
770 ),
771 'label' => array(
772 'attr' => array(
773 'for' => sprintf( 'evf-%d-field_%s', $form_id, $field_id ),
774 ),
775 'class' => $attributes['label_class'],
776 'data' => array(),
777 'disabled' => ! empty( $field['label_disable'] ) ? true : false,
778 'hidden' => ! empty( $field['label_hide'] ) ? true : false,
779 'id' => $attributes['label_id'],
780 'required' => ! empty( $field['required'] ) ? true : false,
781 'value' => ! empty( $field['label'] ) ? $field['label'] : '',
782 ),
783 'inputs' => array(
784 'primary' => array(
785 'attr' => array(
786 'name' => "everest_forms[form_fields][{$field_id}]",
787 'value' => isset( $field['default_value'] ) ? apply_filters( 'everest_forms_process_smart_tags', $field['default_value'], $form_data ) : $defaults,
788 'placeholder' => isset( $field['placeholder'] ) ? evf_string_translation( $form_data['id'], $field['id'], $field['placeholder'], '-placeholder' ) : '',
789 ),
790 'class' => $attributes['input_class'],
791 'data' => $attributes['input_data'],
792 'id' => implode( array_slice( $attributes['input_id'], 0 ) ),
793 'required' => ! empty( $field['required'] ) ? 'required' : '',
794 ),
795 ),
796 'error' => array(
797 'attr' => array(
798 'for' => sprintf( 'evf-%d-field_%s', $form_id, $field_id ),
799 ),
800 'class' => array( 'evf-error' ),
801 'data' => array(),
802 'id' => '',
803 'value' => ! empty( $errors ) ? $errors : '',
804 ),
805 'description' => array(
806 'attr' => array(),
807 'class' => $attributes['description_class'],
808 'data' => array(),
809 'id' => implode( '', array_slice( $attributes['description_id'], 0 ) ),
810 'position' => 'after',
811 'value' => ! empty( $field['description'] ) ? $field['description'] : '',
812 ),
813 ),
814 $field,
815 $form_data
816 );
817
818 return apply_filters( 'everest_forms_field_properties', $properties, $field, $form_data );
819 }
820
821 /**
822 * Output the shortcode.
823 *
824 * @param array $atts Attributes.
825 */
826 public static function output( $atts ) {
827 wp_enqueue_script( 'everest-forms' );
828
829 // Load jQuery flatpickr libraries. https://github.com/flatpickr/flatpickr.
830 if ( evf_is_field_exists( $atts['id'], 'date-time' ) ) {
831 wp_enqueue_style( 'flatpickr' );
832 wp_enqueue_script( 'flatpickr' );
833 }
834
835 // Load jQuery mailcheck library - https://github.com/mailcheck/mailcheck.
836 if ( evf_is_field_exists( $atts['id'], 'email' ) && (bool) apply_filters( 'everest_forms_mailcheck_enabled', true ) ) {
837 wp_enqueue_script( 'mailcheck' );
838 }
839
840 $atts = shortcode_atts(
841 array(
842 'id' => false,
843 'type' => false,
844 'size' => false,
845 'text' => false,
846 'title' => false,
847 'description' => false,
848 ),
849 $atts,
850 'output'
851 );
852
853 // Scripts load action.
854 do_action( 'everest_forms_shortcode_scripts', $atts );
855
856 ob_start();
857 self::view( $atts );
858 echo ob_get_clean(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
859 }
860
861 /**
862 * Form view.
863 *
864 * @param array $atts Attributes.
865 */
866 private static function view( $atts ) {
867 $id = isset( $atts['id'] ) ? $atts['id'] : false;
868 $title = isset( $atts['title'] ) ? $atts['title'] : false;
869 $description = isset( $atts['description'] ) ? $atts['description'] : false;
870 $popup_type = isset( $atts['type'] ) ? $atts['type'] : false;
871 $popup_text = isset( $atts['text'] ) ? $atts['text'] : false;
872 if ( empty( $id ) ) {
873 return;
874 }
875
876 // Grab the form data, if not found then we bail.
877 $form = evf()->form->get( (int) $id );
878
879 if ( empty( $form ) || 'publish' !== $form->post_status ) {
880 return;
881 }
882
883 // Basic form information.
884 $form_data = apply_filters( 'everest_forms_frontend_form_data', evf_decode( $form->post_content ) );
885 $form_id = absint( $form->ID );
886 $settings = isset( $form_data['settings'] ) ? $form_data['settings'] : array();
887 $action = esc_url_raw( remove_query_arg( 'evf-forms' ) );
888 $title = filter_var( $title, FILTER_VALIDATE_BOOLEAN );
889 $description = filter_var( $description, FILTER_VALIDATE_BOOLEAN );
890 $errors = isset( evf()->task->errors[ $form_id ] ) ? evf()->task->errors[ $form_id ] : array();
891 $form_enabled = isset( $form_data['form_enabled'] ) ? absint( $form_data['form_enabled'] ) : 1;
892 $kff_enabled = isset( $settings['keyboard_friendly_form'] ) ? absint( $settings['keyboard_friendly_form'] ) : 0;
893 $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' );
894 if ( isset( $form_data['payments']['stripe']['enable_stripe'] ) && '1' === $form_data['payments']['stripe']['enable_stripe'] ) {
895 $ajax_form_submission = isset( $settings['ajax_form_submission'] ) ? 1 : 0;
896 } else {
897 $ajax_form_submission = isset( $settings['ajax_form_submission'] ) ? $settings['ajax_form_submission'] : 0;
898 }
899
900 if ( 0 !== $ajax_form_submission ) {
901 wp_enqueue_script( 'everest-forms-ajax-submission' );
902 }
903
904 // If the form is disabled or does not contain any fields do not proceed.
905 if ( empty( $form_data['form_fields'] ) ) {
906 echo '<!-- Everest Forms: no fields, form hidden -->';
907 return;
908 } elseif ( 1 !== $form_enabled ) {
909 if ( ! empty( $disable_message ) ) {
910 printf( '<p class="everst-forms-form-disable-notice everest-forms-notice everest-forms-notice--info">%s</p>', esc_textarea( $disable_message ) );
911 }
912 return;
913 }
914
915 // We need to stop output processing in case we are on AMP page.
916 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', '<' ) ) ) {
917
918 $full_page_url = home_url( add_query_arg( 'nonamp', '1' ) . '#evfforms-' . absint( $form->ID ) );
919
920 /**
921 * Allow modifying the text or url for the full page on the AMP pages.
922 *
923 * @since 1.4.1.1
924 * @since 1.7.1 Added $form_id, $full_page_url, and $form_data arguments.
925 *
926 * @param int $form_id Form id.
927 * @param array $form_data Form data and settings.
928 *
929 * @return string
930 */
931 $text = (string) apply_filters(
932 'evf_frontend_shortcode_amp_text',
933 sprintf( /* translators: %s - URL to a non-amp version of a page with the form. */
934 __( '<a href="%s">Go to the full page</a> to view and submit the form.', 'everest-forms' ),
935 esc_url( $full_page_url )
936 ),
937 $form_id,
938 $full_page_url,
939 $form_data
940 );
941
942 printf(
943 '<p class="evf-shortcode-amp-text">%s</p>',
944 wp_kses_post( $text )
945 );
946
947 return;
948 }
949
950 // Before output hook.
951 do_action( 'everest_forms_frontend_output_before', $form_data, $form );
952
953 // Check for return hash.
954 if (
955 ! empty( $_GET['everest_forms_return'] ) // phpcs:ignore WordPress.Security.NonceVerification
956 && evf()->task->is_valid_hash
957 && absint( evf()->task->form_data['id'] ) === $form_id
958 ) {
959 // Output success message if no redirection happened.
960 if ( 'same' === $form_data['settings']['redirect_to'] ) {
961 evf_add_notice( 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' ), 'success' );
962 }
963
964 do_action( 'everest_forms_frontend_output_success', evf()->task->form_data, evf()->task->form_fields, evf()->task->entry_id );
965 return;
966 }
967
968 $success = apply_filters( 'everest_forms_success', false, $form_id );
969 if ( $success && ! empty( $form_data ) ) {
970 do_action( 'everest_forms_frontend_output_success', $form_data );
971 return;
972 }
973
974 // Allow filter to return early if some condition is not meet.
975 if ( ! apply_filters( 'everest_forms_frontend_load', true, $form_data ) ) {
976 do_action( 'everest_forms_frontend_not_loaded', $form_data, $form );
977 return;
978 }
979
980 /**
981 * BW compatiable for multi-parts form.
982 *
983 * @todo Remove in Major EVF version 1.6.0
984 */
985 if ( defined( 'EVF_MULTI_PART_PLUGIN_FILE' ) ) {
986 include_once ABSPATH . 'wp-admin/includes/plugin.php';
987 $plugin_data = get_plugin_data( EVF_MULTI_PART_PLUGIN_FILE, false, false );
988
989 if ( version_compare( $plugin_data['Version'], '1.3.0', '<' ) ) {
990 $settings_defaults = array(
991 'indicator' => 'progress',
992 'indicator_color' => '#7e3bd0',
993 'nav_align' => 'center',
994 );
995
996 if ( isset( $form_data['settings']['enable_multi_part'] ) && evf_string_to_bool( $form_data['settings']['enable_multi_part'] ) ) {
997 $settings = isset( $form_data['settings']['multi_part'] ) ? $form_data['settings']['multi_part'] : array();
998
999 if ( ! empty( $form_data['multi_part'] ) ) {
1000 self::$parts = array(
1001 'total' => count( $form_data['multi_part'] ),
1002 'current' => 1,
1003 'parts' => array_values( $form_data['multi_part'] ),
1004 'settings' => wp_parse_args( $settings, $settings_defaults ),
1005 );
1006 }
1007 } else {
1008 self::$parts = array(
1009 'total' => '',
1010 'current' => '',
1011 'parts' => array(),
1012 'settings' => $settings_defaults,
1013 );
1014 }
1015 }
1016 }
1017
1018 // Allow Multi-Part to be customized.
1019 $parts = ! empty( self::$parts[ $form_id ] ) ? self::$parts[ $form_id ] : array();
1020 self::$parts[ $form_id ] = apply_filters( 'everest_forms_parts_data', $parts, $form_data, $form_id );
1021
1022 // Allow final action to be customized.
1023 $action = apply_filters( 'everest_forms_frontend_form_action', $action, $form_data );
1024
1025 // Allow form container classes to be filtered and user defined classes.
1026 $classes = apply_filters( 'everest_forms_frontend_container_class', array(), $form_data );
1027 if ( ! empty( $settings['form_class'] ) ) {
1028 $classes = array_merge( $classes, explode( ' ', $settings['form_class'] ) );
1029 }
1030 if ( ! empty( $settings['layout_class'] ) ) {
1031 $classes = array_merge( $classes, explode( ' ', $settings['layout_class'] ) );
1032 }
1033 $classes = evf_sanitize_classes( $classes, true );
1034
1035 $form_atts = array(
1036 'id' => sprintf( 'evf-form-%d', absint( $form_id ) ),
1037 'class' => array( 'everest-form' ),
1038 'data' => array(
1039 'formid' => absint( $form_id ),
1040 'ajax_submission' => $ajax_form_submission,
1041 'keyboard_friendly_form' => $kff_enabled,
1042 ),
1043 'atts' => array(
1044 'method' => 'post',
1045 'enctype' => 'multipart/form-data',
1046 'action' => esc_url( $action ),
1047 ),
1048 );
1049
1050 if ( evf_is_amp() ) {
1051
1052 // Set submitting state.
1053 if ( ! isset( $form_atts['atts']['on'] ) ) {
1054 $form_atts['atts']['on'] = '';
1055 } else {
1056 $form_atts['atts']['on'] .= ';';
1057 }
1058 $form_atts['atts']['on'] .= sprintf(
1059 'submit:AMP.setState( %1$s ); submit-success:AMP.setState( %2$s ); submit-error:AMP.setState( %2$s );',
1060 wp_json_encode(
1061 array(
1062 self::get_form_amp_state_id( $form_id ) => array(
1063 'submitting' => true,
1064 ),
1065 )
1066 ),
1067 wp_json_encode(
1068 array(
1069 self::get_form_amp_state_id( $form_id ) => array(
1070 'submitting' => false,
1071 ),
1072 )
1073 )
1074 );
1075
1076 // Upgrade the form to be an amp-form to avoid sanitizer conversion.
1077 if ( isset( $form_atts['atts']['action'] ) ) {
1078 $form_atts['atts']['action-xhr'] = $form_atts['atts']['action'];
1079 unset( $form_atts['atts']['action'] );
1080
1081 $form_atts['atts']['verify-xhr'] = $form_atts['atts']['action-xhr'];
1082 }
1083 }
1084
1085 $form_atts = apply_filters( 'everest_forms_frontend_form_atts', $form_atts, $form_data );
1086 // Begin to build the output.
1087 do_action( 'everest_forms_frontend_output_container_before', $form_data, $form );
1088
1089 printf( '<div class="evf-container %s" id="evf-%d">', esc_attr( $classes ), absint( $form_id ) );
1090
1091 do_action( 'everest_forms_frontend_output_form_before', $form_data, $form, $errors );
1092 if ( isset( $atts['type'] ) && 'popup-button' === $popup_type ) {
1093 printf( "<button class='everest-forms-modal-link everest-forms-modal-link-%s'>%s</button>", esc_attr( $atts['id'] ), esc_html( $popup_text ) );
1094 do_action( 'everest_form_popup', $atts );
1095 } elseif ( isset( $atts['type'] ) && 'popup-link' === $popup_type ) {
1096 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 ) );
1097 do_action( 'everest_form_popup', $atts );
1098 } elseif ( isset( $atts['type'] ) && 'popup' === $popup_type ) {
1099 do_action( 'everest_form_popup', $atts );
1100 } else {
1101 echo '<form ' . evf_html_attributes( $form_atts['id'], $form_atts['class'], $form_atts['data'], $form_atts['atts'] ) . '>';
1102 if ( evf_is_amp() ) {
1103 $state = array(
1104 'submitting' => false,
1105 );
1106 printf(
1107 '<amp-state id="%s"><script type="application/json">%s</script></amp-state>',
1108 self::get_form_amp_state_id( $form_id ), // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1109 wp_json_encode( $state )
1110 );
1111 }
1112 do_action( 'everest_forms_frontend_output', $form_data, $title, $description, $errors );
1113
1114 echo '</form>';
1115 }
1116
1117 do_action( 'everest_forms_frontend_output_form_after', $form_data, $form );
1118
1119 echo '</div><!-- .evf-container -->';
1120
1121 // After output hook.
1122 do_action( 'everest_forms_frontend_output_after', $form_data, $form );
1123
1124 // Debug information.
1125 if ( is_super_admin() ) {
1126 evf_debug_data( $form_data );
1127 }
1128 }
1129
1130 /**
1131 * ReCaptcha Langauge.
1132 *
1133 * @param url $url Recaptcha URL.
1134 *
1135 * @return $url
1136 */
1137 public static function evf_recaptcha_language( $url ) {
1138
1139 return esc_url_raw( add_query_arg( array( 'hl' => get_option( 'everest_forms_recaptcha_recaptcha_language', 'en-GB' ) ), $url ) );
1140
1141 }
1142 }
1143