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 / class-evf-emails.php
everest-forms / includes Last commit date
abstracts 2 years ago admin 2 years ago elementor 4 years ago export 3 years ago fields 2 years ago interfaces 8 years ago libraries 2 years ago log-handlers 4 years ago shortcodes 2 years ago stats 3 years ago templates 5 years ago class-everest-forms.php 2 years ago class-evf-ajax.php 2 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-cron.php 3 years ago class-evf-deprecated-action-hooks.php 6 years ago class-evf-deprecated-filter-hooks.php 5 years ago class-evf-emails.php 2 years ago class-evf-fields.php 2 years ago class-evf-form-block.php 4 years ago class-evf-form-handler.php 3 years ago class-evf-form-task.php 2 years ago class-evf-forms-features.php 2 years ago class-evf-frontend-scripts.php 2 years ago class-evf-install.php 2 years ago class-evf-integrations.php 7 years ago class-evf-log-levels.php 8 years ago class-evf-logger.php 5 years ago class-evf-post-types.php 5 years ago class-evf-privacy.php 6 years ago class-evf-session-handler.php 7 years ago class-evf-shortcodes.php 4 years ago class-evf-smart-tags.php 2 years ago class-evf-template-loader.php 2 years ago class-evf-validation.php 6 years ago evf-conditional-functions.php 6 years ago evf-core-functions.php 2 years ago evf-deprecated-functions.php 6 years ago evf-entry-functions.php 3 years ago evf-formatting-functions.php 4 years ago evf-notice-functions.php 4 years ago evf-template-functions.php 4 years ago evf-template-hooks.php 7 years ago evf-update-functions.php 5 years ago
class-evf-emails.php
623 lines
1 <?php
2 /**
3 * This class handles all (notification) emails sent by Everest Forms.
4 *
5 * Heavily influenced by the great AffiliateWP plugin by Pippin Williamson.
6 * https://github.com/AffiliateWP/AffiliateWP/blob/master/includes/emails/class-affwp-emails.php
7 *
8 * @package EverestForms\Classes\Emails
9 * @version 1.2.0
10 * @since 1.0.0
11 */
12
13 defined( 'ABSPATH' ) || exit;
14
15 /**
16 * Email class.
17 */
18 class EVF_Emails {
19
20 /**
21 * Holds the from address.
22 *
23 * @var string
24 */
25 private $from_address;
26
27 /**
28 * Holds the from name.
29 *
30 * @var string
31 */
32 private $from_name;
33
34 /**
35 * Holds the reply-to address.
36 *
37 * @var string
38 */
39 private $reply_to = false;
40
41 /**
42 * Holds the carbon copy addresses.
43 *
44 * @var string
45 */
46 private $cc = false;
47
48 /**
49 * Holds the blind carbon copy addresses.
50 *
51 * @var string
52 */
53 private $bcc = false;
54
55 /**
56 * Holds the email content type.
57 *
58 * @var string
59 */
60 private $content_type;
61
62 /**
63 * Holds the email headers.
64 *
65 * @var string
66 */
67 private $headers;
68
69 /**
70 * Holds the email attachments.
71 *
72 * @var string
73 */
74 public $attachments = '';
75
76 /**
77 * Whether to send email in HTML.
78 *
79 * @var bool
80 */
81 private $html = true;
82
83 /**
84 * The email template to use.
85 *
86 * @var string
87 */
88 private $template;
89
90 /**
91 * Form data.
92 *
93 * @var array
94 */
95 public $form_data = array();
96
97 /**
98 * Fields, formatted, and sanitized.
99 *
100 * @var array
101 */
102 public $fields = array();
103
104 /**
105 * Entry ID.
106 *
107 * @var int
108 */
109 public $entry_id = '';
110
111 /**
112 * Constructor.
113 */
114 public function __construct() {
115 if ( 'none' === $this->get_template() ) {
116 $this->html = false;
117 }
118
119 // Hooks.
120 add_action( 'everest_forms_email_send_before', array( $this, 'send_before' ) );
121 add_action( 'everest_forms_email_send_after', array( $this, 'send_after' ) );
122 }
123
124 /**
125 * Set a property.
126 *
127 * @param string $key Object property key.
128 * @param mixed $value Object property value.
129 */
130 public function __set( $key, $value ) {
131 $this->$key = $value;
132 }
133
134 /**
135 * Get the email from name.
136 *
137 * @return string The email from name.
138 */
139 public function get_from_name() {
140 if ( ! empty( $this->from_name ) ) {
141 $this->from_name = $this->process_tag( $this->from_name );
142 } else {
143 $this->from_name = get_bloginfo( 'name' );
144 }
145
146 return apply_filters( 'everest_forms_email_from_name', wp_specialchars_decode( $this->from_name ), $this );
147 }
148
149 /**
150 * Get the email from address.
151 *
152 * @return string The email from address.
153 */
154 public function get_from_address() {
155 if ( ! empty( $this->from_address ) ) {
156 $this->from_address = $this->process_tag( $this->from_address );
157 } else {
158 $this->from_address = get_option( 'admin_email' );
159 }
160
161 return apply_filters( 'everest_forms_email_from_address', $this->from_address, $this );
162 }
163
164 /**
165 * Get the email reply-to.
166 *
167 * @return string The email reply-to address.
168 */
169 public function get_reply_to() {
170 if ( ! empty( $this->reply_to ) ) {
171 $this->reply_to = $this->process_tag( $this->reply_to );
172
173 if ( ! is_email( $this->reply_to ) ) {
174 $this->reply_to = false;
175 }
176 }
177
178 return apply_filters( 'everest_forms_email_reply_to', $this->reply_to, $this );
179 }
180
181 /**
182 * Get the email carbon copy addresses.
183 *
184 * @return string The email carbon copy addresses.
185 */
186 public function get_cc() {
187 if ( ! empty( $this->cc ) ) {
188 $this->cc = $this->process_tag( $this->cc );
189 $addresses = array_map( 'trim', explode( ',', $this->cc ) );
190
191 foreach ( $addresses as $key => $address ) {
192 if ( ! is_email( $address ) ) {
193 unset( $addresses[ $key ] );
194 }
195 }
196
197 $this->cc = implode( ',', $addresses );
198 }
199
200 return apply_filters( 'everest_forms_email_cc', $this->cc, $this );
201 }
202
203 /**
204 * Get the email blind carbon copy addresses.
205 *
206 * @return string The email blind carbon copy addresses.
207 */
208 public function get_bcc() {
209 if ( ! empty( $this->bcc ) ) {
210 $this->bcc = $this->process_tag( $this->bcc );
211 $addresses = array_map( 'trim', explode( ',', $this->bcc ) );
212
213 foreach ( $addresses as $key => $address ) {
214 if ( ! is_email( $address ) ) {
215 unset( $addresses[ $key ] );
216 }
217 }
218
219 $this->bcc = implode( ',', $addresses );
220 }
221
222 return apply_filters( 'everest_forms_email_bcc', $this->bcc, $this );
223 }
224
225 /**
226 * Get the email content type.
227 *
228 * @return string The email content type.
229 */
230 public function get_content_type() {
231 if ( ! $this->content_type && $this->html ) {
232 $this->content_type = apply_filters( 'everest_forms_email_default_content_type', 'text/html', $this );
233 } elseif ( ! $this->html ) {
234 $this->content_type = 'text/plain';
235 }
236
237 return apply_filters( 'everest_forms_email_content_type', $this->content_type, $this );
238 }
239
240 /**
241 * Get the email headers.
242 *
243 * @return string The email headers.
244 */
245 public function get_headers() {
246 if ( ! $this->headers ) {
247 $this->headers = "From: {$this->get_from_name()} <{$this->get_from_address()}>\r\n";
248 if ( $this->get_reply_to() ) {
249 $this->headers .= "Reply-To: {$this->get_reply_to()}\r\n";
250 }
251 if ( $this->get_cc() ) {
252 $this->headers .= "Cc: {$this->get_cc()}\r\n";
253 }
254 if ( $this->get_bcc() ) {
255 $this->headers .= "Bcc: {$this->get_bcc()}\r\n";
256 }
257 $this->headers .= "Content-Type: {$this->get_content_type()}; charset=utf-8\r\n";
258 }
259
260 return apply_filters( 'everest_forms_email_headers', $this->headers, $this );
261 }
262
263 /**
264 * Build the email.
265 *
266 * @param string $message The email message.
267 * @return string
268 */
269 public function build_email( $message ) {
270 if ( false === $this->html ) {
271 $message = $this->process_tag( $message, false, true );
272 $message = str_replace( '{all_fields}', $this->everest_forms_html_field_value( false ), $message );
273
274 return apply_filters( 'everest_forms_email_message', $message, $this );
275 }
276
277 ob_start();
278
279 evf_get_template( 'emails/header-' . $this->get_template() . '.php' );
280
281 // Hooks into the email header.
282 do_action( 'everest_forms_email_header', $this );
283
284 evf_get_template( 'emails/body-' . $this->get_template() . '.php' );
285
286 // Hooks into the email body.
287 do_action( 'everest_forms_email_body', $this );
288
289 evf_get_template( 'emails/footer-' . $this->get_template() . '.php' );
290
291 // Hooks into the email footer.
292 do_action( 'everest_forms_email_footer', $this );
293
294 $message = $this->process_tag( $message, false );
295 $message = nl2br( $message );
296
297 $body = ob_get_clean();
298 $message = str_replace( '{email}', $message, $body );
299 $message = str_replace( '{all_fields}', $this->everest_forms_html_field_value( true ), $message );
300 $message = make_clickable( $message );
301
302 return apply_filters( 'everest_forms_email_message', $message, $this );
303 }
304
305 /**
306 * Send the email.
307 *
308 * @param string $to The To address.
309 * @param string $subject The subject line of the email.
310 * @param string $message The body of the email.
311 * @param array $attachments Attachments to the email.
312 * @param string $connection_id Connection ID of the email.
313 *
314 * @return bool
315 */
316 public function send( $to, $subject, $message, $attachments = '', $connection_id = '' ) {
317 if ( ! did_action( 'init' ) && ! did_action( 'admin_init' ) ) {
318 evf_doing_it_wrong( __FUNCTION__, __( 'You cannot send emails with EVF_Emails until init/admin_init has been reached', 'everest-forms' ), null );
319 return false;
320 }
321
322 // Don't send anything if emails have been disabled.
323 if ( $this->is_email_disabled() ) {
324 return false;
325 }
326
327 // Don't send if email address is invalid.
328 if ( ! is_email( $to ) ) {
329 return false;
330 }
331
332 // Hooks before email is sent.
333 do_action( 'everest_forms_email_send_before', $this );
334
335 $message = apply_filters( 'everest_forms_entry_email__message', str_replace( '{entry_id}', absint( $this->entry_id ), $message ), $this );
336
337 // Email Template Enabled or not checked.
338 $email_template_included = ! empty( $this->form_data['settings']['email'][ $connection_id ]['choose_template'] ) ? true : false;
339
340 if ( $email_template_included && true === $this->html ) {
341 $message = apply_filters( 'everest_forms_email_template_message', $message, $this, $connection_id );
342 } else {
343 $message = $this->build_email( $message );
344 }
345 $this->attachments = apply_filters( 'everest_forms_email_attachments', $this->attachments, $this );
346 $subject = evf_decode_string( $this->process_tag( $subject ) );
347
348 // Let's do this.
349 $sent = wp_mail( $to, $subject, $message, $this->get_headers(), $this->attachments );
350
351 // Hooks after the email is sent.
352 do_action( 'everest_forms_email_send_after', $this );
353
354 return $sent;
355 }
356
357 /**
358 * Add filters/actions before the email is sent.
359 */
360 public function send_before() {
361 add_filter( 'wp_mail_from', array( $this, 'get_from_address' ) );
362 add_filter( 'wp_mail_from_name', array( $this, 'get_from_name' ) );
363 add_filter( 'wp_mail_content_type', array( $this, 'get_content_type' ) );
364 }
365
366 /**
367 * Remove filters/actions after the email is sent.
368 */
369 public function send_after() {
370 remove_filter( 'wp_mail_from', array( $this, 'get_from_address' ) );
371 remove_filter( 'wp_mail_from_name', array( $this, 'get_from_name' ) );
372 remove_filter( 'wp_mail_content_type', array( $this, 'get_content_type' ) );
373 }
374
375 /**
376 * Converts text formatted HTML. This is primarily for turning line breaks
377 * into <p> and <br/> tags.
378 *
379 * @param string $message Text to convert.
380 * @return string
381 */
382 public function text_to_html( $message ) {
383 if ( 'text/html' === $this->content_type || true === $this->html ) {
384 $message = wpautop( $message );
385 }
386
387 return $message;
388 }
389
390 /**
391 * Processes a smart tag.
392 *
393 * @param string $string String that may contain tags.
394 * @param bool $sanitize Toggle to maybe sanitize.
395 * @param bool $linebreaks Toggle to process linebreaks.
396 *
397 * @return string
398 */
399 public function process_tag( $string = '', $sanitize = true, $linebreaks = false ) {
400 $tag = apply_filters( 'everest_forms_process_smart_tags', $string, $this->form_data, $this->fields, $this->entry_id );
401 $tag = evf_decode_string( $tag );
402
403 if ( $sanitize ) {
404 if ( $linebreaks ) {
405 $tag = evf_sanitize_textarea_field( $tag );
406 } else {
407 $tag = sanitize_text_field( $tag );
408 }
409 }
410
411 return $tag;
412 }
413
414 /**
415 * Process the all fields smart tag if present.
416 *
417 * @param bool $html Toggle to use HTML or plaintext.
418 * @return string
419 */
420 public function everest_forms_html_field_value( $html = true ) {
421 if ( empty( $this->fields ) ) {
422 return '';
423 }
424
425 // Make sure we have an entry id.
426 if ( ! empty( $this->entry_id ) ) {
427 $this->form_data['entry_id'] = (int) $this->entry_id;
428 }
429
430 $message = '';
431
432 if ( $html ) {
433 /*
434 * HTML emails.
435 */
436 ob_start();
437
438 // Hooks into the email field.
439 do_action( 'everest_forms_email_field', $this );
440
441 evf_get_template( 'emails/field-' . $this->get_template() . '.php' );
442
443 $field_template = ob_get_clean();
444 $empty_message = '<em>' . __( '(empty)', 'everest-forms' ) . '</em>';
445
446 $field_iterator = 1;
447 foreach ( $this->fields as $meta_id => $field ) {
448 if (
449 ! apply_filters( 'everest_forms_email_display_empty_fields', false ) &&
450 ( empty( $field['value'] ) && '0' !== $field['value'] )
451 ) {
452 continue;
453 }
454
455 // If empty value is provided for select field, don't send email.
456 if ( 'select' === $field['type'] && empty( $field['value'][0] ) ) {
457 continue;
458 }
459
460 if ( ( 'radio' === $field['type'] && empty( $field['value']['label'] ) ) || ( 'payment-multiple' === $field['type'] && empty( $field['value']['label'] ) ) ) {
461 continue;
462 }
463
464 if ( ( 'checkbox' === $field['type'] && empty( $field['value']['label'][0] ) ) || ( 'payment-checkbox' === $field['type'] && empty( $field['value']['label'] ) ) ) {
465 continue;
466 }
467
468 // If there's the export data filter, utilize that and re-loop promptly.
469 if ( has_filter( "everest_forms_field_exporter_{$field['type']}" ) ) {
470 $formatted_string = apply_filters( "everest_forms_field_exporter_{$field['type']}", $field, 'email-html', 2 );
471 $formatted_string['value'] = false === $formatted_string['value'] ? $empty_message : $formatted_string['value'];
472
473 $field_item = $field_template;
474 if ( 1 === $field_iterator ) {
475 $field_item = str_replace( 'border-top:1px solid #dddddd;', '', $field_item );
476 }
477
478 // Inject the label and value into the email template.
479 $field_item = str_replace( '{field_name}', $formatted_string['label'], $field_item );
480 $field_item = str_replace( '{field_value}', $formatted_string['value'], $field_item );
481
482 $message .= wpautop( $field_item );
483
484 // For BW compatibility reasons.
485 ++$field_iterator;
486 continue;
487 }
488
489 $field_val = empty( $field['value'] ) && '0' !== $field['value'] ? $empty_message : $field['value'];
490 $field_name = isset( $field_val['name'] ) ? $field_val['name'] : $field['name'];
491 $field_label = ! empty( $field_val['label'] ) ? $field_val['label'] : $field_val;
492 $field_type = $field['type'];
493
494 // If empty label is provided for choice field, don't store their data nor send email.
495 if ( in_array( $field_type, array( 'radio', 'payment-multiple' ), true ) ) {
496 if ( isset( $field_val['label'] ) && '' === $field_val['label'] ) {
497 continue;
498 }
499 } elseif ( in_array( $field_type, array( 'checkbox', 'payment-checkbox' ), true ) ) {
500 if ( isset( $field_val['label'] ) && ( empty( $field_val['label'] ) || '' === current( $field_val['label'] ) ) ) {
501 continue;
502 }
503 }
504
505 if ( isset( $field['value'], $field['value_raw'] ) && is_string( $field['value'] ) && in_array( $field_type, array( 'image-upload', 'file-upload' ), true ) ) {
506 $field['value'] = $field;
507 }
508
509 if ( isset( $field_val['type'] ) && in_array( $field['type'], array( 'image-upload', 'file-upload', 'rating' ), true ) ) {
510 if ( 'rating' === $field_val['type'] ) {
511 $value = ! empty( $field_val['value'] ) ? $field_val['value'] : 0;
512 $number_of_stars = ! empty( $field_val['number_of_rating'] ) ? $field_val['number_of_rating'] : 5;
513 $field_val = $value . '/' . $number_of_stars;
514 } else {
515 $field_val = empty( $field_val['file_url'] ) ? $empty_message : $field_val;
516 }
517 }
518
519 if ( 'rating' !== $field_type ) {
520 if ( is_array( $field_label ) ) {
521 $field_html = array();
522 foreach ( $field_label as $meta_val ) {
523 $field_html[] = esc_html( $meta_val );
524 }
525 $field_val = implode( ', ', $field_html );
526 } else {
527 $field_val = esc_html( $field_label );
528 }
529 }
530
531 if ( empty( $field_name ) ) {
532 $field_name = sprintf(
533 /* translators: %d - field ID. */
534 esc_html__( 'Field ID #%d', 'everest-forms' ),
535 absint( $field['id'] )
536 );
537 }
538
539 $field_item = $field_template;
540 if ( 1 === $field_iterator ) {
541 $field_item = str_replace( 'border-top:1px solid #dddddd;', '', $field_item );
542 }
543
544 $field_item = str_replace( '{field_name}', $field_name, $field_item );
545 $field_value = apply_filters( 'everest_forms_html_field_value', evf_decode_string( $field_val ), $field['value'], $this->form_data, 'email-html', $field );
546 $field_item = str_replace( '{field_value}', $field_value, $field_item );
547
548 $message .= wpautop( $field_item );
549 ++$field_iterator;
550 }
551 } else {
552 /*
553 * Plain Text emails.
554 */
555 foreach ( $this->fields as $field ) {
556 if ( ! apply_filters( 'everest_forms_email_display_empty_fields', false ) && ( empty( $field['value'] ) && '0' !== $field['value'] ) ) {
557 continue;
558 }
559
560 $field_val = empty( $field['value'] ) && '0' !== $field['value'] ? esc_html__( '(empty)', 'everest-forms' ) : $field['value'];
561 $field_name = isset( $field['name'] ) ? $field['name'] : '';
562
563 if ( is_array( $field_val ) ) {
564 $field_html = array();
565
566 foreach ( $field_val as $meta_val ) {
567 $field_html[] = $meta_val;
568 }
569
570 if ( ! empty( $field_html ) && is_array( $field_html ) ) {
571 $field_val = implode( ', ', $field_html );
572 } else {
573 $field_val = '';
574 }
575 }
576
577 if ( empty( $field_name ) ) {
578 $field_name = sprintf(
579 /* translators: %d - field ID. */
580 esc_html__( 'Field ID #%d', 'everest-forms' ),
581 absint( $field['id'] )
582 );
583 }
584
585 $message .= '--- ' . evf_decode_string( $field_name ) . " ---\r\n\r\n";
586 $field_value = evf_decode_string( $field_val ) . "\r\n\r\n";
587 $message .= apply_filters( 'everest_forms_plaintext_field_value', $field_value, $field['value'], $this->form_data, 'email-plain' );
588 }
589 }
590
591 if ( empty( $message ) ) {
592 $empty_message = esc_html__( 'An empty form was submitted.', 'everest-forms' );
593 $message = $html ? wpautop( $empty_message ) : $empty_message;
594 }
595
596 return $message;
597 }
598
599 /**
600 * Email kill switch if needed.
601 *
602 * @return bool
603 */
604 public function is_email_disabled() {
605 return (bool) apply_filters( 'everest_forms_disable_all_emails', false, $this );
606 }
607
608 /**
609 * Get the enabled email template.
610 *
611 * @todo Email template.
612 *
613 * @return string When filtering return 'none' to switch to text/plain email.
614 */
615 public function get_template() {
616 if ( ! $this->template ) {
617 $this->template = get_option( 'everest_forms_email_template', 'default' );
618 }
619
620 return apply_filters( 'everest_forms_email_template', $this->template );
621 }
622 }
623