PluginProbe ʕ •ᴥ•ʔ
WPForms – Easy Form Builder for WordPress – Contact Forms, Payment Forms, Surveys, & More / 1.10.0.1
WPForms – Easy Form Builder for WordPress – Contact Forms, Payment Forms, Surveys, & More v1.10.0.1
1.10.1.1 1.10.1 1.10.0.5 trunk 1.1.4 1.1.4.2 1.1.5 1.1.5.1 1.1.6 1.1.6.1 1.1.7 1.1.7.1 1.1.7.2 1.1.8 1.1.8.1 1.1.8.2 1.1.8.3 1.1.8.4 1.10.0.1 1.10.0.2 1.10.0.3 1.10.0.4 1.2.0 1.2.0.1 1.2.1 1.2.2 1.2.2.1 1.2.2.2 1.2.3 1.2.3.1 1.2.3.2 1.2.4 1.2.4.1 1.2.5 1.2.5.1 1.2.6 1.2.7 1.2.8 1.2.8.1 1.2.9 1.3.0 1.3.1 1.3.1.1 1.3.1.2 1.3.2 1.3.3 1.3.5 1.3.6 1.3.6.1 1.3.6.2 1.3.7.2 1.3.7.3 1.3.7.4 1.3.8 1.3.9.1 1.4.0.1 1.4.1.1 1.4.2 1.4.2.1 1.4.2.2 1.4.3 1.4.4 1.4.4.1 1.4.5 1.4.5.1 1.4.5.2 1.4.5.3 1.4.6 1.4.7.1 1.4.7.2 1.4.8.1 1.4.9 1.5.0.1 1.5.0.3 1.5.0.4 1.5.1 1.5.1.1 1.5.1.3 1.5.2.1 1.5.2.2 1.5.2.3 1.5.3 1.5.3.1 1.5.4.1 1.5.4.2 1.5.5 1.5.5.1 1.5.6 1.5.6.2 1.5.7 1.5.8.2 1.5.9.1 1.5.9.4 1.5.9.5 1.6.0.1 1.6.0.2 1.6.1 1.6.2.2 1.6.2.3 1.6.3.1 1.6.4 1.6.4.1 1.6.5 1.6.6 1.6.7 1.6.7.1 1.6.7.2 1.6.7.3 1.6.8 1.6.8.1 1.6.9 1.7.0 1.7.1.1 1.7.1.2 1.7.2 1.7.2.1 1.7.3 1.7.4 1.7.4.1 1.7.4.2 1.7.5.1 1.7.5.2 1.7.5.3 1.7.5.5 1.7.6 1.7.7 1.7.7.1 1.7.7.2 1.7.8 1.7.9 1.7.9.1 1.8.0.1 1.8.0.2 1.8.1.1 1.8.1.2 1.8.1.3 1.8.2.1 1.8.2.2 1.8.2.3 1.8.3 1.8.3.1 1.8.4 1.8.4.1 1.8.5.2 1.8.5.3 1.8.5.4 1.8.6.2 1.8.6.3 1.8.6.4 1.8.7.2 1.8.8.2 1.8.8.3 1.8.9.1 1.8.9.2 1.8.9.4 1.8.9.5 1.8.9.6 1.9.0.1 1.9.0.2 1.9.0.3 1.9.0.4 1.9.1.1 1.9.1.2 1.9.1.3 1.9.1.4 1.9.1.5 1.9.1.6 1.9.2.1 1.9.2.2 1.9.2.3 1.9.3.1 1.9.3.2 1.9.4.1 1.9.4.2 1.9.5 1.9.5.1 1.9.5.2 1.9.6 1.9.6.1 1.9.6.2 1.9.7.1 1.9.7.2 1.9.7.3 1.9.8.1 1.9.8.2 1.9.8.4 1.9.8.7 1.9.9.2 1.9.9.3 1.9.9.4
wpforms-lite / src / Emails / Mailer.php
wpforms-lite / src / Emails Last commit date
Tasks 8 months ago Templates 2 years ago Helpers.php 2 years ago InfoBlocks.php 1 year ago Mailer.php 4 months ago NotificationBlocks.php 1 year ago Notifications.php 2 months ago Preview.php 10 months ago Styler.php 2 years ago Summaries.php 8 months ago
Mailer.php
627 lines
1 <?php
2
3 namespace WPForms\Emails;
4
5 use WPForms\Emails\Templates\General;
6
7 /**
8 * Mailer class to wrap wp_mail().
9 *
10 * @since 1.5.4
11 */
12 class Mailer {
13
14 /**
15 * Array or comma-separated list of email addresses to send a message.
16 *
17 * @since 1.5.4
18 *
19 * @var string|string[]
20 */
21 private $to_email;
22
23 /**
24 * CC addresses (comma delimited).
25 *
26 * @since 1.5.4
27 *
28 * @var string
29 */
30 private $cc;
31
32 /**
33 * From address.
34 *
35 * @since 1.5.4
36 *
37 * @var string
38 */
39 private $from_address = '';
40
41 /**
42 * From name.
43 *
44 * @since 1.5.4
45 *
46 * @var string
47 */
48 private $from_name;
49
50 /**
51 * Reply to address.
52 *
53 * @since 1.5.4
54 *
55 * @var string
56 */
57 private $reply_to;
58
59 /**
60 * Email headers.
61 *
62 * @since 1.5.4
63 *
64 * @var string
65 */
66 private $headers;
67
68 /**
69 * Email content type.
70 *
71 * @since 1.5.4
72 *
73 * @var string
74 */
75 private $content_type;
76
77 /**
78 * Email attachments.
79 *
80 * @since 1.5.4
81 *
82 * @var string|string[]
83 */
84 private $attachments;
85
86 /**
87 * Email subject.
88 *
89 * @since 1.5.4
90 *
91 * @var string
92 */
93 private $subject;
94
95 /**
96 * Email message.
97 *
98 * @since 1.5.4
99 *
100 * @var string
101 */
102 private $message;
103
104 /**
105 * Email template.
106 *
107 * @since 1.5.4
108 *
109 * @var General
110 */
111 private $template;
112
113 /**
114 * Set a property.
115 *
116 * @since 1.5.4
117 *
118 * @param string $key Property name.
119 * @param string|array $value Property value.
120 */
121 public function __set( string $key, $value ) {
122
123 $this->$key = $value;
124 }
125
126 /**
127 * Get a property.
128 *
129 * @since 1.5.4
130 *
131 * @param string $key Property name.
132 *
133 * @return string
134 */
135 public function __get( $key ) {
136
137 return $this->$key;
138 }
139
140 /**
141 * Check if a property exists.
142 *
143 * @since 1.5.4
144 *
145 * @param string $key Property name.
146 *
147 * @return bool
148 */
149 public function __isset( $key ) {
150
151 return isset( $this->key );
152 }
153
154 /**
155 * Unset a property.
156 *
157 * @since 1.5.4
158 *
159 * @param string $key Property name.
160 */
161 public function __unset( $key ) {
162
163 unset( $this->key );
164 }
165
166 /**
167 * Email kill switch if needed.
168 *
169 * @since 1.5.4
170 *
171 * @return bool
172 */
173 public function is_email_disabled() {
174
175 // phpcs:ignore WPForms.Comments.PHPDocHooks.RequiredHookDocumentation
176 return (bool) apply_filters( 'wpforms_emails_mailer_is_email_disabled', false, $this );
177 }
178
179 /**
180 * Sanitize the string.
181 *
182 * @since 1.5.4
183 * @since 1.6.0 Deprecated param: $linebreaks. This is handled by wpforms_decode_string().
184 *
185 * @param string $input String that may contain tags.
186 * @param string $context Context of the string.
187 *
188 * @return string
189 * @uses wpforms_decode_string()
190 */
191 public function sanitize( $input = '', $context = '' ): string { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed
192
193 return wpforms_decode_string( $input );
194 }
195
196 /**
197 * Get the email from the name.
198 *
199 * @since 1.5.4
200 *
201 * @return string
202 */
203 public function get_from_name() {
204
205 $this->from_name = $this->from_name ? $this->sanitize( $this->from_name ) : get_bloginfo( 'name' );
206
207 // phpcs:ignore WPForms.Comments.PHPDocHooks.RequiredHookDocumentation
208 return apply_filters( 'wpforms_emails_mailer_get_from_name', $this->from_name, $this );
209 }
210
211 /**
212 * Get the email from the address.
213 *
214 * @since 1.5.4
215 *
216 * @return string
217 */
218 public function get_from_address() {
219
220 $from_address = $this->sanitize( $this->from_address, 'notification-from' );
221 $from_address = $from_address ? $from_address : get_option( 'admin_email' );
222
223 // phpcs:ignore WPForms.Comments.PHPDocHooks.RequiredHookDocumentation
224 return apply_filters( 'wpforms_emails_mailer_get_from_address', $from_address, $this );
225 }
226
227 /**
228 * Get the email reply to the address.
229 *
230 * @since 1.5.4
231 *
232 * @return string
233 */
234 public function get_reply_to_address() {
235
236 if ( empty( $this->reply_to ) || ! is_email( $this->reply_to ) ) {
237 $this->reply_to = $this->from_address;
238 }
239
240 $this->reply_to = $this->sanitize( $this->reply_to, 'notification-reply-to' );
241
242 if ( empty( $this->reply_to ) || ! is_email( $this->reply_to ) ) {
243 $this->reply_to = get_option( 'admin_email' );
244 }
245
246 // phpcs:ignore WPForms.Comments.PHPDocHooks.RequiredHookDocumentation
247 return apply_filters( 'wpforms_emails_mailer_get_reply_to_address', $this->reply_to, $this );
248 }
249
250 /**
251 * Get the email carbon copy addresses.
252 *
253 * @since 1.5.4
254 * @since 1.8.9 Allow using CC field as an array.
255 *
256 * @return string The email carbon copy addresses.
257 */
258 public function get_cc_address() {
259
260 if ( is_array( $this->cc ) ) {
261 $this->cc = implode( ',', $this->cc );
262 }
263
264 if ( empty( $this->cc ) ) {
265 /**
266 * Filters the email carbon copy addresses.
267 *
268 * @since 1.5.4
269 *
270 * @param string $cc Carbon copy addresses.
271 * @param Mailer $this Mailer instance.
272 */
273 return apply_filters( 'wpforms_emails_mailer_get_cc_address', $this->cc, $this );
274 }
275
276 $this->cc = $this->sanitize( $this->cc );
277
278 $addresses = array_filter( array_map( 'sanitize_email', explode( ',', $this->cc ) ) );
279
280 $this->cc = implode( ',', $addresses );
281
282 /** This filter is documented in src/Emails/Mailer.php. */
283 return apply_filters( 'wpforms_emails_mailer_get_cc_address', $this->cc, $this );
284 }
285
286 /**
287 * Get the email content type.
288 *
289 * @since 1.5.4
290 *
291 * @return string The email content type.
292 */
293 public function get_content_type() {
294
295 $is_html = ! Helpers::is_plain_text_template();
296
297 if ( ! $this->content_type && $is_html ) {
298 // phpcs:ignore WPForms.Comments.PHPDocHooks.RequiredHookDocumentation
299 $this->content_type = apply_filters( 'wpforms_emails_mailer_get_content_type_default', 'text/html', $this );
300 } elseif ( ! $is_html ) {
301 $this->content_type = 'text/plain';
302 }
303
304 // phpcs:ignore WPForms.Comments.PHPDocHooks.RequiredHookDocumentation
305 return apply_filters( 'wpforms_emails_mailer_get_content_type', $this->content_type, $this );
306 }
307
308 /**
309 * Get the email subject.
310 *
311 * @since 1.8.9
312 *
313 * @return string The email subject.
314 */
315 private function get_subject() {
316
317 if ( empty( $this->subject ) ) {
318 $this->subject = __( 'New Email Submit', 'wpforms-lite' );
319 }
320
321 /**
322 * Filters the email subject.
323 *
324 * @since 1.8.9
325 *
326 * @param string $subject Email subject.
327 * @param Mailer $this Mailer instance.
328 */
329 return apply_filters( 'wpforms_emails_mailer_get_subject', $this->subject, $this );
330 }
331
332 /**
333 * Get the email message.
334 *
335 * @since 1.5.4
336 *
337 * @return string The email message.
338 */
339 public function get_message() {
340
341 if ( empty( $this->message ) && ! empty( $this->template ) ) {
342 $this->message = $this->template->get();
343 }
344
345 /**
346 * Filters the email message.
347 *
348 * @since 1.5.4
349 *
350 * @param string $message Email message.
351 * @param Mailer $this Mailer instance.
352 */
353 return apply_filters( 'wpforms_emails_mailer_get_message', $this->message, $this );
354 }
355
356 /**
357 * Get the email headers.
358 *
359 * @since 1.5.4
360 *
361 * @return string The email headers.
362 */
363 public function get_headers() {
364
365 $this->headers = "From: {$this->get_from_name()} <{$this->get_from_address()}>\r\n";
366
367 if ( $this->get_reply_to_address() ) {
368 $this->headers .= "Reply-To: {$this->get_reply_to_address()}\r\n";
369 }
370
371 $cc = $this->get_cc_address();
372
373 if ( $cc ) {
374 $this->headers .= "Cc: {$cc}\r\n";
375 }
376
377 $this->headers .= "Content-Type: {$this->get_content_type()}; charset=utf-8\r\n";
378
379 /**
380 * Filters the email headers.
381 *
382 * @since 1.5.4
383 *
384 * @param string $headers Email headers.
385 * @param Mailer $this Mailer instance.
386 */
387 return apply_filters( 'wpforms_emails_mailer_get_headers', $this->headers, $this );
388 }
389
390 /**
391 * Get the email attachments.
392 *
393 * @since 1.5.4
394 *
395 * @return string|string[]
396 */
397 public function get_attachments() {
398
399 if ( $this->attachments === null ) {
400 $this->attachments = [];
401 }
402
403 /**
404 * Filters the email attachments.
405 *
406 * @since 1.5.4
407 *
408 * @param string|string[] $attachments Array or string with attachment paths.
409 * @param Mailer $this Mailer instance.
410 */
411 return apply_filters( 'wpforms_emails_mailer_get_attachments', $this->attachments, $this );
412 }
413
414 /**
415 * Set an email address to send to.
416 *
417 * @since 1.5.4
418 *
419 * @param string|string[] $email Array or comma-separated list of email addresses to send a message.
420 *
421 * @return Mailer
422 */
423 public function to_email( $email ) {
424
425 if ( is_string( $email ) ) {
426 $email = explode( ',', $email );
427 }
428
429 // phpcs:ignore WPForms.Comments.PHPDocHooks.RequiredHookDocumentation
430 $this->to_email = apply_filters( 'wpforms_emails_mailer_to_email', $email, $this );
431
432 return $this;
433 }
434
435 /**
436 * Set an email subject.
437 *
438 * @since 1.5.4
439 *
440 * @param string $subject Email subject.
441 *
442 * @return Mailer
443 */
444 public function subject( $subject ) {
445
446 $subject = $this->sanitize( $subject );
447
448 // phpcs:ignore WPForms.Comments.PHPDocHooks.RequiredHookDocumentation
449 $this->subject = apply_filters( 'wpforms_emails_mailer_subject', $subject, $this );
450
451 return $this;
452 }
453
454 /**
455 * Set an email message (body).
456 *
457 * @since 1.5.4
458 *
459 * @param string $message Email message.
460 *
461 * @return Mailer
462 */
463 public function message( $message ) {
464
465 // phpcs:ignore WPForms.Comments.PHPDocHooks.RequiredHookDocumentation
466 $this->message = apply_filters( 'wpforms_emails_mailer_message', $message, $this );
467
468 return $this;
469 }
470
471 /**
472 * Set email template.
473 *
474 * @since 1.5.4
475 *
476 * @param General $template Email template.
477 *
478 * @return Mailer
479 */
480 public function template( General $template ) {
481
482 // phpcs:ignore WPForms.Comments.PHPDocHooks.RequiredHookDocumentation
483 $this->template = apply_filters( 'wpforms_emails_mailer_template', $template, $this );
484
485 return $this;
486 }
487
488 /**
489 * Get email errors.
490 *
491 * @since 1.5.4
492 *
493 * @return array
494 */
495 protected function get_errors() {
496
497 $errors = [];
498
499 foreach ( (array) $this->to_email as $email ) {
500 if ( ! is_email( $email ) ) {
501 $errors[] = sprintf( /* translators: %1$s - namespaced class name, %2$s - invalid email. */
502 esc_html__( '%1$s Invalid email address %2$s.', 'wpforms-lite' ),
503 '[WPForms\Emails\Mailer]',
504 $email
505 );
506 }
507 }
508
509 if ( empty( $this->get_subject() ) ) {
510 $errors[] = sprintf( /* translators: %s - namespaced class name. */
511 esc_html__( '%s Empty subject line.', 'wpforms-lite' ),
512 '[WPForms\Emails\Mailer]'
513 );
514 }
515
516 if ( empty( $this->get_message() ) ) {
517 $errors[] = sprintf( /* translators: %s - namespaced class name. */
518 esc_html__( '%s Empty message.', 'wpforms-lite' ),
519 '[WPForms\Emails\Mailer]'
520 );
521 }
522
523 return $errors;
524 }
525
526 /**
527 * Log given email errors.
528 *
529 * @since 1.5.4
530 *
531 * @param array $errors Errors to log.
532 */
533 protected function log_errors( $errors ): void {
534
535 if ( empty( $errors ) || ! is_array( $errors ) ) {
536 return;
537 }
538
539 foreach ( $errors as $error ) {
540 wpforms_log(
541 $error,
542 [
543 'to_email' => $this->to_email,
544 'subject' => $this->subject,
545 'message' => wp_trim_words( $this->get_message() ),
546 ],
547 [
548 'type' => 'error',
549 ]
550 );
551 }
552 }
553
554 /**
555 * Send the email.
556 *
557 * @since 1.5.4
558 *
559 * @return bool
560 */
561 public function send() {
562
563 if ( ! did_action( 'init' ) && ! did_action( 'admin_init' ) ) {
564 _doing_it_wrong( __FUNCTION__, esc_html__( 'You cannot send emails with WPForms\Emails\Mailer until init/admin_init has been reached.', 'wpforms-lite' ), null );
565
566 return false;
567 }
568
569 // Don't send anything if emails have been disabled.
570 if ( $this->is_email_disabled() ) {
571 return false;
572 }
573
574 $errors = $this->get_errors();
575
576 if ( $errors ) {
577 $this->log_errors( $errors );
578
579 return false;
580 }
581
582 $this->send_before();
583
584 $sent = wp_mail(
585 $this->to_email,
586 $this->get_subject(),
587 $this->get_message(),
588 $this->get_headers(),
589 $this->get_attachments()
590 );
591
592 $this->send_after();
593
594 return $sent;
595 }
596
597 /**
598 * Add filters / actions before the email is sent.
599 *
600 * @since 1.5.4
601 */
602 public function send_before(): void { // phpcs:ignore WPForms.PHP.HooksMethod.InvalidPlaceForAddingHooks
603
604 // phpcs:ignore WPForms.Comments.PHPDocHooks.RequiredHookDocumentation
605 do_action( 'wpforms_emails_mailer_send_before', $this );
606
607 add_filter( 'wp_mail_from', [ $this, 'get_from_address' ] );
608 add_filter( 'wp_mail_from_name', [ $this, 'get_from_name' ] );
609 add_filter( 'wp_mail_content_type', [ $this, 'get_content_type' ] );
610 }
611
612 /**
613 * Remove filters / actions after the email is sent.
614 *
615 * @since 1.5.4
616 */
617 public function send_after(): void { // phpcs:ignore WPForms.PHP.HooksMethod.InvalidPlaceForAddingHooks
618
619 // phpcs:ignore WPForms.Comments.PHPDocHooks.RequiredHookDocumentation
620 do_action( 'wpforms_emails_mailer_send_after', $this );
621
622 remove_filter( 'wp_mail_from', [ $this, 'get_from_address' ] );
623 remove_filter( 'wp_mail_from_name', [ $this, 'get_from_name' ] );
624 remove_filter( 'wp_mail_content_type', [ $this, 'get_content_type' ] );
625 }
626 }
627