PluginProbe ʕ •ᴥ•ʔ
Everest Forms – Contact Form, Payment Form, Quiz, Survey & Custom Form Builder with AI / 1.6.3
Everest Forms – Contact Form, Payment Form, Quiz, Survey & Custom Form Builder with AI v1.6.3
3.5.2 3.5.1 3.5.0 3.4.8 3.4.7 3.4.6 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.5.1 1.1.6 1.1.7 1.1.8 1.1.9 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.10 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.6.1 1.6.7 1.7.0 1.7.0.1 1.7.0.2 1.7.0.3 1.7.1 1.7.2 1.7.2.1 1.7.2.2 1.7.3 1.7.4 1.7.5 1.7.5.1 1.7.5.2 1.7.6 1.7.7 1.7.7.1 1.7.7.2 1.7.8 1.7.9 1.8.0 1.8.0.1 1.8.1 1.8.2 1.8.2.1 1.8.2.2 1.8.2.3 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.0.1 1.9.1 1.9.2 1.9.3 1.9.4 1.9.4.1 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.0.1 2.0.1 2.0.2 2.0.3 2.0.3.1 2.0.4 2.0.4.1 2.0.5 2.0.6 2.0.7 2.0.8 2.0.8.1 2.0.9 3.0.0 3.0.0.1 3.0.1 3.0.2 3.0.3 3.0.3.1 3.0.4 3.0.4.1 3.0.4.2 3.0.5 3.0.5.1 3.0.5.2 3.0.6 3.0.6.1 3.0.7.1 3.0.8 3.0.8.1 3.0.9 3.0.9.1 3.0.9.2 3.0.9.3 3.0.9.4 3.0.9.5 3.1.0 3.1.1 3.1.2 3.2.0 3.2.1 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.3.0 3.4.0 3.4.1 3.4.2 3.4.2.1 3.4.3 3.4.4 3.4.5 trunk 1.0 1.0.1 1.0.2 1.0.3
everest-forms / includes / class-evf-form-task.php
everest-forms / includes Last commit date
abstracts 6 years ago admin 6 years ago export 6 years ago fields 6 years ago interfaces 8 years ago libraries 7 years ago log-handlers 6 years ago shortcodes 6 years ago templates 6 years ago class-everest-forms.php 6 years ago class-evf-ajax.php 6 years ago class-evf-autoloader.php 7 years ago class-evf-background-updater.php 7 years ago class-evf-cache-helper.php 6 years ago class-evf-deprecated-action-hooks.php 6 years ago class-evf-deprecated-filter-hooks.php 7 years ago class-evf-emails.php 6 years ago class-evf-fields.php 6 years ago class-evf-form-block.php 6 years ago class-evf-form-handler.php 6 years ago class-evf-form-task.php 6 years ago class-evf-forms-features.php 6 years ago class-evf-frontend-scripts.php 6 years ago class-evf-install.php 6 years ago class-evf-integrations.php 7 years ago class-evf-log-levels.php 8 years ago class-evf-logger.php 6 years ago class-evf-post-types.php 6 years ago class-evf-privacy.php 6 years ago class-evf-session-handler.php 7 years ago class-evf-shortcodes.php 7 years ago class-evf-smart-tags.php 6 years ago class-evf-template-loader.php 6 years ago class-evf-validation.php 6 years ago evf-conditional-functions.php 6 years ago evf-core-functions.php 6 years ago evf-deprecated-functions.php 6 years ago evf-entry-functions.php 6 years ago evf-formatting-functions.php 6 years ago evf-notice-functions.php 6 years ago evf-template-functions.php 6 years ago evf-template-hooks.php 7 years ago evf-update-functions.php 6 years ago
class-evf-form-task.php
724 lines
1 <?php
2 /**
3 * Process form data
4 *
5 * @package EverestForms
6 * @since 1.0.0
7 */
8
9 defined( 'ABSPATH' ) || exit;
10
11 /**
12 * EVF_Form_Task class.
13 */
14 class EVF_Form_Task {
15
16 /**
17 * Holds errors.
18 *
19 * @since 1.0.0
20 * @var array
21 */
22 public $errors;
23
24 /**
25 * Holds formatted fields.
26 *
27 * @since 1.0.0
28 * @var array
29 */
30 public $form_fields;
31
32 /**
33 * Holds the ID of a successful entry.
34 *
35 * @since 1.0.0
36 * @var int
37 */
38 public $entry_id = 0;
39
40 /**
41 * Form data and settings.
42 *
43 * @since 1.5.0
44 *
45 * @var array
46 */
47 public $form_data = array();
48
49 /**
50 * Primary class constructor.
51 *
52 * @since 1.0.0
53 */
54 public function __construct() {
55 add_action( 'wp', array( $this, 'listen_task' ) );
56 }
57
58 /**
59 * Listen to see if this is a return callback or a posted form entry.
60 *
61 * @since 1.0.0
62 */
63 public function listen_task() {
64 if ( ! empty( $_GET['everest_forms_return'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
65 $this->entry_confirmation_redirect( '', wp_unslash( $_GET['everest_forms_return'] ) ); // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
66 }
67
68 if ( ! empty( $_POST['everest_forms']['id'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
69 $this->do_task( stripslashes_deep( $_POST['everest_forms'] ) ); // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
70 }
71 }
72
73 /**
74 * Do task of form entry
75 *
76 * @since 1.0.0
77 * @param array $entry $_POST object.
78 */
79 public function do_task( $entry ) {
80 try {
81 $this->errors = array();
82 $this->form_fields = array();
83 $form_id = absint( $entry['id'] );
84 $form = evf()->form->get( $form_id );
85 $honeypot = false;
86 $response_data = array();
87 $this->ajax_err = array();
88 $this->evf_notice_print = false;
89
90 // Check nonce for form submission.
91 if ( empty( $_POST['_wpnonce'] ) || ! wp_verify_nonce( wp_unslash( $_POST['_wpnonce'] ), 'everest-forms_process_submit' ) ) { // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
92 $this->errors[ $form_id ]['header'] = esc_html__( 'We were unable to process your form, please try again.', 'everest-forms' );
93 return $this->errors;
94 }
95
96 // Validate form is real and active (published).
97 if ( ! $form || 'publish' !== $form->post_status ) {
98 $this->errors[ $form_id ]['header'] = esc_html__( 'Invalid form. Please check again.', 'everest-forms' );
99 return $this->errors;
100 }
101
102 // Formatted form data for hooks.
103 $this->form_data = apply_filters( 'everest_forms_process_before_form_data', evf_decode( $form->post_content ), $entry );
104
105 // Pre-process/validate hooks and filter. Data is not validated or cleaned yet so use with caution.
106 $entry = apply_filters( 'everest_forms_process_before_filter', $entry, $this->form_data );
107
108 do_action( 'everest_forms_process_before', $entry, $this->form_data );
109 do_action( "everest_forms_process_before_{$form_id}", $entry, $this->form_data );
110
111 $ajax_form_submission = isset( $this->form_data['settings']['ajax_form_submission'] ) ? $this->form_data['settings']['ajax_form_submission'] : 0;
112 if ( '1' === $ajax_form_submission ) {
113
114 // For the sake of validation we completely remove the validator option.
115 update_option( 'evf_validation_error', '' );
116
117 // Prepare fields for entry_save.
118 foreach ( $this->form_data['form_fields'] as $field ) {
119
120 if ( '' === isset( $this->form_data['form_fields']['meta-key'] ) ) {
121 continue;
122 }
123
124 $field_id = $field['id'];
125 $field_type = $field['type'];
126 $field_submit = isset( $entry['form_fields'][ $field_id ] ) ? $entry['form_fields'][ $field_id ] : '';
127
128 if ( 'signature' === $field_type ) {
129 $field_submit = isset( $field_submit['signature_image'] ) ? $field_submit['signature_image'] : '';
130 }
131
132 $exclude = array( 'title', 'html', 'captcha' );
133
134 if ( ! in_array( $field_type, $exclude, true ) ) {
135 $this->form_fields[ $field_id ] = array(
136 'id' => $field_id,
137 'name' => sanitize_text_field( $field['label'] ),
138 'meta_key' => $this->form_data['form_fields'][ $field_id ]['meta-key'],
139 'type' => $field_type,
140 'value' => evf_sanitize_textarea_field( $field_submit ),
141 );
142 }
143 }
144 }
145
146 // Validate fields.
147 foreach ( $this->form_data['form_fields'] as $field ) {
148 $field_id = $field['id'];
149 $field_type = $field['type'];
150 $field_submit = isset( $entry['form_fields'][ $field_id ] ) ? $entry['form_fields'][ $field_id ] : '';
151
152 do_action( "everest_forms_process_validate_{$field_type}", $field_id, $field_submit, $this->form_data, $field_type );
153
154 if ( 'credit-card' === $field_type ) {
155 $this->evf_notice_print = true;
156 }
157
158 if ( 'yes' === get_option( 'evf_validation_error' ) && $ajax_form_submission ) {
159 $this->ajax_err[] = array( $field_type => $field_id );
160 update_option( 'evf_validation_error', '' );
161 }
162 }
163 // If validation issues occur, send the results accordingly.
164 if ( $ajax_form_submission && count( $this->ajax_err ) ) {
165 $response_data['error'] = $this->ajax_err;
166 $response_data['message'] = __( 'Form has not been submitted, please see the errors below.', 'everest-forms' );
167 $response_data['response'] = 'error';
168 return $response_data;
169 }
170
171 // reCAPTCHA check.
172 $recaptcha_type = get_option( 'everest_forms_recaptcha_type', 'v2' );
173 $invisible_recaptcha = get_option( 'everest_forms_recaptcha_v2_invisible', 'no' );
174
175 if ( 'v2' === $recaptcha_type && 'no' === $invisible_recaptcha ) {
176 $site_key = get_option( 'everest_forms_recaptcha_v2_site_key' );
177 $secret_key = get_option( 'everest_forms_recaptcha_v2_secret_key' );
178 } elseif ( 'v2' === $recaptcha_type && 'yes' === $invisible_recaptcha ) {
179 $site_key = get_option( 'everest_forms_recaptcha_v2_invisible_site_key' );
180 $secret_key = get_option( 'everest_forms_recaptcha_v2_invisible_secret_key' );
181 } else {
182 $site_key = get_option( 'everest_forms_recaptcha_v3_site_key' );
183 $secret_key = get_option( 'everest_forms_recaptcha_v3_secret_key' );
184 }
185
186 if ( ! empty( $site_key ) && ! empty( $secret_key ) && isset( $this->form_data['settings']['recaptcha_support'] ) && '1' === $this->form_data['settings']['recaptcha_support'] ) {
187 if ( ( 'v2' === $recaptcha_type && ! empty( $_POST['g-recaptcha-response'] ) ) || ( 'v3' === $recaptcha_type && ! empty( $_POST['g-recaptcha-hidden'] ) ) ) {
188 $response = 'v2' === $recaptcha_type ? evf_clean( wp_unslash( $_POST['g-recaptcha-response'] ) ) : evf_clean( wp_unslash( $_POST['g-recaptcha-hidden'] ) ); // phpcs:ignore WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
189 $raw_data = wp_safe_remote_get( 'https://www.google.com/recaptcha/api/siteverify?secret=' . $secret_key . '&response=' . $response );
190
191 if ( ! is_wp_error( $raw_data ) ) {
192 $data = json_decode( wp_remote_retrieve_body( $raw_data ) );
193
194 // Check reCAPTCHA response.
195 if ( empty( $data->success ) || ( isset( $data->hostname ) && evf_clean( wp_unslash( $_SERVER['SERVER_NAME'] ) ) !== $data->hostname ) || ( isset( $data->action, $data->score ) && ( 'everest_form' !== $data->action && 0.5 > floatval( $data->score ) ) ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
196 $this->errors[ $form_id ]['header'] = esc_html__( 'Incorrect reCAPTCHA, please try again.', 'everest-forms' );
197 return $this->errors;
198 }
199 }
200 } else {
201 // @todo This error message is not delivered in frontend. Need to fix :)
202 $this->errors[ $form_id ]['recaptcha'] = esc_html__( 'reCAPTCHA is required.', 'everest-forms' );
203 }
204 }
205
206 // Initial error check.
207 $errors = apply_filters( 'everest_forms_process_initial_errors', $this->errors, $this->form_data );
208
209 if ( ! empty( $errors[ $form_id ] ) ) {
210 if ( empty( $errors[ $form_id ]['header'] ) ) {
211 $errors[ $form_id ]['header'] = __( 'Form has not been submitted, please see the errors below.', 'everest-forms' );
212 }
213 $this->errors = $errors;
214 return $this->errors;
215 }
216
217 // Early honeypot validation - before actual processing.
218 if ( isset( $this->form_data['settings']['honeypot'] ) && '1' === $this->form_data['settings']['honeypot'] && ! empty( $entry['hp'] ) ) {
219 $honeypot = esc_html__( 'Everest Forms honeypot field triggered.', 'everest-forms' );
220 }
221
222 $honeypot = apply_filters( 'everest_forms_process_honeypot', $honeypot, $this->form_fields, $entry, $this->form_data );
223
224 // If spam - return early.
225 if ( $honeypot ) {
226 $logger = evf_get_logger();
227 $logger->notice( sprintf( 'Spam entry for Form ID %d Response: %s', absint( $this->form_data['id'] ), evf_print_r( $entry, true ) ), array( 'source' => 'honeypot' ) );
228 return $this->errors;
229 }
230
231 // Pass the form created date into the form data.
232 $this->form_data['created'] = $form->post_date;
233
234 // Format fields.
235 foreach ( (array) $this->form_data['form_fields'] as $field ) {
236 $field_id = $field['id'];
237 $field_key = isset( $field['meta-key'] ) ? $field['meta-key'] : '';
238 $field_type = $field['type'];
239 $field_submit = isset( $entry['form_fields'][ $field_id ] ) ? $entry['form_fields'][ $field_id ] : '';
240
241 do_action( "everest_forms_process_format_{$field_type}", $field_id, $field_submit, $this->form_data, $field_key );
242 }
243
244 // This hook is for internal purposes and should not be leveraged.
245 do_action( 'everest_forms_process_format_after', $this->form_data );
246
247 // Process hooks/filter - this is where most addons should hook
248 // because at this point we have completed all field validation and
249 // formatted the data.
250 $this->form_fields = apply_filters( 'everest_forms_process_filter', $this->form_fields, $entry, $this->form_data );
251
252 do_action( 'everest_forms_process', $this->form_fields, $entry, $this->form_data );
253 do_action( "everest_forms_process_{$form_id}", $this->form_fields, $entry, $this->form_data );
254
255 $this->form_fields = apply_filters( 'everest_forms_process_after_filter', $this->form_fields, $entry, $this->form_data );
256
257 // One last error check - don't proceed if there are any errors.
258 if ( ! empty( $this->errors[ $form_id ] ) ) {
259 if ( empty( $this->errors[ $form_id ]['header'] ) ) {
260 $this->errors[ $form_id ]['header'] = esc_html__( 'Form has not been submitted, please see the errors below.', 'everest-forms' );
261 }
262 return $this->errors;
263 }
264
265 // Success - add entry to database.
266 $entry_id = $this->entry_save( $this->form_fields, $entry, $this->form_data['id'], $this->form_data );
267
268 // Success - send email notification.
269 $this->entry_email( $this->form_fields, $entry, $this->form_data, $entry_id, 'entry' );
270
271 // @todo remove this way of printing notices.
272 add_filter( 'everest_forms_success', array( $this, 'check_success_message' ), 10, 2 );
273
274 // Pass completed and formatted fields in POST.
275 $_POST['everest-forms']['complete'] = $this->form_fields;
276
277 // Pass entry ID in POST.
278 $_POST['everest-forms']['entry_id'] = $entry_id;
279
280 // Post-process hooks.
281 do_action( 'everest_forms_process_complete', $this->form_fields, $entry, $this->form_data, $entry_id );
282 do_action( "everest_forms_process_complete_{$form_id}", $this->form_fields, $entry, $this->form_data, $entry_id );
283 } catch ( Exception $e ) {
284 evf_add_notice( $e->getMessage(), 'error' );
285 if ( '1' === $ajax_form_submission ) {
286 $this->errors[] = $e->getMessage();
287 $response_data['message'] = $this->errors;
288 $response_data['response'] = 'error';
289 return $response_data;
290 }
291 }
292
293 $message = isset( $this->form_data['settings']['successful_form_submission_message'] ) ? $this->form_data['settings']['successful_form_submission_message'] : __( 'Thanks for contacting us! We will be in touch with you shortly.', 'everest-forms' );
294 if ( '1' === $ajax_form_submission ) {
295 $response_data['message'] = $message;
296 $response_data['response'] = 'success';
297 $settings = $this->form_data['settings'];
298
299 // Backward Compatibility Check.
300 switch ( $settings['redirect_to'] ) {
301 case '0':
302 $settings['redirect_to'] = 'same';
303 break;
304
305 case '1':
306 $settings['redirect_to'] = 'custom_page';
307 break;
308
309 case '2':
310 $settings['redirect_to'] = 'external_url';
311 break;
312 }
313
314 if ( isset( $settings['redirect_to'] ) && 'external_url' === $settings['redirect_to'] ) {
315 $response_data['redirect_url'] = isset( $settings['external_url'] ) ? esc_url( $settings['external_url'] ) : 'undefined';
316 } elseif ( isset( $settings['redirect_to'] ) && 'custom_page' === $settings['redirect_to'] ) {
317 $response_data['redirect_url'] = isset( $settings['custom_page'] ) ? get_page_link( absint( $settings['custom_page'] ) ) : 'undefined';
318 }
319
320 // Add notice only if credit card is populated in form fields.
321 if ( isset( $this->evf_notice_print ) && $this->evf_notice_print ) {
322 evf_add_notice( $message, 'success' );
323 }
324
325 return $response_data;
326 }
327 evf_add_notice( $message, 'success' );
328
329 do_action( 'everest_forms_after_success_message', $this->form_data, $entry );
330
331 $this->entry_confirmation_redirect( $this->form_data );
332 }
333
334 /**
335 * Process AJAX form submission.
336 *
337 * @since 1.6.0
338 *
339 * @param mixed $posted_data Posted data.
340 */
341 public function ajax_form_submission( $posted_data ) {
342 add_filter( 'wp_redirect', array( $this, 'ajax_process_redirect' ), 999 );
343 $process = $this->do_task( stripslashes_deep( $posted_data ) );
344 return $process;
345 }
346
347 /**
348 * Process AJAX redirect.
349 *
350 * @since 1.6.0
351 *
352 * @param string $url Redirect URL.
353 */
354 public function ajax_process_redirect( $url ) {
355
356 $form_id = isset( $_POST['everest_forms']['id'] ) ? absint( $_POST['everest_forms']['id'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification
357
358 if ( empty( $form_id ) ) {
359 wp_send_json_error();
360 }
361
362 $response = array(
363 'form_id' => $form_id,
364 'redirect_url' => $url,
365 );
366
367 $response = apply_filters( 'everest_forms_ajax_submit_redirect', $response, $form_id, $url );
368
369 do_action( 'everest_forms_ajax_submit_completed', $form_id, $response );
370
371 wp_send_json_success( $response );
372 }
373
374 /**
375 * Check the sucessful message.
376 *
377 * @param bool $status Message status.
378 * @param int $form_id Form ID.
379 */
380 public function check_success_message( $status, $form_id ) {
381 if ( isset( $this->form_data['id'] ) && absint( $this->form_data['id'] ) === $form_id ) {
382 return true;
383 }
384 return false;
385 }
386
387 /**
388 * Validate the form return hash.
389 *
390 * @since 1.0.0
391 * @param string $hash Hash data.
392 * @return mixed false for invalid or form id.
393 */
394 public function validate_return_hash( $hash = '' ) {
395 $query_args = base64_decode( $hash );
396
397 parse_str( $query_args, $output );
398
399 // Verify hash matches.
400 if ( wp_hash( $output['form_id'] . ',' . $output['entry_id'] ) !== $output['hash'] ) {
401 return false;
402 }
403
404 // Get lead and verify it is attached to the form we received with it.
405 $entry = evf()->entry->get( $output['entry_id'] );
406
407 if ( $output['form_id'] !== $entry->form_id ) {
408 return false;
409 }
410
411 return absint( $output['form_id'] );
412 }
413
414 /**
415 * Redirects user to a page or URL specified in the form confirmation settings.
416 *
417 * @since 1.0.0
418 *
419 * @param array $form_data Form data and settings.
420 * @param string $hash Hash data.
421 */
422 public function entry_confirmation_redirect( $form_data = '', $hash = '' ) {
423 $_POST = array(); // clear fields after successful form submission.
424
425 if ( ! empty( $hash ) ) {
426 $form_id = $this->validate_return_hash( $hash );
427
428 if ( ! $form_id ) {
429 return;
430 }
431
432 // Get form.
433 $this->form_data = evf()->form->get(
434 $form_id,
435 array(
436 'content_only' => true,
437 )
438 );
439 } else {
440 $this->form_data = $form_data;
441 }
442
443 $settings = $this->form_data['settings'];
444
445 // Backward Compatibility Check.
446 switch ( $settings['redirect_to'] ) {
447 case '0':
448 $settings['redirect_to'] = 'same';
449 break;
450
451 case '1':
452 $settings['redirect_to'] = 'custom_page';
453 break;
454
455 case '2':
456 $settings['redirect_to'] = 'external_url';
457 break;
458 }
459
460 if ( isset( $settings['redirect_to'] ) && 'custom_page' === $settings['redirect_to'] ) {
461 ?>
462 <script>
463 var redirect = '<?php echo esc_url( get_page_link( $settings['custom_page'] ) ); ?>';
464 window.setTimeout( function () {
465 window.location.href = redirect;
466 })
467 </script>
468 <?php
469 } elseif ( isset( $settings['redirect_to'] ) && 'external_url' === $settings['redirect_to'] ) {
470 ?>
471 <script>
472 window.setTimeout( function () {
473 window.location.href = '<?php echo esc_url( $settings['external_url'] ); ?>';
474 })
475 </script>
476 <?php
477 }
478
479 // Redirect if needed, to either a page or URL, after form processing.
480 if ( ! empty( $this->form_data['settings']['confirmation_type'] ) && 'message' !== $this->form_data['settings']['confirmation_type'] ) {
481 if ( 'redirect' === $this->form_data['settings']['confirmation_type'] ) {
482 $url = apply_filters( 'everest_forms_process_smart_tags', $this->form_data['settings']['confirmation_redirect'], $this->form_data, $this->form_fields, $this->entry_id );
483 }
484
485 if ( 'page' === $this->form_data['settings']['confirmation_type'] ) {
486 $url = get_permalink( (int) $this->form_data['settings']['confirmation_page'] );
487 }
488 }
489
490 if ( ! empty( $this->form_data['id'] ) ) {
491 $form_id = $this->form_data['id'];
492 } else {
493 return;
494 }
495
496 if ( isset( $settings['submission_message_scroll'] ) && $settings['submission_message_scroll'] ) {
497 add_filter( 'everest_forms_success_notice_class', array( $this, 'add_scroll_notice_class' ) );
498 }
499
500 if ( ! empty( $url ) ) {
501 $url = apply_filters( 'everest_forms_process_redirect_url', $url, $form_id, $this->form_fields );
502 wp_safe_redirect( esc_url_raw( $url ) );
503 do_action( 'everest_forms_process_redirect', $form_id );
504 do_action( "everest_forms_process_redirect_{$form_id}", $form_id );
505 exit;
506 }
507 }
508
509 /**
510 * Add scroll notice class.
511 *
512 * @param array $classes Notice Classes.
513 * @return array of notice classes.
514 */
515 public function add_scroll_notice_class( $classes ) {
516 $classes[] = 'everest-forms-submission-scroll';
517
518 return $classes;
519 }
520
521 /**
522 * Sends entry email notifications.
523 *
524 * @param array $fields List of fields.
525 * @param array $entry Submitted form entry.
526 * @param array $form_data Form data and settings.
527 * @param int $entry_id Saved entry id.
528 * @param string $context In which context this email is sent.
529 */
530 public function entry_email( $fields, $entry, $form_data, $entry_id, $context = '' ) {
531 // Provide the opportunity to override via a filter.
532 if ( ! apply_filters( 'everest_forms_entry_email', true, $fields, $entry, $form_data ) ) {
533 return;
534 }
535
536 // Don't proceed if email notification is not enabled.
537 if ( isset( $form_data['settings']['email']['enable_email_notification'] ) && '1' !== $form_data['settings']['email']['enable_email_notification'] ) {
538 return;
539 }
540
541 // Make sure we have an entry id.
542 if ( empty( $this->entry_id ) ) {
543 $this->entry_id = (int) $entry_id;
544 }
545
546 $fields = apply_filters( 'everest_forms_entry_email_data', $fields, $entry, $form_data );
547
548 if ( ! isset( $form_data['settings']['email']['connection_1'] ) ) {
549 $old_email_data = $form_data['settings']['email'];
550 $form_data['settings']['email'] = array();
551 $form_data['settings']['email']['connection_1'] = array( 'connection_name' => __( 'Admin Notification', 'everest-forms' ) );
552
553 $email_settings = array( 'evf_to_email', 'evf_from_name', 'evf_from_email', 'evf_reply_to', 'evf_email_subject', 'evf_email_message', 'attach_pdf_to_admin_email', 'show_header_in_attachment_pdf_file', 'conditional_logic_status', 'conditional_option', 'conditionals' );
554 foreach ( $email_settings as $email_setting ) {
555 $form_data['settings']['email']['connection_1'][ $email_setting ] = isset( $old_email_data[ $email_setting ] ) ? $old_email_data[ $email_setting ] : '';
556 }
557 }
558
559 $notifications = isset( $form_data['settings']['email'] ) ? $form_data['settings']['email'] : array();
560
561 foreach ( $notifications as $connection_id => $notification ) :
562 $process_email = apply_filters( 'everest_forms_entry_email_process', true, $fields, $form_data, $context, $connection_id );
563
564 if ( ! $process_email ) {
565 continue;
566 }
567
568 $email = array();
569 $evf_to_email = isset( $notification['evf_to_email'] ) ? $notification['evf_to_email'] : '';
570
571 // Setup email properties.
572 /* translators: %s - form name. */
573 $email['subject'] = ! empty( $notification['evf_email_subject'] ) ? $notification['evf_email_subject'] : sprintf( esc_html__( 'New %s Entry', 'everest-forms' ), $form_data['settings']['form_title'] );
574 $email['address'] = explode( ',', apply_filters( 'everest_forms_process_smart_tags', $evf_to_email, $form_data, $fields, $this->entry_id ) );
575 $email['address'] = array_map( 'sanitize_email', $email['address'] );
576 $email['sender_name'] = ! empty( $notification['evf_from_name'] ) ? $notification['evf_from_name'] : get_bloginfo( 'name' );
577 $email['sender_address'] = ! empty( $notification['evf_from_email'] ) ? $notification['evf_from_email'] : get_option( 'admin_email' );
578 $email['reply_to'] = ! empty( $notification['evf_reply_to'] ) ? $notification['evf_reply_to'] : $email['sender_address'];
579 $email['message'] = ! empty( $notification['evf_email_message'] ) ? $notification['evf_email_message'] : '{all_fields}';
580 $email = apply_filters( 'everest_forms_entry_email_atts', $email, $fields, $entry, $form_data );
581
582 $attachment = '';
583
584 // Create new email.
585 $emails = new EVF_Emails();
586 $emails->__set( 'form_data', $form_data );
587 $emails->__set( 'fields', $fields );
588 $emails->__set( 'entry_id', $entry_id );
589 $emails->__set( 'from_name', $email['sender_name'] );
590 $emails->__set( 'from_address', $email['sender_address'] );
591 $emails->__set( 'reply_to', $email['reply_to'] );
592 $emails->__set( 'attachments', apply_filters( 'everest_forms_email_file_attachments', $attachment, $entry, $form_data, 'entry-email', $connection_id, $entry_id ) );
593
594 // Maybe include Cc and Bcc email addresses.
595 if ( 'yes' === get_option( 'everest_forms_enable_email_copies' ) ) {
596 if ( ! empty( $notification['evf_carboncopy'] ) ) {
597 $emails->__set( 'cc', $notification['evf_carboncopy'] );
598 }
599 if ( ! empty( $notification['evf_blindcarboncopy'] ) ) {
600 $emails->__set( 'bcc', $notification['evf_blindcarboncopy'] );
601 }
602 }
603
604 $emails = apply_filters( 'everest_forms_entry_email_before_send', $emails );
605
606 // Send entry email.
607 foreach ( $email['address'] as $address ) {
608 $emails->send( trim( $address ), $email['subject'], $email['message'] );
609 }
610
611 endforeach;
612 }
613
614 /**
615 * Saves entry to database.
616 *
617 * @param array $fields List of form fields.
618 * @param array $entry User submitted data.
619 * @param int $form_id Form ID.
620 * @param array $form_data Prepared form settings.
621 * @return int
622 */
623 public function entry_save( $fields, $entry, $form_id, $form_data = array() ) {
624 global $wpdb;
625
626 // Check if form has entries disabled.
627 if ( isset( $form_data['settings']['disabled_entries'] ) && '1' === $form_data['settings']['disabled_entries'] ) {
628 return;
629 }
630
631 // Provide the opportunity to override via a filter.
632 if ( ! apply_filters( 'everest_forms_entry_save', true, $fields, $entry, $form_data ) ) {
633 return;
634 }
635
636 do_action( 'everest_forms_process_entry_save', $fields, $entry, $form_id, $form_data );
637
638 $fields = apply_filters( 'everest_forms_entry_save_data', $fields, $entry, $form_data );
639 $browser = evf_get_browser();
640 $user_ip = evf_get_ip_address();
641 $user_agent = $browser['name'] . '/' . $browser['platform'];
642 $referer = ! empty( $_SERVER['HTTP_REFERER'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_REFERER'] ) ) : '';
643 $entry_id = false;
644
645 // GDPR enhancements - If user details are disabled globally discard the IP and UA.
646 if ( 'yes' === get_option( 'everest_forms_disable_user_details' ) ) {
647 $user_agent = '';
648 $user_ip = '';
649 }
650
651 $entry_data = array(
652 'form_id' => $form_id,
653 'user_id' => get_current_user_id(),
654 'user_device' => sanitize_text_field( $user_agent ),
655 'user_ip_address' => sanitize_text_field( $user_ip ),
656 'status' => 'publish',
657 'referer' => $referer,
658 'fields' => wp_json_encode( $fields ),
659 'date_created' => current_time( 'mysql', true ),
660 );
661
662 if ( ! $entry_data['form_id'] ) {
663 return new WP_Error( 'no-form-id', __( 'No form ID was found.', 'everest-forms' ) );
664 }
665
666 // Create entry.
667 $success = $wpdb->insert( $wpdb->prefix . 'evf_entries', $entry_data );
668
669 if ( is_wp_error( $success ) || ! $success ) {
670 return new WP_Error( 'could-not-create', __( 'Could not create an entry', 'everest-forms' ) );
671 }
672
673 $entry_id = $wpdb->insert_id;
674
675 // Create meta data.
676 if ( $entry_id ) {
677 foreach ( $fields as $field ) {
678 $field = apply_filters( 'everest_forms_entry_save_fields', $field, $form_data, $entry_id );
679 // Add only whitelisted fields to entry meta.
680 if ( in_array( $field['type'], array( 'html', 'title' ), true ) ) {
681 continue;
682 }
683
684 // If empty file is supplied, don't store their data nor send email.
685 if ( in_array( $field['type'], array( 'image-upload', 'file-upload' ), true ) ) {
686
687 // BW compatibility for previous file uploader.
688 if ( isset( $field['value']['file_url'] ) && '' === $field['value']['file_url'] ) {
689 continue;
690 }
691 }
692
693 // If empty label is provided for choice field, don't store their data nor send email.
694 if ( in_array( $field['type'], array( 'radio', 'payment-multiple' ), true ) ) {
695 if ( isset( $field['value']['label'] ) && '' === $field['value']['label'] ) {
696 continue;
697 }
698 } elseif ( in_array( $field['type'], array( 'checkbox', 'payment-checkbox' ), true ) ) {
699 if ( isset( $field['value']['label'] ) && ( empty( $field['value']['label'] ) || '' === current( $field['value']['label'] ) ) ) {
700 continue;
701 }
702 }
703
704 if ( isset( $field['meta_key'], $field['value'] ) && '' !== $field['value'] ) {
705 $entry_metadata = array(
706 'entry_id' => $entry_id,
707 'meta_key' => sanitize_key( $field['meta_key'] ),
708 'meta_value' => maybe_serialize( $field['value'] ), // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
709 );
710
711 // Insert entry meta.
712 $wpdb->insert( $wpdb->prefix . 'evf_entrymeta', $entry_metadata );
713 }
714 }
715 }
716
717 $this->entry_id = $entry_id;
718
719 do_action( 'everest_forms_complete_entry_save', $entry_id, $fields, $entry, $form_id, $form_data );
720
721 return $this->entry_id;
722 }
723 }
724