PluginProbe
weForms – Easy Drag & Drop Contact Form Builder For WordPress / 1.6.13
weForms – Easy Drag & Drop Contact Form Builder For WordPress v1.6.13
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
weforms / includes / class-notification.php

class-notification.php in weForms – Easy Drag & Drop Contact Form Builder For WordPress 1.6.13, at includes/class-notification.php

714 lines 23.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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 weforms()->emailer->send( $to, $subject, wp_kses_post( htmlspecialchars_decode( $email_body ) ) , $headers );
125 }
126
127 /**
128 * Send a single sms notification
129 *
130 * @param array $notification
131 *
132 * @return void
133 */
134 public function send_sms( $notification ) {
135 if ( !class_exists( 'WeForms_SMS_Notification' ) ) {
136 return;
137 }
138
139 $to = $this->replace_tags( $notification['smsTo'] );
140 $message = $this->replace_tags( $notification['smsText'] );
141 $message = static::replace_name_tag( $message, $this->args['entry_id'] );
142 $message = $this->replace_all_fields( $message );
143
144 $email_body = apply_filters( 'weforms_sms_message', $this->get_formatted_sms_body( $message ) );
145
146 weforms_sms()->send_sms( [ $to ], $message );
147 }
148
149 /**
150 * Check conditional logics
151 *
152 * @param array $notification
153 *
154 * @return bool
155 */
156 public function meet_conditions( $notification ) {
157 $form = weforms()->form->get( $this->args['form_id'] );
158 $entry = $form->entries()->get( $this->args['entry_id'] );
159 $fields = $entry->get_fields();
160
161 $cond = !empty( $notification['weforms_cond'] ) ? $notification['weforms_cond'] : [];
162
163 if ( isset( $cond['condition_status'] ) && 'yes' === $cond['condition_status'] ) {
164 $cond_logic = !empty( $cond['cond_logic'] ) ? $cond['cond_logic'] : 'any';
165
166 if ( !empty( $cond['conditions'] ) && is_array( $cond['conditions'] ) ) {
167 $status = []; // going to store all condition result as boolean
168
169 foreach ( $cond['conditions'] as $k => $condition ) {
170 $field = $fields[$condition['name']];
171 $value = $field['value'];
172 $options = $field['options'];
173 $operator = $condition['operator'] == '=' ? true : false;
174
175 // probably from checkbox
176 if ( is_array( $value ) ) {
177
178 // search by value
179 if ( in_array( $condition['option'], $value ) ) {
180 $status[$k] = $operator ? true : false;
181 } else {
182
183 // search by key
184 foreach ( $value as $single_value ) {
185 if ( $condition['option'] == array_search( $single_value, $options ) ) {
186 $status[$k] = $operator ? true : false;
187
188 break;
189 }
190 }
191 }
192
193 if ( !isset( $status[$k] ) ) {
194 $status[$k] = $operator ? false : true;
195 }
196 } else {
197 if ( $condition['option'] == $value || $condition['option'] == array_search( $value, $options ) ) {
198 $status[$k] = $operator ? true : false;
199 } else {
200 $status[$k] = $operator ? false : true;
201 }
202 }
203 }
204
205 if ( $cond_logic == 'any' ) {
206 return in_array( true, $status ) ? true : false; // any true? then true
207 } elseif ( $cond_logic == 'all' ) {
208 return in_array( false, $status ) ? false : true; // any false? then false
209 }
210 }
211 }
212
213 return true;
214 }
215
216 /**
217 * Get active notifications of a form
218 *
219 * @param int $form_id
220 *
221 * @return array|bool
222 */
223 public function get_active_notifications() {
224 $notifications = weforms()->form->get( $this->args['form_id'] )->get_notifications();
225
226 if ( $notifications ) {
227 $notifications = array_filter( $notifications, function ( $notification ) {
228 return $notification['active'] == true;
229 } );
230
231 return $notifications;
232 }
233
234 return false;
235 }
236
237 /**
238 * Get formatted HTML email
239 *
240 * @param string $message
241 *
242 * @return string
243 */
244 public function get_formatted_body( $message ) {
245 $css = '';
246 $header = apply_filters( 'weforms_email_header', '' );
247 $footer = apply_filters( 'weforms_email_footer', '' );
248
249 if ( empty( $header ) ) {
250 ob_start();
251 include WEFORMS_INCLUDES . '/email/template/header.php';
252 $header = ob_get_clean();
253 }
254
255 if ( empty( $footer ) ) {
256 ob_start();
257 include WEFORMS_INCLUDES . '/email/template/footer.php';
258 $footer = ob_get_clean();
259 }
260
261 ob_start();
262 include WEFORMS_INCLUDES . '/email/template/styles.php';
263 $css = apply_filters( 'weforms_email_styles', ob_get_clean() );
264
265 $content = $header . $message . $footer;
266
267 if ( !class_exists( 'Emogrifier' ) ) {
268 require_once WEFORMS_INCLUDES . '/library/Emogrifier.php';
269 }
270
271 try {
272
273 // apply CSS styles inline for picky email clients
274 $emogrifier = new Emogrifier( $content, $css );
275 $content = $emogrifier->emogrify();
276 } catch ( Exception $e ) {
277 echo esc_html( $e->getMessage() );
278 }
279
280 return $content;
281 }
282
283 /**
284 * Get formatted HTML email
285 *
286 * @param string $message
287 *
288 * @return string
289 */
290 public function get_formatted_sms_body( $message ) {
291 $message = strip_tags( $message );
292
293 if ( strlen( $message ) > apply_filters( 'wefroms_sms_char_length', 153 ) ) {
294 $message = substr( $message, 0, apply_filters( 'wefroms_sms_char_length', 153 ) );
295 $message .= __( '..', 'weforms' );
296 }
297
298 return $message;
299 }
300
301 /**
302 * Populate an key/value pair of search/replace array
303 *
304 * @return array
305 */
306 public function set_merge_tags() {
307
308 // return early we had a previous array call
309 if ( $this->merge_tags ) {
310 return $this->merge_tags;
311 }
312
313 // populate the key/value array for the first time
314 $tags = weforms_get_merge_tags();
315 $replace_array = [];
316
317 foreach ( $tags as $section => $child ) {
318 if ( !$child['tags'] ) {
319 continue;
320 }
321
322 foreach ( $child['tags'] as $search_key => $label ) {
323 $replace_array[ '{' . $search_key . '}' ] = $this->get_merge_value( $search_key );
324 }
325 }
326
327 $this->merge_tags = $replace_array;
328 }
329
330 /**
331 * Get a merge tag value based on a tag
332 *
333 * @param string $tag
334 *
335 * @return string
336 */
337 public function get_merge_value( $tag ) {
338 switch ( $tag ) {
339 case 'entry_id':
340 return $this->args['entry_id'];
341 break;
342
343 case 'form_id':
344 return $this->args['form_id'];
345 break;
346
347 case 'form_name':
348 return get_post_field( 'post_title', $this->args['form_id'] );
349 break;
350
351 case 'admin_email':
352 return get_option( 'admin_email' );
353 break;
354
355 case 'date':
356 return date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ) );
357 break;
358
359 case 'site_name':
360 return get_bloginfo( 'name' );
361 break;
362
363 case 'site_url':
364 return site_url( '/' );
365 break;
366
367 case 'page_title':
368 return get_post_field( 'post_title', $this->args['page_id'] );
369 break;
370
371 case 'ip_address':
372 return weforms_get_client_ip();
373 break;
374
375 case 'user_id':
376 return get_current_user_id();
377 break;
378
379 case 'first_name':
380 return $this->get_user_prop( 'first_name' );
381 break;
382
383 case 'last_name':
384 return $this->get_user_prop( 'last_name' );
385 break;
386
387 case 'display_name':
388 return $this->get_user_prop( 'display_name' );
389 break;
390
391 case 'user_email':
392 return $this->get_user_prop( 'user_email' );
393 break;
394
395 case 'url_page':
396 return get_permalink( $this->args['page_id'] );
397 break;
398
399 case 'url_referer':
400 return isset( $_SERVER['HTTP_REFERER'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_REFERER'] ) ) : '';
401 break;
402
403 case 'url_login':
404 return wp_login_url();
405 break;
406
407 case 'url_logout':
408 return wp_logout_url();
409 break;
410
411 case 'url_register':
412 return wp_registration_url();
413 break;
414
415 case 'url_lost_password':
416 return wp_lostpassword_url();
417 break;
418
419 case 'personal_data_erase_confirm_url':
420 $action_type = 'remove_personal_data';
421 $email_address = weforms_get_entry_meta( $this->args['entry_id'], 'user_email_address', true );
422 $request_id = wp_create_user_request( $email_address, $action_type );
423
424 if ( !empty( $email_address ) ) {
425 $confirm_url = add_query_arg(
426 [
427 'action' => 'confirmaction',
428 'request_id' => $request_id,
429 'confirm_key' => wp_generate_user_request_key( $request_id ),
430 ],
431 wp_login_url()
432 );
433
434 return make_clickable( $confirm_url );
435 }
436
437 break;
438
439 case 'personal_data_export_confirm_url':
440 $action_type = 'export_personal_data';
441 $email_address = weforms_get_entry_meta( $this->args['entry_id'], 'user_email_address', true );
442 $request_id = wp_create_user_request( $email_address, $action_type );
443
444 if ( !empty( $email_address ) ) {
445 $confirm_url = add_query_arg(
446 [
447 'action' => 'confirmaction',
448 'request_id' => $request_id,
449 'confirm_key' => wp_generate_user_request_key( $request_id ),
450 ],
451 wp_login_url()
452 );
453
454 return make_clickable( $confirm_url );
455 }
456
457 break;
458
459 default:
460 return apply_filters( 'weforms_merge_tag_value', '', $tag, $this->args );
461 break;
462 }
463 }
464
465 /**
466 * Parse out the custom fields with options or values. Since the options are what is stored, options may need to be
467 * used to find the value from the field settings.
468 *
469 * For example, let's say we have the following options:
470 * DEPARTMENT / EMAIL
471 * Support / support@example.com
472 * Sales / sales@example.com
473 *
474 * Users need the ability to pass {field:department} and get "Support",
475 * and {value:department} to get support@email.com
476 *
477 * @param string $text The text to parse.
478 * @param int $entry_id The entry ID. Optional. Default null if tags to be replaced are on the frontend.
479 *
480 * @return string $text The parsed text.
481 */
482 public static function replace_field_tags( $text, $entry_id = null ) {
483 // Validate data.
484 if ( empty( $text ) || !isset( $entry_id ) ) {
485 return;
486 }
487
488 // Users looking for {field:something} or {value:something}, determine which one.
489 $is_field = preg_match_all( '/{field:(\w*)}/', $text, $matches_field );
490 $is_value = preg_match_all( '/{value:(\w*)}/', $text, $matches_value );
491
492 if ( $is_field ) {
493 $meta_keys = $matches_field[1];
494 // Create an array of meta values to replace.
495 $meta_values = array();
496 foreach ( $meta_keys as $meta_key ) {
497 $meta_value = weforms_get_entry_meta( $entry_id, $meta_key, true );
498 // Add values to the array.
499 array_push( $meta_values, $meta_value );
500 if ( is_array( $meta_value ) ) {
501 $meta_value = implode( WeForms::$field_separator, $meta_value );
502 }
503 }
504 // $text may include HTML tags, only replace tag that was matched. Replace all matches.
505 $text = str_replace( $matches_field[0], $meta_values, $text );
506 }
507 if ( $is_value ) {
508 $meta_keys = $matches_value[1];
509 // Create an array of modified values to replace.
510 $modified_values = array();
511 foreach ( $meta_keys as $meta_key ) {
512 $form_field_values = WeForms_Form_Entry::get_form( $entry_id )->get_field_values()[ $meta_key ]['options'];
513 $meta_value = weforms_get_entry_meta( $entry_id, $meta_key, true );
514 $modified_value = array_search( $meta_value, $form_field_values );
515 // Add values to the array.
516 array_push( $modified_values, $modified_value );
517 if ( is_array( $modified_value ) ) {
518 $modified_value = implode( WeForms::$field_separator, $modified_value );
519 }
520 }
521 // $text may include HTML tags, only replace tag that was matched.
522 $text = str_replace( $matches_value[0], $modified_values, $text );
523 }
524 return $text;
525 }
526
527 /**
528 * Replace name tag with required value
529 *
530 * @param string $text
531 *
532 * @return string
533 */
534 public static function replace_name_tag( $text, $entry_id ) {
535 $pattern = '/{name-(full|first|middle|last):(\w*)}/';
536
537 preg_match_all( $pattern, $text, $matches );
538
539 // bail out if nothing found to be replaced
540 if ( !$matches[0] ) {
541 return $text;
542 }
543
544 list( $search, $fields, $meta_key ) = $matches;
545
546 $meta_value = weforms_get_entry_meta( $entry_id, $meta_key[0], true );
547 $replace = explode( WeForms::$field_separator, $meta_value );
548
549 foreach ( $search as $index => $search_key ) {
550 if ( 'first' == $fields[ $index ] ) {
551 $text = str_replace( $search_key, $replace[0], $text );
552 } elseif ( 'middle' == $fields[ $index ] ) {
553 $text = str_replace( $search_key, $replace[1], $text );
554 } elseif ( 'last' == $fields[ $index ] ) {
555 $text = str_replace( $search_key, $replace[2], $text );
556 } else {
557 $text = str_replace( $search_key, implode( ' ', $replace ), $text );
558 }
559 }
560
561 return $text;
562 }
563
564 /**
565 * Replace image/file tag with Image URL
566 *
567 * @param string $text
568 *
569 * @return string
570 */
571 public static function replace_file_tags( $text, $entry_id ) {
572 $pattern = '/{(?:image|file):(\w*)}/';
573
574 preg_match_all( $pattern, $text, $matches );
575
576 // bail out if nothing found to be replaced
577 if ( !$matches ) {
578 return $text;
579 }
580
581 foreach ( $matches[1] as $index => $meta_key ) {
582 $meta_value = weforms_get_entry_meta( $entry_id, $meta_key, true );
583
584 $files = [];
585
586 if ( is_array( $meta_value ) ) {
587 foreach ( $meta_value as $key => $attachment_id ) {
588 $file_url = wp_get_attachment_url( $attachment_id );
589
590 if ( $file_url ) {
591 $files[] = $file_url;
592 }
593 }
594 } else {
595 $file_url = wp_get_attachment_url( $attachment_id );
596
597 if ( $file_url ) {
598 $files[] = $file_url;
599 }
600 }
601
602 $files = implode( ' ', $files );
603
604 $text = str_replace( $matches[0][$index], $files, $text );
605 }
606
607 return $text;
608 }
609
610 /**
611 * Get property of a user object with failsafe check
612 *
613 * @param string $property
614 *
615 * @return string
616 */
617 public function get_user_prop( $property ) {
618 $user = wp_get_current_user();
619
620 if ( $user->ID != 0 ) {
621 return $user->{$property};
622 }
623
624 return '';
625 }
626
627 /**
628 * Replace text with merge tags
629 *
630 * @param string $text
631 *
632 * @return text
633 */
634 public function replace_tags( $text = '' ) {
635 $merge_keys = array_keys( $this->merge_tags );
636 $merge_values = array_values( $this->merge_tags );
637
638 $text = str_replace( $merge_keys, $merge_values, $text );
639 $text = static::replace_field_tags( $text, $this->args['entry_id'] );
640 $text = static::replace_file_tags( $text, $this->args['entry_id'] );
641
642 return $text;
643 }
644
645 /**
646 * Replace {all_fields} if found
647 *
648 * @param string $text
649 *
650 * @return string
651 */
652 public function replace_all_fields( $text = '' ) {
653
654 // check if {all_fields} exists
655 if ( false === strpos( $text, '{all_fields}' ) ) {
656 return $text;
657 }
658
659 $form = weforms()->form->get( $this->args['form_id'] );
660 $entry = $form->entries()->get( $this->args['entry_id'] );
661 $fields = $entry->get_fields();
662
663 if ( !$fields ) {
664 return $text;
665 }
666
667 $table = '<table width="600" cellpadding="0" cellspacing="0">';
668 $table .= '<tbody>';
669
670 foreach ( $fields as $key => $value ) {
671 $field_value = isset( $value[ 'value' ] ) ? $value[ 'value' ] : '';
672
673 if ( !$field_value ) {
674 continue; // let's skip empty fields
675 }
676
677 $table .= '<tr class="field-label">';
678 $table .= '<td><strong>' . $value['label'] . '</strong></td>';
679 $table .= '</tr>';
680 $table .= '<tr class="field-value">';
681 $table .= '<td>';
682
683 if ( in_array( $value['type'], array( 'multiple_select', 'checkbox_field' ) ) ) {
684 $field_value = is_array( $field_value ) ? $field_value : [];
685
686 if ( $field_value ) {
687 $table .= '<ul>';
688
689 foreach ( $field_value as $value_key ) {
690 $table .= '<li>' . $value_key . '</li>';
691 }
692 $table .= '</ul>';
693 } else {
694 $table .= '&mdash;';
695 }
696 } elseif ( in_array( $value['type'], array( 'google_map' ) ) ) {
697 $table .= $field_value['address'];
698 } else {
699 $table .= $field_value;
700 }
701
702 $table .= '</td>';
703 $table .= '</tr>';
704 }
705
706 $table .= '</tbody>';
707 $table .= '</table>';
708
709 $text = str_replace( '{all_fields}', $table, $text );
710
711 return $text;
712 }
713 }
714