PluginProbe
weForms – Easy Drag & Drop Contact Form Builder For WordPress / 1.0.1
weForms – Easy Drag & Drop Contact Form Builder For WordPress v1.0.1
1.6.7 1.6.8 1.6.9 1.6.12 1.6.13 1.6.14 1.6.15 1.6.16 1.6.17 1.6.18 1.6.19 1.6.2 1.6.20 1.6.21 1.6.22 1.6.23 1.6.24 1.6.25 1.6.26 1.6.27 1.6.28 1.6.3 1.6.4 1.6.5 1.6.6 All 74 releases
← All changes | includes/class-notification.php +456 -746 1.6.201.0.1 View file →
@@ -1,746 +1,456 @@
1 -<?php
2 -
3 -/**
4 - * Email Notification Class
5 - */
6 -class WeForms_Notification {
7 -
8 - private $merge_tags = [];
9 - private $args = [];
10 -
11 - /**
12 - * Init the class
13 - *
14 - * @param array $args
15 - */
16 - public function __construct( $args = [] ) {
17 - $defaults = [
18 - 'form_id' => 0,
19 - 'entry_id' => 0,
20 - 'page_id' => 0,
21 - ];
22 -
23 - $this->args = wp_parse_args( $args, $defaults );
24 - }
25 -
26 - /**
27 - * Send notifications
28 - *
29 - * @return void
30 - */
31 - public function send_notifications() {
32 - $notifications = $this->get_active_notifications();
33 -
34 - if ( !$notifications ) {
35 - return;
36 - }
37 -
38 - $this->set_merge_tags();
39 -
40 - foreach ( $notifications as $notification ) {
41 - if ( $this->meet_conditions( $notification ) ) {
42 - if ( $notification['type'] == 'email' ) {
43 - $this->send_notification( $notification );
44 - } elseif ( $notification['type'] == 'sms' ) {
45 - $this->send_sms( $notification );
46 - }
47 - }
48 - }
49 - }
50 -
51 - /**
52 - * Resend entry notifications
53 - *
54 - * @return void
55 - */
56 - public function resend_entry_notifications( $notifications ) {
57 - if ( !$notifications ) {
58 - return;
59 - }
60 -
61 - $this->set_merge_tags();
62 -
63 - foreach ( $notifications as $notification ) {
64 - if ( $this->meet_conditions( $notification ) ) {
65 - if ( $notification['type'] == 'email' ) {
66 - $this->send_notification( $notification );
67 - } elseif ( $notification['type'] == 'sms' ) {
68 - $this->send_sms( $notification );
69 - }
70 - }
71 - }
72 - }
73 -
74 - /**
75 - * Send a single notification
76 - *
77 - * @param array $notification
78 - *
79 - * @return void
80 - */
81 - public function send_notification( $notification ) {
82 - $headers = [];
83 -
84 - $to = $this->replace_tags( $notification['to'] );
85 -
86 - $subject = $this->replace_tags( $notification['subject'] );
87 - $subject = static::replace_name_tag( $subject, $this->args['entry_id'] );
88 -
89 - $message = $this->replace_tags( $notification['message'] );
90 - $message = static::replace_name_tag( $message, $this->args['entry_id'] );
91 - $message = $this->replace_all_fields( $message );
92 - $message = wpautop( $message );
93 -
94 - $fromName = $this->replace_tags( $notification['fromName'] );
95 - $fromName = static::replace_name_tag( $fromName, $this->args['entry_id'] );
96 - $fromAddress = $this->replace_tags( $notification['fromAddress'] );
97 - $replyTo = $this->replace_tags( $notification['replyTo'] );
98 - $cc = $this->replace_tags( $notification['cc'] );
99 - $bcc = $this->replace_tags( $notification['bcc'] );
100 -
101 - if ( $fromName || $fromAddress ) {
102 - $headers['from'] = [
103 - 'email' => $fromAddress,
104 - 'name' => $fromName,
105 - ];
106 - }
107 -
108 - if ( $cc ) {
109 - $headers['cc'] = $cc;
110 - }
111 -
112 - if ( $bcc ) {
113 - $headers['bcc'] = $bcc;
114 - }
115 -
116 - if ( $replyTo ) {
117 - $headers['replyto'] = $replyTo;
118 - }
119 -
120 - // content type to text/html
121 - $headers[] = 'Content-Type: text/html; charset=UTF-8';
122 - $email_body = apply_filters( 'weforms_email_message', $this->get_formatted_body( $message ), $notification['message'], $headers );
123 -
124 - /**
125 - * Added the display style to the safe styles during wp_kses_post().
126 - * WP kses post removes the display css property that we need when formatting the Checkbox and Multiple Choice Grids.
127 - * This function will only run during the notification process.
128 - *
129 - * @since 1.6.17
130 - */
131 - add_filter( 'safe_style_css', function( $styles ) {
132 - $styles[] = 'display';
133 - return $styles;
134 - } );
135 -
136 - /**
137 - * Added the input tag to the allowed html during wp_kses_post().
138 - * WP kses post removes the input tag that we need when formatting the Checkbox and Multiple Choice Grids.
139 - * The $message variable is formatted during the entry creation process. The values from the form are sanitized to avoid
140 - * any issues with malicious inputs.
141 - *
142 - * This function is only used during the notification process.
143 - *
144 - * @since 1.6.17
145 - */
146 - add_filter( 'wp_kses_allowed_html', function( $html ) {
147 - $html['input'] = array(
148 - 'class' => array(),
149 - 'name' => array(),
150 - 'type' => array(),
151 - 'value' => array(),
152 - 'checked' => array(),
153 - 'disabled' => array(),
154 - );
155 - return $html;
156 - } );
157 - weforms()->emailer->send( $to, $subject, wp_kses_post( htmlspecialchars_decode( $email_body ) ) , $headers );
158 - }
159 -
160 - /**
161 - * Send a single sms notification
162 - *
163 - * @param array $notification
164 - *
165 - * @return void
166 - */
167 - public function send_sms( $notification ) {
168 - if ( !class_exists( 'WeForms_SMS_Notification' ) ) {
169 - return;
170 - }
171 -
172 - $to = $this->replace_tags( $notification['smsTo'] );
173 - $message = $this->replace_tags( $notification['smsText'] );
174 - $message = static::replace_name_tag( $message, $this->args['entry_id'] );
175 - $message = $this->replace_all_fields( $message );
176 -
177 - $email_body = apply_filters( 'weforms_sms_message', $this->get_formatted_sms_body( $message ) );
178 -
179 - weforms_sms()->send_sms( [ $to ], $message );
180 - }
181 -
182 - /**
183 - * Check conditional logics
184 - *
185 - * @param array $notification
186 - *
187 - * @return bool
188 - */
189 - public function meet_conditions( $notification ) {
190 - $form = weforms()->form->get( $this->args['form_id'] );
191 - $entry = $form->entries()->get( $this->args['entry_id'] );
192 - $fields = $entry->get_fields();
193 -
194 - $cond = !empty( $notification['weforms_cond'] ) ? $notification['weforms_cond'] : [];
195 -
196 - if ( isset( $cond['condition_status'] ) && 'yes' === $cond['condition_status'] ) {
197 - $cond_logic = !empty( $cond['cond_logic'] ) ? $cond['cond_logic'] : 'any';
198 -
199 - if ( !empty( $cond['conditions'] ) && is_array( $cond['conditions'] ) ) {
200 - $status = []; // going to store all condition result as boolean
201 -
202 - foreach ( $cond['conditions'] as $k => $condition ) {
203 - $field = $fields[$condition['name']];
204 - $value = $field['value'];
205 - $options = $field['options'];
206 - $operator = $condition['operator'] == '=' ? true : false;
207 -
208 - // probably from checkbox
209 - if ( is_array( $value ) ) {
210 -
211 - // search by value
212 - if ( in_array( $condition['option'], $value ) ) {
213 - $status[$k] = $operator ? true : false;
214 - } else {
215 -
216 - // search by key
217 - foreach ( $value as $single_value ) {
218 - if ( $condition['option'] == array_search( $single_value, $options ) ) {
219 - $status[$k] = $operator ? true : false;
220 -
221 - break;
222 - }
223 - }
224 - }
225 -
226 - if ( !isset( $status[$k] ) ) {
227 - $status[$k] = $operator ? false : true;
228 - }
229 - } else {
230 - if ( $condition['option'] == $value || $condition['option'] == array_search( $value, $options ) ) {
231 - $status[$k] = $operator ? true : false;
232 - } else {
233 - $status[$k] = $operator ? false : true;
234 - }
235 - }
236 - }
237 -
238 - if ( $cond_logic == 'any' ) {
239 - return in_array( true, $status ) ? true : false; // any true? then true
240 - } elseif ( $cond_logic == 'all' ) {
241 - return in_array( false, $status ) ? false : true; // any false? then false
242 - }
243 - }
244 - }
245 -
246 - return true;
247 - }
248 -
249 - /**
250 - * Get active notifications of a form
251 - *
252 - * @param int $form_id
253 - *
254 - * @return array|bool
255 - */
256 - public function get_active_notifications() {
257 - $notifications = weforms()->form->get( $this->args['form_id'] )->get_notifications();
258 -
259 - if ( $notifications ) {
260 - $notifications = array_filter( $notifications, function ( $notification ) {
261 - return $notification['active'] == true;
262 - } );
263 -
264 - return $notifications;
265 - }
266 -
267 - return false;
268 - }
269 -
270 - /**
271 - * Get formatted HTML email
272 - *
273 - * @param string $message
274 - *
275 - * @return string
276 - */
277 - public function get_formatted_body( $message ) {
278 - $css = '';
279 - $header = apply_filters( 'weforms_email_header', '' );
280 - $footer = apply_filters( 'weforms_email_footer', '' );
281 -
282 - if ( empty( $header ) ) {
283 - ob_start();
284 - include WEFORMS_INCLUDES . '/email/template/header.php';
285 - $header = ob_get_clean();
286 - }
287 -
288 - if ( empty( $footer ) ) {
289 - ob_start();
290 - include WEFORMS_INCLUDES . '/email/template/footer.php';
291 - $footer = ob_get_clean();
292 - }
293 -
294 - ob_start();
295 - include WEFORMS_INCLUDES . '/email/template/styles.php';
296 - $css = apply_filters( 'weforms_email_styles', ob_get_clean() );
297 -
298 - $content = $header . $message . $footer;
299 -
300 - if ( !class_exists( 'Emogrifier' ) ) {
301 - require_once WEFORMS_INCLUDES . '/library/Emogrifier.php';
302 - }
303 -
304 - try {
305 -
306 - // apply CSS styles inline for picky email clients
307 - $emogrifier = new Emogrifier( $content, $css );
308 - $content = $emogrifier->emogrify();
309 - } catch ( Exception $e ) {
310 - echo esc_html( $e->getMessage() );
311 - }
312 -
313 - return $content;
314 - }
315 -
316 - /**
317 - * Get formatted HTML email
318 - *
319 - * @param string $message
320 - *
321 - * @return string
322 - */
323 - public function get_formatted_sms_body( $message ) {
324 - $message = strip_tags( $message );
325 -
326 - if ( strlen( $message ) > apply_filters( 'wefroms_sms_char_length', 153 ) ) {
327 - $message = substr( $message, 0, apply_filters( 'wefroms_sms_char_length', 153 ) );
328 - $message .= __( '..', 'weforms' );
329 - }
330 -
331 - return $message;
332 - }
333 -
334 - /**
335 - * Populate an key/value pair of search/replace array
336 - *
337 - * @return array
338 - */
339 - public function set_merge_tags() {
340 -
341 - // return early we had a previous array call
342 - if ( $this->merge_tags ) {
343 - return $this->merge_tags;
344 - }
345 -
346 - // populate the key/value array for the first time
347 - $tags = weforms_get_merge_tags();
348 - $replace_array = [];
349 -
350 - foreach ( $tags as $section => $child ) {
351 - if ( !$child['tags'] ) {
352 - continue;
353 - }
354 -
355 - foreach ( $child['tags'] as $search_key => $label ) {
356 - $replace_array[ '{' . $search_key . '}' ] = $this->get_merge_value( $search_key );
357 - }
358 - }
359 -
360 - $this->merge_tags = $replace_array;
361 - }
362 -
363 - /**
364 - * Get a merge tag value based on a tag
365 - *
366 - * @param string $tag
367 - *
368 - * @return string
369 - */
370 - public function get_merge_value( $tag ) {
371 - switch ( $tag ) {
372 - case 'entry_id':
373 - return $this->args['entry_id'];
374 - break;
375 -
376 - case 'form_id':
377 - return $this->args['form_id'];
378 - break;
379 -
380 - case 'form_name':
381 - return get_post_field( 'post_title', $this->args['form_id'] );
382 - break;
383 -
384 - case 'admin_email':
385 - return get_option( 'admin_email' );
386 - break;
387 -
388 - case 'date':
389 - return date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ) );
390 - break;
391 -
392 - case 'site_name':
393 - return get_bloginfo( 'name' );
394 - break;
395 -
396 - case 'site_url':
397 - return site_url( '/' );
398 - break;
399 -
400 - case 'page_title':
401 - return get_post_field( 'post_title', $this->args['page_id'] );
402 - break;
403 -
404 - case 'ip_address':
405 - return weforms_get_client_ip();
406 - break;
407 -
408 - case 'user_id':
409 - return get_current_user_id();
410 - break;
411 -
412 - case 'first_name':
413 - return $this->get_user_prop( 'first_name' );
414 - break;
415 -
416 - case 'last_name':
417 - return $this->get_user_prop( 'last_name' );
418 - break;
419 -
420 - case 'display_name':
421 - return $this->get_user_prop( 'display_name' );
422 - break;
423 -
424 - case 'user_email':
425 - return $this->get_user_prop( 'user_email' );
426 - break;
427 -
428 - case 'url_page':
429 - return get_permalink( $this->args['page_id'] );
430 - break;
431 -
432 - case 'url_referer':
433 - return isset( $_SERVER['HTTP_REFERER'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_REFERER'] ) ) : '';
434 - break;
435 -
436 - case 'url_login':
437 - return wp_login_url();
438 - break;
439 -
440 - case 'url_logout':
441 - return wp_logout_url();
442 - break;
443 -
444 - case 'url_register':
445 - return wp_registration_url();
446 - break;
447 -
448 - case 'url_lost_password':
449 - return wp_lostpassword_url();
450 - break;
451 -
452 - case 'personal_data_erase_confirm_url':
453 - $action_type = 'remove_personal_data';
454 - $email_address = weforms_get_entry_meta( $this->args['entry_id'], 'user_email_address', true );
455 - $request_id = wp_create_user_request( $email_address, $action_type );
456 -
457 - if ( !empty( $email_address ) ) {
458 - $confirm_url = add_query_arg(
459 - [
460 - 'action' => 'confirmaction',
461 - 'request_id' => $request_id,
462 - 'confirm_key' => wp_generate_user_request_key( $request_id ),
463 - ],
464 - wp_login_url()
465 - );
466 -
467 - return make_clickable( $confirm_url );
468 - }
469 -
470 - break;
471 -
472 - case 'personal_data_export_confirm_url':
473 - $action_type = 'export_personal_data';
474 - $email_address = weforms_get_entry_meta( $this->args['entry_id'], 'user_email_address', true );
475 - $request_id = wp_create_user_request( $email_address, $action_type );
476 -
477 - if ( !empty( $email_address ) ) {
478 - $confirm_url = add_query_arg(
479 - [
480 - 'action' => 'confirmaction',
481 - 'request_id' => $request_id,
482 - 'confirm_key' => wp_generate_user_request_key( $request_id ),
483 - ],
484 - wp_login_url()
485 - );
486 -
487 - return make_clickable( $confirm_url );
488 - }
489 -
490 - break;
491 -
492 - default:
493 - return apply_filters( 'weforms_merge_tag_value', '', $tag, $this->args );
494 - break;
495 - }
496 - }
497 -
498 - /**
499 - * Parse out the custom fields with options or values. Since the options are what is stored, options may need to be
500 - * used to find the value from the field settings.
501 - *
502 - * For example, let's say we have the following options:
503 - * DEPARTMENT / EMAIL
504 - * Support / support@example.com
505 - * Sales / sales@example.com
506 - *
507 - * Users need the ability to pass {field:department} and get "Support",
508 - * and {value:department} to get support@email.com
509 - *
510 - * @param string $text The text to parse.
511 - * @param int $entry_id The entry ID. Optional. Default null if tags to be replaced are on the frontend.
512 - *
513 - * @return string $text The parsed text.
514 - */
515 - public static function replace_field_tags( $text, $entry_id = null ) {
516 - // Validate data.
517 - if ( empty( $text ) || !isset( $entry_id ) ) {
518 - return;
519 - }
520 -
521 - // Users looking for {field:something} or {value:something}, determine which one.
522 - $is_field = preg_match_all( '/{field:(\w*)}/', $text, $matches_field );
523 - $is_value = preg_match_all( '/{value:(\w*)}/', $text, $matches_value );
524 -
525 - if ( $is_field ) {
526 - $meta_keys = $matches_field[1];
527 - // Create an array of meta values to replace.
528 - $meta_values = array();
529 - foreach ( $meta_keys as $meta_key ) {
530 - $meta_value = weforms_get_entry_meta( $entry_id, $meta_key, true );
531 - // Add values to the array.
532 - array_push( $meta_values, $meta_value );
533 - if ( is_array( $meta_value ) ) {
534 - $meta_value = implode( WeForms::$field_separator, $meta_value );
535 - }
536 - }
537 - // $text may include HTML tags, only replace tag that was matched. Replace all matches.
538 - $text = str_replace( $matches_field[0], $meta_values, $text );
539 - }
540 - if ( $is_value ) {
541 - $meta_keys = $matches_value[1];
542 - // Create an array of modified values to replace.
543 - $modified_values = array();
544 - foreach ( $meta_keys as $meta_key ) {
545 - $form_field_values = WeForms_Form_Entry::get_form( $entry_id )->get_field_values()[ $meta_key ]['options'];
546 - $meta_value = weforms_get_entry_meta( $entry_id, $meta_key, true );
547 - $modified_value = array_search( $meta_value, $form_field_values );
548 - // Add values to the array.
549 - array_push( $modified_values, $modified_value );
550 - if ( is_array( $modified_value ) ) {
551 - $modified_value = implode( WeForms::$field_separator, $modified_value );
552 - }
553 - }
554 - // $text may include HTML tags, only replace tag that was matched.
555 - $text = str_replace( $matches_value[0], $modified_values, $text );
556 - }
557 - return $text;
558 - }
559 -
560 - /**
561 - * Replace name tag with required value
562 - *
563 - * @param string $text
564 - *
565 - * @return string
566 - */
567 - public static function replace_name_tag( $text, $entry_id ) {
568 - $pattern = '/{name-(full|first|middle|last):(\w*)}/';
569 -
570 - preg_match_all( $pattern, $text, $matches );
571 -
572 - // bail out if nothing found to be replaced
573 - if ( !$matches[0] ) {
574 - return $text;
575 - }
576 -
577 - list( $search, $fields, $meta_key ) = $matches;
578 -
579 - $meta_value = weforms_get_entry_meta( $entry_id, $meta_key[0], true );
580 - $replace = explode( WeForms::$field_separator, $meta_value );
581 -
582 - foreach ( $search as $index => $search_key ) {
583 - if ( 'first' == $fields[ $index ] ) {
584 - $text = str_replace( $search_key, $replace[0], $text );
585 - } elseif ( 'middle' == $fields[ $index ] ) {
586 - $text = str_replace( $search_key, $replace[1], $text );
587 - } elseif ( 'last' == $fields[ $index ] ) {
588 - $text = str_replace( $search_key, $replace[2], $text );
589 - } else {
590 - $text = str_replace( $search_key, implode( ' ', $replace ), $text );
591 - }
592 - }
593 -
594 - return $text;
595 - }
596 -
597 - /**
598 - * Replace image/file tag with Image URL
599 - *
600 - * @param string $text
601 - *
602 - * @return string
603 - */
604 - public static function replace_file_tags( $text, $entry_id ) {
605 - $pattern = '/{(?:image|file):(\w*)}/';
606 -
607 - preg_match_all( $pattern, $text, $matches );
608 -
609 - // bail out if nothing found to be replaced
610 - if ( !$matches ) {
611 - return $text;
612 - }
613 -
614 - foreach ( $matches[1] as $index => $meta_key ) {
615 - $meta_value = weforms_get_entry_meta( $entry_id, $meta_key, true );
616 -
617 - $files = [];
618 -
619 - if ( is_array( $meta_value ) ) {
620 - foreach ( $meta_value as $key => $attachment_id ) {
621 - $file_url = wp_get_attachment_url( $attachment_id );
622 -
623 - if ( $file_url ) {
624 - $files[] = $file_url;
625 - }
626 - }
627 - } else {
628 - $file_url = wp_get_attachment_url( $attachment_id );
629 -
630 - if ( $file_url ) {
631 - $files[] = $file_url;
632 - }
633 - }
634 -
635 - $files = implode( ' ', $files );
636 -
637 - $text = str_replace( $matches[0][$index], $files, $text );
638 - }
639 -
640 - return $text;
641 - }
642 -
643 - /**
644 - * Get property of a user object with failsafe check
645 - *
646 - * @param string $property
647 - *
648 - * @return string
649 - */
650 - public function get_user_prop( $property ) {
651 - $user = wp_get_current_user();
652 -
653 - if ( $user->ID != 0 ) {
654 - return $user->{$property};
655 - }
656 -
657 - return '';
658 - }
659 -
660 - /**
661 - * Replace text with merge tags
662 - *
663 - * @param string $text
664 - *
665 - * @return text
666 - */
667 - public function replace_tags( $text = '' ) {
668 - $merge_keys = array_keys( $this->merge_tags );
669 - $merge_values = array_values( $this->merge_tags );
670 -
671 - $text = str_replace( $merge_keys, $merge_values, $text );
672 - $text = static::replace_field_tags( $text, $this->args['entry_id'] );
673 - $text = static::replace_file_tags( $text, $this->args['entry_id'] );
674 -
675 - return $text;
676 - }
677 -
678 - /**
679 - * Replace {all_fields} if found
680 - *
681 - * @param string $text
682 - *
683 - * @return string
684 - */
685 - public function replace_all_fields( $text = '' ) {
686 -
687 - // check if {all_fields} exists
688 - if ( false === strpos( $text, '{all_fields}' ) ) {
689 - return $text;
690 - }
691 -
692 - $form = weforms()->form->get( $this->args['form_id'] );
693 - $entry = $form->entries()->get( $this->args['entry_id'] );
694 - $fields = $entry->get_fields();
695 -
696 - if ( !$fields ) {
697 - return $text;
698 - }
699 -
700 - $table = '<table width="600" cellpadding="0" cellspacing="0">';
701 - $table .= '<tbody>';
702 -
703 - foreach ( $fields as $key => $value ) {
704 - $field_value = isset( $value[ 'value' ] ) ? $value[ 'value' ] : '';
705 -
706 - if ( !$field_value ) {
707 - continue; // let's skip empty fields
708 - }
709 -
710 - $table .= '<tr class="field-label">';
711 - $table .= '<td><strong>' . $value['label'] . '</strong></td>';
712 - $table .= '</tr>';
713 - $table .= '<tr class="field-value">';
714 - $table .= '<td>';
715 -
716 - if ( in_array( $value['type'], array( 'multiple_select', 'checkbox_field' ) ) ) {
717 - $field_value = is_array( $field_value ) ? $field_value : [];
718 -
719 - if ( $field_value ) {
720 - $table .= '<ul>';
721 -
722 - foreach ( $field_value as $value_key ) {
723 - $table .= '<li>' . $value_key . '</li>';
724 - }
725 - $table .= '</ul>';
726 - } else {
727 - $table .= '&mdash;';
728 - }
729 - } elseif ( in_array( $value['type'], array( 'google_map' ) ) ) {
730 - $table .= $field_value['address'];
731 - } else {
732 - $table .= $field_value;
733 - }
734 -
735 - $table .= '</td>';
736 - $table .= '</tr>';
737 - }
738 -
739 - $table .= '</tbody>';
740 - $table .= '</table>';
741 -
742 - $text = str_replace( '{all_fields}', $table, $text );
743 -
744 - return $text;
745 - }
746 -}
1 +<?php
2 +
3 +/**
4 + * Email Notification Class
5 + */
6 +class WeForms_Notification {
7 +
8 + private $merge_tags = array();
9 + private $args = array();
10 +
11 + /**
12 + * Init the class
13 + *
14 + * @param array $args
15 + */
16 + public function __construct( $args = array() ) {
17 + $defaults = array(
18 + 'form_id' => 0,
19 + 'entry_id' => 0,
20 + 'page_id' => 0
21 + );
22 +
23 + $this->args = wp_parse_args( $args, $defaults );
24 + }
25 +
26 + /**
27 + * Send notifications
28 + *
29 + * @return void
30 + */
31 + public function send_notifications() {
32 + $notifications = $this->get_active_notifications();
33 +
34 + if ( !$notifications ) {
35 + return;
36 + }
37 +
38 + $this->set_merge_tags();
39 +
40 + foreach ($notifications as $notification) {
41 + $this->send_notification( $notification );
42 + }
43 + }
44 +
45 + /**
46 + * Send a single notification
47 + *
48 + * @param array $notification
49 + *
50 + * @return void
51 + */
52 + public function send_notification( $notification ) {
53 + $headers = array();
54 +
55 + $to = $this->replace_tags( $notification['to'] );
56 +
57 + $subject = $this->replace_tags( $notification['subject'] );
58 + $subject = static::replace_name_tag( $subject, $this->args['entry_id'] );
59 +
60 + $message = $this->replace_tags( $notification['message'] );
61 + $message = static::replace_name_tag( $message, $this->args['entry_id'] );
62 + $message = $this->replace_all_fields( $message );
63 + $message = wpautop( $message );
64 +
65 + $fromName = $this->replace_tags( $notification['fromName'] );
66 + $fromName = static::replace_name_tag( $fromName, $this->args['entry_id'] );
67 + $fromAddress = $this->replace_tags( $notification['fromAddress'] );
68 + $replyTo = $this->replace_tags( $notification['replyTo'] );
69 + $cc = $this->replace_tags( $notification['cc'] );
70 + $bcc = $this->replace_tags( $notification['bcc'] );
71 +
72 + if ( $fromName || $fromAddress ) {
73 + $headers['from'] = array(
74 + 'email' => $fromAddress,
75 + 'name' => $fromName
76 + );
77 + }
78 +
79 + if ( $cc ) {
80 + $headers['cc'] = $cc;
81 + }
82 +
83 + if ( $bcc ) {
84 + $headers['bcc'] = $bcc;
85 + }
86 +
87 + if ( $replyTo ) {
88 + $headers['replyto'] = $replyTo;
89 + }
90 +
91 + // content type to text/html
92 + $headers[] = 'Content-Type: text/html; charset=UTF-8';
93 + $email_body = apply_filters( 'weforms_email_message', $this->get_formatted_body( $message ), $notification['message'], $headers );
94 +
95 + weforms()->emailer->send( $to, $subject, $email_body, $headers );
96 + }
97 +
98 + /**
99 + * Get active notifications of a form
100 + *
101 + * @param int $form_id
102 + *
103 + * @return array|boolean
104 + */
105 + public function get_active_notifications() {
106 + $notifications = wpuf_get_form_notifications( $this->args['form_id'] );
107 +
108 + if ( $notifications ) {
109 + $notifications = array_filter( $notifications, function($notification) {
110 + return $notification['active'] == true;
111 + } );
112 +
113 + return $notifications;
114 + }
115 +
116 + return false;
117 + }
118 +
119 + /**
120 + * Get formatted HTML email
121 + *
122 + * @param string $message
123 + *
124 + * @return string
125 + */
126 + public function get_formatted_body( $message ) {
127 + $css = '';
128 + $header = apply_filters( 'weforms_email_header', '' );
129 + $footer = apply_filters( 'weforms_email_footer', '' );
130 +
131 + if ( empty( $header ) ) {
132 + ob_start();
133 + include WEFORMS_INCLUDES . '/email/template/header.php';
134 + $header = ob_get_clean();
135 + }
136 +
137 + if ( empty( $footer ) ) {
138 + ob_start();
139 + include WEFORMS_INCLUDES . '/email/template/footer.php';
140 + $footer = ob_get_clean();
141 + }
142 +
143 + ob_start();
144 + include WEFORMS_INCLUDES . '/email/template/styles.php';
145 + $css = apply_filters( 'weforms_email_styles', ob_get_clean() );
146 +
147 + $content = $header . $message . $footer;
148 +
149 + if ( ! class_exists( 'Emogrifier' ) ) {
150 + require_once WEFORMS_INCLUDES . '/library/Emogrifier.php';
151 + }
152 +
153 + try {
154 +
155 + // apply CSS styles inline for picky email clients
156 + $emogrifier = new Emogrifier( $content, $css );
157 + $content = $emogrifier->emogrify();
158 +
159 + } catch ( Exception $e ) {
160 +
161 + echo $e->getMessage();
162 + }
163 +
164 + return $content;
165 + }
166 +
167 + /**
168 + * Populate an key/value pair of search/replace array
169 + *
170 + * @return array
171 + */
172 + public function set_merge_tags() {
173 +
174 + // return early we had a previous array call
175 + if ( $this->merge_tags ) {
176 + return $this->merge_tags;
177 + }
178 +
179 + // populate the key/value array for the first time
180 + $tags = weforms_get_merge_tags();
181 + $replace_array = array();
182 +
183 + foreach ($tags as $section => $child) {
184 +
185 + if ( !$child['tags'] ) {
186 + continue;
187 + }
188 +
189 + foreach ($child['tags'] as $search_key => $label) {
190 + $replace_array[ '{' . $search_key . '}' ] = $this->get_merge_value( $search_key );
191 + }
192 + }
193 +
194 + $this->merge_tags = $replace_array;
195 + }
196 +
197 + /**
198 + * Get a merge tag value based on a tag
199 + *
200 + * @param string $tag
201 + *
202 + * @return string
203 + */
204 + public function get_merge_value( $tag ) {
205 +
206 + switch ( $tag ) {
207 + case 'entry_id':
208 + return $this->args['entry_id'];
209 + break;
210 +
211 + case 'form_id':
212 + return $this->args['form_id'];
213 + break;
214 +
215 + case 'form_name':
216 + return get_post_field( 'post_title', $this->args['form_id'] );
217 + break;
218 +
219 + case 'admin_email':
220 + return get_option( 'admin_email' );
221 + break;
222 +
223 + case 'date':
224 + return date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ) );
225 + break;
226 +
227 + case 'site_name':
228 + return get_bloginfo( 'name' );
229 + break;
230 +
231 + case 'site_url':
232 + return site_url( '/' );
233 + break;
234 +
235 + case 'page_title':
236 + return get_post_field( 'post_title', $this->args['page_id'] );
237 + break;
238 +
239 + case 'ip_address':
240 + return wpuf_get_client_ip();
241 + break;
242 +
243 + case 'user_id':
244 + return get_current_user_id();
245 + break;
246 +
247 + case 'first_name':
248 + return $this->get_user_prop( 'first_name' );
249 + break;
250 +
251 + case 'last_name':
252 + return $this->get_user_prop( 'last_name' );
253 + break;
254 +
255 + case 'display_name':
256 + return $this->get_user_prop( 'display_name' );
257 + break;
258 +
259 + case 'user_email':
260 + return $this->get_user_prop( 'user_email' );
261 + break;
262 +
263 + case 'url_page':
264 + return get_permalink( $this->args['page_id'] );
265 + break;
266 +
267 + case 'url_referer':
268 + return $_SERVER['HTTP_REFERER'];
269 + break;
270 +
271 + case 'url_login':
272 + return wp_login_url();
273 + break;
274 +
275 + case 'url_logout':
276 + return wp_logout_url();
277 + break;
278 +
279 + case 'url_register':
280 + return wp_registration_url();
281 + break;
282 +
283 + case 'url_lost_password':
284 + return wp_lostpassword_url();
285 + break;
286 +
287 + default:
288 + return apply_filters( 'weforms_merge_tag_value', '', $tag, $this->args );
289 + break;
290 + }
291 + }
292 +
293 + /**
294 + * Parse out the custom fields with entry meta values
295 + *
296 + * @param string $text
297 + *
298 + * @return string
299 + */
300 + public static function replace_field_tags( $text, $entry_id ) {
301 + $pattern = '/{field:(\w*)}/';
302 +
303 + preg_match_all( $pattern, $text, $matches );
304 +
305 + // bail out if nothing found to be replaced
306 + if ( !$matches ) {
307 + return $text;
308 + }
309 +
310 + foreach ($matches[1] as $index => $meta_key) {
311 + $meta_value = weforms_get_entry_meta( $entry_id, $meta_key, true );
312 + $text = str_replace( $matches[0][$index], $meta_value, $text );
313 + }
314 +
315 + return $text;
316 + }
317 +
318 + /**
319 + * Replace name tag with required value
320 + *
321 + * @param string $text
322 + *
323 + * @return string
324 + */
325 + public static function replace_name_tag( $text, $entry_id ) {
326 + $pattern = '/{name-(full|first|middle|last):(\w*)}/';
327 +
328 + preg_match_all( $pattern, $text, $matches );
329 +
330 + // bail out if nothing found to be replaced
331 + if ( !$matches[0] ) {
332 + return $text;
333 + }
334 +
335 + list( $search, $fields, $meta_key ) = $matches;
336 +
337 + $meta_value = weforms_get_entry_meta( $entry_id, $meta_key[0], true );
338 + $replace = explode( WPUF_Render_Form::$separator, $meta_value );
339 +
340 + foreach ($search as $index => $search_key) {
341 +
342 + if ( 'first' == $fields[ $index ] ) {
343 +
344 + $text = str_replace( $search_key, $replace[0], $text );
345 +
346 + } elseif ( 'middle' == $fields[ $index ] ) {
347 +
348 + $text = str_replace( $search_key, $replace[1], $text );
349 +
350 + } elseif ( 'last' == $fields[ $index ] ) {
351 +
352 + $text = str_replace( $search_key, $replace[2], $text );
353 +
354 + } else {
355 +
356 + $text = str_replace( $search_key, implode(' ', $replace ), $text );
357 + }
358 +
359 + }
360 +
361 + return $text;
362 + }
363 +
364 + /**
365 + * Get property of a user object with failsafe check
366 + *
367 + * @param string $property
368 + *
369 + * @return string
370 + */
371 + public function get_user_prop( $property ) {
372 + $user = wp_get_current_user();
373 +
374 + if ( $user->ID != 0 ) {
375 + return $user->{$property};
376 + }
377 +
378 + return '';
379 + }
380 +
381 + /**
382 + * Replace text with merge tags
383 + *
384 + * @param string $text
385 + *
386 + * @return text
387 + */
388 + public function replace_tags( $text = '' ) {
389 + $merge_keys = array_keys( $this->merge_tags );
390 + $merge_values = array_values( $this->merge_tags );
391 +
392 + $text = str_replace( $merge_keys, $merge_values, $text );
393 + $text = static::replace_field_tags( $text, $this->args['entry_id'] );
394 +
395 + return $text;
396 + }
397 +
398 + /**
399 + * Replace {all_fields} if found
400 + *
401 + * @param string $text
402 + *
403 + * @return string
404 + */
405 + public function replace_all_fields( $text = '' ) {
406 +
407 + // check if {all_fields} exists
408 + if ( false === strpos( $text, '{all_fields}' ) ) {
409 + return $text;
410 + }
411 +
412 + $data = array();
413 + $fields = weforms_get_form_field_labels( $this->args['form_id'] );
414 +
415 + if ( !$fields ) {
416 + return $text;
417 + }
418 +
419 + foreach ($fields as $meta_key => $field ) {
420 + $value = weforms_get_entry_meta( $this->args['entry_id'], $meta_key, true );
421 +
422 + if ( empty( $value ) ) {
423 + $value = '&mdash;';
424 + }
425 +
426 + if ( $field['type'] == 'textarea' ) {
427 + $data[ $meta_key ] = weforms_format_text( $value );
428 + } elseif( $field['type'] == 'name' ) {
429 + $data[ $meta_key ] = implode( ' ', explode( WPUF_Render_Form::$separator, $value ) );
430 + } else {
431 + $data[ $meta_key ] = $value;
432 + }
433 + }
434 +
435 + $table = '<table width="600" cellpadding="0" cellspacing="0">';
436 + $table .= '<tbody>';
437 +
438 + foreach ($data as $key => $value) {
439 + $table .= '<tr class="field-label">';
440 + $table .= '<th><strong>' . $fields[$key]['label'] . '</strong></th>';
441 + $table .= '</tr>';
442 + $table .= '<tr class="field-value">';
443 + $table .= '<td>';
444 + $table .= $value;
445 + $table .= '</td>';
446 + $table .= '</tr>';
447 + }
448 +
449 + $table .= '</tbody>';
450 + $table .= '</table>';
451 +
452 + $text = str_replace( '{all_fields}', $table, $text );
453 +
454 + return $text;
455 + }
456 +}