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

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

680 lines 20.9 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 entry meta values
467 *
468 * @param string $text
469 *
470 * @return string
471 */
472 public static function replace_field_tags( $text, $entry_id ) {
473 $pattern = '/{field:(\w*)}/';
474
475 preg_match_all( $pattern, $text, $matches );
476
477 // bail out if nothing found to be replaced
478 if ( !$matches ) {
479 return $text;
480 }
481
482 foreach ( $matches[1] as $index => $meta_key ) {
483 $meta_value = weforms_get_entry_meta( $entry_id, $meta_key, true );
484
485 if ( is_array( $meta_value ) ) {
486 $meta_value = implode( WeForms::$field_separator, $meta_value );
487 }
488
489 $text = str_replace( $matches[0][$index], $meta_value, $text );
490 }
491
492 return $text;
493 }
494
495 /**
496 * Replace name tag with required value
497 *
498 * @param string $text
499 *
500 * @return string
501 */
502 public static function replace_name_tag( $text, $entry_id ) {
503 $pattern = '/{name-(full|first|middle|last):(\w*)}/';
504
505 preg_match_all( $pattern, $text, $matches );
506
507 // bail out if nothing found to be replaced
508 if ( !$matches[0] ) {
509 return $text;
510 }
511
512 list( $search, $fields, $meta_key ) = $matches;
513
514 $meta_value = weforms_get_entry_meta( $entry_id, $meta_key[0], true );
515 $replace = explode( WeForms::$field_separator, $meta_value );
516
517 foreach ( $search as $index => $search_key ) {
518 if ( 'first' == $fields[ $index ] ) {
519 $text = str_replace( $search_key, $replace[0], $text );
520 } elseif ( 'middle' == $fields[ $index ] ) {
521 $text = str_replace( $search_key, $replace[1], $text );
522 } elseif ( 'last' == $fields[ $index ] ) {
523 $text = str_replace( $search_key, $replace[2], $text );
524 } else {
525 $text = str_replace( $search_key, implode( ' ', $replace ), $text );
526 }
527 }
528
529 return $text;
530 }
531
532 /**
533 * Replace image/file tag with Image URL
534 *
535 * @param string $text
536 *
537 * @return string
538 */
539 public static function replace_file_tags( $text, $entry_id ) {
540 $pattern = '/{(?:image|file):(\w*)}/';
541
542 preg_match_all( $pattern, $text, $matches );
543
544 // bail out if nothing found to be replaced
545 if ( !$matches ) {
546 return $text;
547 }
548
549 foreach ( $matches[1] as $index => $meta_key ) {
550 $meta_value = weforms_get_entry_meta( $entry_id, $meta_key, true );
551
552 $files = [];
553
554 if ( is_array( $meta_value ) ) {
555 foreach ( $meta_value as $key => $attachment_id ) {
556 $file_url = wp_get_attachment_url( $attachment_id );
557
558 if ( $file_url ) {
559 $files[] = $file_url;
560 }
561 }
562 } else {
563 $file_url = wp_get_attachment_url( $attachment_id );
564
565 if ( $file_url ) {
566 $files[] = $file_url;
567 }
568 }
569
570 $files = implode( ' ', $files );
571
572 $text = str_replace( $matches[0][$index], $files, $text );
573 }
574
575 return $text;
576 }
577
578 /**
579 * Get property of a user object with failsafe check
580 *
581 * @param string $property
582 *
583 * @return string
584 */
585 public function get_user_prop( $property ) {
586 $user = wp_get_current_user();
587
588 if ( $user->ID != 0 ) {
589 return $user->{$property};
590 }
591
592 return '';
593 }
594
595 /**
596 * Replace text with merge tags
597 *
598 * @param string $text
599 *
600 * @return text
601 */
602 public function replace_tags( $text = '' ) {
603 $merge_keys = array_keys( $this->merge_tags );
604 $merge_values = array_values( $this->merge_tags );
605
606 $text = str_replace( $merge_keys, $merge_values, $text );
607 $text = static::replace_field_tags( $text, $this->args['entry_id'] );
608 $text = static::replace_file_tags( $text, $this->args['entry_id'] );
609
610 return $text;
611 }
612
613 /**
614 * Replace {all_fields} if found
615 *
616 * @param string $text
617 *
618 * @return string
619 */
620 public function replace_all_fields( $text = '' ) {
621
622 // check if {all_fields} exists
623 if ( false === strpos( $text, '{all_fields}' ) ) {
624 return $text;
625 }
626
627 $form = weforms()->form->get( $this->args['form_id'] );
628 $entry = $form->entries()->get( $this->args['entry_id'] );
629 $fields = $entry->get_fields();
630
631 if ( !$fields ) {
632 return $text;
633 }
634
635 $table = '<table width="600" cellpadding="0" cellspacing="0">';
636 $table .= '<tbody>';
637
638 foreach ( $fields as $key => $value ) {
639 $field_value = isset( $value[ 'value' ] ) ? $value[ 'value' ] : '';
640
641 if ( !$field_value ) {
642 continue; // let's skip empty fields
643 }
644
645 $table .= '<tr class="field-label">';
646 $table .= '<th><strong>' . $value['label'] . '</strong></th>';
647 $table .= '</tr>';
648 $table .= '<tr class="field-value">';
649 $table .= '<td>';
650
651 if ( in_array( $value['type'], [ 'multiple_select', 'checkbox_field' ] ) ) {
652 $field_value = is_array( $field_value ) ? $field_value : [];
653
654 if ( $field_value ) {
655 $table .= '<ul>';
656
657 foreach ( $field_value as $value_key ) {
658 $table .= '<li>' . $value_key . '</li>';
659 }
660 $table .= '</ul>';
661 } else {
662 $table .= '&mdash;';
663 }
664 } else {
665 $table .= $field_value;
666 }
667
668 $table .= '</td>';
669 $table .= '</tr>';
670 }
671
672 $table .= '</tbody>';
673 $table .= '</table>';
674
675 $text = str_replace( '{all_fields}', $table, $text );
676
677 return $text;
678 }
679 }
680