PluginProbe ʕ •ᴥ•ʔ
JetFormBuilder — Dynamic Blocks Form Builder / 3.5.6.3
JetFormBuilder — Dynamic Blocks Form Builder v3.5.6.3
3.6.3.1 3.6.3 3.6.2.2 3.6.2.1 3.6.2 3.6.1.1 3.6.1 3.6.0.1 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.4.1 1.4.2 1.4.3 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.1.0 2.1.1 2.1.10 2.1.11 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 3.0.0 3.0.0.1 3.0.0.2 3.0.0.3 3.0.1 3.0.1.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.0.1 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.3.2 3.3.3 3.3.3.1 3.3.4 3.3.4.1 3.3.4.2 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.5.1 3.4.5.2 3.4.6 3.4.7 3.4.7.1 3.5.0 3.5.1 3.5.1.1 3.5.1.2 3.5.2 3.5.2.1 3.5.3 3.5.4 3.5.5 3.5.6 3.5.6.1 3.5.6.2 3.5.6.3 3.6.0
jetformbuilder / modules / actions-v2 / send-email / send-email-action.php
jetformbuilder / modules / actions-v2 / send-email Last commit date
assets 6 months ago send-email-action.php 3 months ago send-email-hooks.php 1 year ago send-email.php 1 year ago
send-email-action.php
635 lines
1 <?php
2
3 namespace JFB_Modules\Actions_V2\Send_Email;
4
5 use Jet_Form_Builder\Actions\Action_Handler;
6 use Jet_Form_Builder\Actions\Types\Base;
7 use Jet_Form_Builder\Classes\Http\Http_Tools;
8 use Jet_Form_Builder\Classes\Resources\Uploaded_File;
9 use Jet_Form_Builder\Classes\Tools;
10 use Jet_Form_Builder\Exceptions\Action_Exception;
11 use Jet_Form_Builder\Request\Request_Tools;
12
13 // If this file is called directly, abort.
14 if ( ! defined( 'WPINC' ) ) {
15 die;
16 }
17
18 /**
19 * Define Base_Type class
20 */
21 class Send_Email_Action extends Base {
22
23 private $content_type = '';
24 private $mail_to = array();
25 private $cc = array();
26 private $bcc = array();
27 private $reply_to = '';
28 private $from_email = '';
29 private $content = '';
30 private $subject = '';
31 private $from_name = '';
32 private $attachments = array();
33 private $headers = '';
34
35 public function get_name() {
36 return __( 'Send Email', 'jet-form-builder' );
37 }
38
39 public function get_id() {
40 return 'send_email';
41 }
42
43 public function self_script_name() {
44 return 'jetFormEmailData';
45 }
46
47 public function editor_labels() {
48 return array(
49 'mail_to' => __( 'Mail To:', 'jet-form-builder' ),
50 'custom_email' => __( 'Email Address:', 'jet-form-builder' ),
51 'from_field' => __( 'From Field:', 'jet-form-builder' ),
52 'reply_to' => __( 'Reply To:', 'jet-form-builder' ),
53 'reply_to_email' => __( 'Reply to Email Address:', 'jet-form-builder' ),
54 'reply_from_field' => __( 'Reply To Email From Field:', 'jet-form-builder' ),
55 'subject' => __( 'Subject:', 'jet-form-builder' ),
56 'from_name' => __( 'From Name:', 'jet-form-builder' ),
57 'from_address' => __( 'From Email Address:', 'jet-form-builder' ),
58 'content_type' => __( 'Content type:', 'jet-form-builder' ),
59 'disable_format' => __( 'Disable Auto-Formatting', 'jet-form-builder' ),
60 'content' => __( 'Content:', 'jet-form-builder' ),
61 'attachments' => __( 'Attachments:', 'jet-form-builder' ),
62 'add_attachment' => __( 'Add form field with attachment', 'jet-form-builder' ),
63 );
64 }
65
66 public function action_attributes() {
67 return array(
68 'mail_to' => array(
69 'default' => '',
70 ),
71 'custom_email' => array(
72 'default' => '',
73 ),
74 'from_field' => array(
75 'default' => '',
76 ),
77 'reply_to' => array(
78 'default' => '',
79 ),
80 'reply_to_email' => array(
81 'default' => '',
82 ),
83 'reply_from_field' => array(
84 'default' => '',
85 ),
86 'subject' => array(
87 'default' => '',
88 'path' => 'email/subject',
89 ),
90 'from_name' => array(
91 'default' => '',
92 'path' => 'email/from_name',
93 ),
94 'from_address' => array(
95 'default' => '',
96 'path' => 'email/from_address',
97 ),
98 'content_type' => array(
99 'default' => '',
100 'path' => 'email/content_type',
101 ),
102 'content' => array(
103 'default' => '',
104 'path' => 'email/content',
105 ),
106 );
107 }
108
109 /**
110 * Regsiter custom action data for the editor
111 *
112 * @return [type] [description]
113 */
114 public function action_data() {
115 return array(
116 'replyTo' => Tools::with_placeholder(
117 array(
118 array(
119 'value' => 'form',
120 'label' => __( 'Email from submitted form field', 'jet-form-builder' ),
121 ),
122 array(
123 'value' => 'custom',
124 'label' => __( 'Custom email', 'jet-form-builder' ),
125 ),
126 )
127 ),
128 'content_type' => Tools::with_placeholder(
129 array(
130 array(
131 'value' => 'text/plain',
132 'label' => __( 'Plain text', 'jet-form-builder' ),
133 ),
134 array(
135 'value' => 'text/html',
136 'label' => __( 'HTML', 'jet-form-builder' ),
137 ),
138 )
139 ),
140 'customMacros' => apply_filters( 'jet-form-builder/actions/send-email/custom-macros', false ),
141 );
142 }
143
144 /**
145 * @param array $request
146 * @param Action_Handler $handler
147 *
148 * @throws Action_Exception
149 */
150 public function do_action( array $request, Action_Handler $handler ) {
151 $message = apply_filters(
152 'jet-form-builder/send-email/message_content',
153 $this->settings['content'] ?? '',
154 $this
155 );
156 $this->set_content( $message );
157
158 $content_type = apply_filters(
159 'jet-form-builder/send-email/content-type',
160 $this->get_default_content_type(),
161 $this
162 );
163 $this->set_content_type( $content_type );
164
165 $from_name = apply_filters(
166 'jet-form-builder/send-email/from-name',
167 $this->get_default_from_name(),
168 $this
169 );
170 $this->set_from_name( $from_name );
171
172 $reply_to = apply_filters(
173 'jet-form-builder/send-email/reply-to',
174 $this->get_default_reply_to(),
175 $this
176 );
177 $this->set_reply_to( $reply_to );
178
179 $from_email = apply_filters(
180 'jet-form-builder/send-email/from-address',
181 $this->get_default_from_address(),
182 $this
183 );
184 $this->set_from_address( $from_email );
185
186 $this->set_mail_to( $this->get_default_mail_to() );
187 $this->set_cc( $this->get_default_cc() );
188 $this->set_bcc( $this->get_default_bcc() );
189 $this->set_subject( $this->get_default_subject() );
190 $this->set_attachments( $this->get_default_attachments() );
191
192 $headers = apply_filters(
193 'jet-form-builder/send-email/headers',
194 $this->get_default_headers(),
195 $this
196 );
197 $this->set_headers( $headers );
198
199 /**
200 * Hooks before the email is sent
201 */
202 do_action( 'jet-form-builder/send-email/send-before', $this );
203
204 if ( jet_form_builder()->has_module( 'dev' ) ) {
205 add_action(
206 'wp_mail_failed',
207 function ( \WP_Error $wp_error ) {
208 new Action_Exception( 'failed', $wp_error->get_error_message(), $wp_error->get_error_data() );
209 }
210 );
211 }
212
213 $this->validate();
214
215 $sent = wp_mail(
216 $this->get_mail_to(),
217 $this->get_subject(),
218 $this->get_content(),
219 $this->get_headers(),
220 $this->get_attachments()
221 );
222
223 if ( ! $sent ) {
224 throw new Action_Exception(
225 'failed',
226 array(
227 // phpcs:disable WordPress.Security.EscapeOutput.ExceptionNotEscaped
228 'to' => $this->get_mail_to(),
229 'subject' => $this->get_subject(),
230 'message' => $message,
231 'headers' => $this->get_headers(),
232 // phpcs:enable
233 )
234 );
235 }
236
237 /**
238 * Hooks after the email is sent
239 *
240 * @since 2.1
241 */
242 do_action( 'jet-form-builder/send-email/send-after', $this );
243 }
244
245 /**
246 * @throws Action_Exception
247 */
248 protected function validate() {
249 $this->validate_mail_to();
250 $this->validate_reply_to();
251 }
252
253 /**
254 * @throws Action_Exception
255 */
256 protected function validate_mail_to() {
257 foreach ( $this->mail_to as $value ) {
258 if ( ! $value || ! is_email( $value ) ) {
259 throw new Action_Exception( 'invalid_email' );
260 }
261 }
262 }
263
264 protected function validate_reply_to() {
265 $emails = explode( ',', $this->get_reply_to() );
266
267 foreach ( $emails as &$value ) {
268 $value = trim( $value );
269 }
270
271 $emails = array_filter( $emails, 'is_email' );
272
273 if ( count( $emails ) ) {
274 $this->set_reply_to( $emails );
275
276 return;
277 }
278
279 $this->set_reply_to( 'noreply@' . Http_Tools::get_site_host() );
280 }
281
282 public function get_default_mail_to() {
283 $mail_to = ! empty( $this->settings['mail_to'] ) ? $this->settings['mail_to'] : 'admin';
284
285 switch ( $mail_to ) {
286 case 'form':
287 $field = $this->settings['from_field'] ?? '';
288 $email = jet_fb_context()->get_value( $field );
289
290 return $email ?: '';
291 case 'custom':
292 return ! empty( $this->settings['custom_email'] ) ? $this->settings['custom_email'] : '';
293 case 'admin':
294 default:
295 return get_option( 'admin_email' );
296 }
297 }
298
299 public function get_default_cc() {
300 if ( empty( $this->settings['use_cc_bcc'] ) ) {
301 return array();
302 }
303
304 $mail_to = ! empty( $this->settings['cc_from'] ) ? $this->settings['cc_from'] : '';
305
306 switch ( $mail_to ) {
307 case 'form':
308 $field = $this->settings['cc_field'] ?? '';
309 $email = jet_fb_context()->get_value( $field );
310
311 return $email ?: '';
312 case 'custom':
313 return ! empty( $this->settings['cc_email'] ) ? $this->settings['cc_email'] : '';
314 case 'admin':
315 return get_option( 'admin_email' );
316 default:
317 return '';
318 }
319 }
320
321 public function get_default_bcc() {
322 if ( empty( $this->settings['use_cc_bcc'] ) ) {
323 return array();
324 }
325
326 $mail_to = ! empty( $this->settings['bcc_from'] ) ? $this->settings['bcc_from'] : '';
327
328 switch ( $mail_to ) {
329 case 'form':
330 $field = $this->settings['bcc_field'] ?? '';
331 $email = jet_fb_context()->get_value( $field );
332
333 return $email ?: '';
334 case 'custom':
335 return ! empty( $this->settings['bcc_email'] ) ? $this->settings['bcc_email'] : '';
336 case 'admin':
337 return get_option( 'admin_email' );
338 default:
339 return '';
340 }
341 }
342
343 public function get_default_reply_to(): string {
344 $reply_to = ! empty( $this->settings['reply_to'] ) ? $this->settings['reply_to'] : 'form';
345
346 switch ( $reply_to ) {
347 case 'form':
348 $field = $this->settings['reply_from_field'] ?? '';
349
350 return Tools::to_string( jet_fb_context()->get_value( $field ) );
351 case 'custom':
352 return ! empty( $this->settings['reply_to_email'] ) ? $this->settings['reply_to_email'] : '';
353 default:
354 return '';
355 }
356 }
357
358 public function get_default_subject(): string {
359 return empty( $this->settings['subject'] )
360 ? sprintf(
361 /* translators: %s - site url */
362 __( 'Form on %s Submitted', 'jet-form-builder' ),
363 home_url( '' )
364 )
365 : $this->settings['subject'];
366 }
367
368 public function get_default_content_type(): string {
369 $type = $this->settings['content_type'] ?? 'text/html';
370
371 return empty( $type ) ? 'text/html' : $type;
372 }
373
374 public function get_default_from_name(): string {
375 return empty( $this->settings['from_name'] )
376 ? Tools::get_site_name()
377 : $this->settings['from_name'];
378 }
379
380 public function get_default_from_address(): string {
381 return ! empty( $this->settings['from_address'] ) ? $this->settings['from_address'] : '';
382 }
383
384 public function get_default_attachments(): array {
385 $fields = $this->settings['attachments'] ?? array();
386 $attachments = array();
387
388 foreach ( $fields as $field ) {
389 $value = Request_Tools::get_file( $field );
390
391 if ( ! $value ) {
392 continue;
393 }
394
395 array_push(
396 $attachments,
397 ...explode( ',', $value->get_attachment_file() )
398 );
399 }
400
401 return $this->filter_safe_attachments( $attachments );
402 }
403
404 /**
405 * Allow only readable files within the uploads directory.
406 */
407 private function filter_safe_attachments( array $attachments ): array {
408 $safe = array();
409
410 foreach ( $attachments as $attachment ) {
411 if ( ! is_string( $attachment ) || '' === $attachment ) {
412 continue;
413 }
414
415 $allowed = Uploaded_File::normalize_allowed_upload_file_path( $attachment );
416 if ( '' === $allowed || ! is_file( $allowed ) || ! is_readable( $allowed ) ) {
417 continue;
418 }
419
420 $safe[] = $allowed;
421 }
422
423 return array_values( array_unique( $safe ) );
424 }
425
426 public function update_headers() {
427 $this->set_headers( $this->get_default_headers() );
428 }
429
430 /**
431 * Get the email headers
432 *
433 * @since 2.1
434 */
435 public function get_default_headers(): string {
436 $headers = array(
437 "From: {$this->get_from_name()} <{$this->get_from_address()}>",
438 "Reply-To: {$this->get_reply_to()}",
439 "Content-Type: {$this->get_content_type()}; charset=utf-8",
440 );
441
442 $cc_emails = $this->get_cc();
443 $bcc_emails = $this->get_bcc();
444
445 foreach ( $cc_emails as $cc_email ) {
446 $headers[] = 'Cc: ' . $cc_email;
447 }
448 foreach ( $bcc_emails as $bcc_email ) {
449 $headers[] = 'Bcc: ' . $bcc_email;
450 }
451
452 return implode( "\r\n", $headers );
453 }
454
455 /**
456 * @param string|array $email
457 */
458 public function set_mail_to( $email ) {
459 if ( ! is_array( $email ) && ! is_string( $email ) ) {
460 return;
461 }
462
463 $this->mail_to = $this->parse_email( $email );
464 }
465
466 /**
467 * @param $email
468 *
469 * @return void
470 */
471 public function set_cc( $email ): void {
472 if ( ! is_array( $email ) && ! is_string( $email ) ) {
473 return;
474 }
475
476 $this->cc = $this->parse_email( $email );
477 }
478
479 /**
480 * @param $email
481 *
482 * @return void
483 */
484 public function set_bcc( $email ): void {
485 if ( ! is_array( $email ) && ! is_string( $email ) ) {
486 return;
487 }
488
489 $this->bcc = $this->parse_email( $email );
490 }
491
492 /**
493 * @param $email
494 *
495 * @return string[]
496 */
497 private function parse_email( $email ): array {
498 if ( ! is_array( $email ) ) {
499 $email = explode( ',', $email );
500 }
501
502 foreach ( $email as &$value ) {
503 $value = trim( $value );
504 }
505
506 return $email;
507 }
508
509 public function set_reply_to( $email ) {
510 if ( ! is_string( $email ) && ! is_array( $email ) ) {
511 return;
512 }
513
514 $this->reply_to = Tools::to_string( $email );
515 }
516
517 public function set_content( $content ) {
518 if ( ! is_string( $content ) ) {
519 return;
520 }
521
522 $this->content = $content;
523 }
524
525 public function set_subject( $subject ) {
526 if ( ! is_string( $subject ) ) {
527 return;
528 }
529
530 $this->subject = $subject;
531 }
532
533 public function set_content_type( string $type ) {
534 $this->content_type = $type;
535 }
536
537 public function set_from_name( string $name ) {
538 $this->from_name = $name;
539 }
540
541 public function set_from_address( string $email ) {
542 $this->from_email = $email;
543 }
544
545 /**
546 * @param array $attachments
547 */
548 public function set_attachments( array $attachments ) {
549 $this->attachments = $attachments;
550 }
551
552 public function set_headers( string $headers ) {
553 $this->headers = $headers;
554 }
555
556 public function get_attachments(): array {
557 return $this->attachments;
558 }
559
560 /**
561 * @return array
562 */
563 public function get_mail_to(): array {
564 return $this->mail_to;
565 }
566
567 /**
568 * @return array
569 */
570 public function get_cc(): array {
571 return $this->cc;
572 }
573
574 /**
575 * @return array
576 */
577 public function get_bcc(): array {
578 return $this->bcc;
579 }
580
581 /**
582 * @return string
583 */
584 public function get_subject(): string {
585 return $this->subject;
586 }
587
588 /**
589 * @return string
590 */
591 public function get_content(): string {
592 return $this->content;
593 }
594
595 /**
596 * Get the email from name
597 */
598 public function get_from_name(): string {
599 return $this->from_name;
600 }
601
602 /**
603 * Returns e-mail address to set into Reply-to email header
604 */
605 public function get_reply_to(): string {
606 return $this->reply_to;
607 }
608
609 /**
610 * Get the email from address
611 */
612 public function get_from_address(): string {
613 return $this->from_email;
614 }
615
616 public function is_html(): bool {
617 return 'text/html' === $this->get_content_type();
618 }
619
620 /**
621 * Get the email content type
622 */
623 public function get_content_type(): string {
624 return $this->content_type;
625 }
626
627 /**
628 * @return string
629 */
630 public function get_headers(): string {
631 return $this->headers;
632 }
633
634 }
635