PluginProbe
Customize WordPress Emails and Alerts – Better Notifications for WP / 1.9
Customize WordPress Emails and Alerts – Better Notifications for WP v1.9
1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.8 1.8.1 1.8.10 1.8.11 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9 1.9.1 1.9.2 1.9.3 1.9.4 1.9.5 All 81 releases
bnfw / includes / engine / class-bnfw-engine.php

class-bnfw-engine.php in Customize WordPress Emails and Alerts – Better Notifications for WP 1.9, at includes/engine/class-bnfw-engine.php

1,643 lines 57.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * BNFW Engine.
4 *
5 * @since 1.0
6 * @package bnfw
7 */
8
9 defined( 'ABSPATH' ) || exit;
10
11 if ( ! class_exists( 'BNFW_Engine', false ) ) {
12 /**
13 * BNFW Engine class.
14 */
15 class BNFW_Engine {
16
17 /**
18 * Send test email.
19 *
20 * @since 1.2
21 *
22 * @param array $setting Settings.
23 */
24 public function send_test_email( $setting ) {
25 $subject = __( 'Test Email:', 'bnfw' ) . ' ' . $setting['subject'];
26 $message = '<p><strong>' . __( 'This is a test email. All shortcodes below will show in place but not be replaced with content.', 'bnfw' ) . '</strong></p>' . stripslashes( $setting['message'] );
27
28 if ( 'true' !== $setting['disable-autop'] && 'html' === $setting['email-formatting'] ) {
29 $message = wpautop( $message );
30 }
31
32 $current_user = wp_get_current_user();
33 $email = $current_user->user_email;
34
35 $headers = array();
36 if ( 'html' === $setting['email-formatting'] ) {
37 $headers[] = 'Content-type: text/html';
38 $message = apply_filters( 'bnfw_test_email_message', $message, $setting );
39 } elseif ( 'text' === $setting['email-formatting'] ) {
40 $message = wp_strip_all_tags( $message );
41 }
42
43 wp_mail( $email, stripslashes( $subject ), $message, $headers );
44 }
45
46 /**
47 * Send the notification email.
48 *
49 * @since 1.0
50 * @param array $setting Setting options.
51 * @param int $id Id.
52 */
53 public function send_notification( $setting, $id ) {
54 /**
55 * BNFW - Whether notification is disabled?
56 *
57 * @since 1.3.6
58 */
59
60 $notification_disabled = apply_filters( 'bnfw_notification_disabled', ( 'true' === $setting['disabled'] ), $id, $setting );
61
62 if ( ! $notification_disabled ) {
63
64 $subject = $this->handle_shortcodes( $setting['subject'], $setting['notification'], $id );
65 $message = $this->handle_shortcodes( $setting['message'], $setting['notification'], $id );
66 $emails = $this->get_emails( $setting, $id );
67 $headers = $this->get_headers( $emails );
68
69 if ( 'true' !== $setting['disable-autop'] && 'html' === $setting['email-formatting'] ) {
70 $message = wpautop( $message );
71 }
72
73 if ( 'html' === $setting['email-formatting'] ) {
74 $headers[] = 'Content-type: text/html';
75 $message = apply_filters( 'bnfw_notification_message', $message, $setting );
76 } else {
77 $headers[] = 'Content-type: text/plain';
78 if ( 'text' === $setting['email-formatting'] ) {
79 $message = wp_strip_all_tags( $message );
80 }
81 }
82
83 $emails = apply_filters( 'bnfw_emails', $emails, $setting, $id );
84
85 $send = apply_filters( 'bnfw_can_send_email', true, $setting, $emails, $subject, $message, $headers );
86
87 if ( ! $send ) {
88 return;
89 }
90
91 if ( isset( $emails['to'] ) && is_array( $emails['to'] ) ) {
92 foreach ( $emails['to'] as $email ) {
93 wp_mail( $email, stripslashes( $this->handle_global_user_shortcodes( $subject, $email ) ), $this->handle_global_user_shortcodes( $message, $email ), $headers );
94 }
95 }
96 }
97 }
98
99 /**
100 * Send new user registration notification email.
101 *
102 * @since 1.1
103 * @param array $setting Notification setting.
104 * @param object $user User object.
105 * @param string $password_url Plain text password in WP < 4.3 and password url in WP > 4.3.
106 */
107 public function send_registration_email( $setting, $user, $password_url = '' ) {
108 /**
109 * Whether to trigger welcome email notification or not.
110 *
111 * @since 1.7
112 */
113 $trigger_notification = apply_filters( 'bnfw_trigger_welcome-email_notification', true, $setting, $user );
114
115 if ( ! $trigger_notification ) {
116 return;
117 }
118
119 $user_id = $user->ID;
120
121 $subject = $this->handle_shortcodes( $setting['subject'], $setting['notification'], $user_id );
122 $message = $this->handle_shortcodes( $setting['message'], $setting['notification'], $user_id );
123
124 $subject = str_replace( '[password]', $password_url, $subject );
125 $message = str_replace( '[password]', $password_url, $message );
126
127 $subject = str_replace( '[password_url]', $password_url, $subject );
128 $message = str_replace( '[password_url]', $password_url, $message );
129
130 $subject = str_replace( '[password_url_raw]', $password_url, $subject );
131 $message = str_replace( '[password_url_raw]', $password_url, $message );
132
133 $subject = str_replace( '[login_url]', wp_login_url(), $subject );
134 $message = str_replace( '[login_url]', wp_login_url(), $message );
135
136 $subject = str_replace( '[login_url_raw]', wp_login_url(), $subject );
137 $message = str_replace( '[login_url_raw]', wp_login_url(), $message );
138
139 if ( 'true' !== $setting['disable-autop'] && 'html' === $setting['email-formatting'] ) {
140 $message = wpautop( $message );
141 }
142
143 $headers = array();
144 if ( 'html' === $setting['email-formatting'] ) {
145 $headers[] = 'Content-type: text/html';
146 $message = apply_filters( 'bnfw_registration_email_message', $message, $setting );
147 } elseif ( 'text' === $setting['email-formatting'] ) {
148 $message = wp_strip_all_tags( $message );
149 }
150
151 $subject = $this->handle_global_user_shortcodes( $subject, $user->user_email );
152 $message = $this->handle_global_user_shortcodes( $message, $user->user_email );
153 wp_mail( $user->user_email, stripslashes( $subject ), $message, $headers );
154 }
155
156 /**
157 * Send user login notification email.
158 *
159 * @since 1.1
160 * @param array $setting Notification setting.
161 * @param object $user User object.
162 */
163 public function send_user_login_email( $setting, $user ) {
164
165 $trigger_notification = apply_filters( 'bnfw_trigger_user-login_notification', true, $setting, $user );
166
167 if ( ! $trigger_notification ) {
168 return;
169 }
170
171 $user_id = $user->ID;
172
173 $subject = $this->handle_shortcodes( $setting['subject'], $setting['notification'], $user_id );
174 $message = $this->handle_shortcodes( $setting['message'], $setting['notification'], $user_id );
175 $emails = $this->get_emails( $setting, $user_id );
176 $headers = $this->get_headers( $emails );
177
178 if ( 'true' !== $setting['disable-autop'] && 'html' === $setting['email-formatting'] ) {
179 $message = wpautop( $message );
180 }
181
182 if ( 'html' === $setting['email-formatting'] ) {
183 $headers[] = 'Content-type: text/html';
184 $message = apply_filters( 'bnfw_notification_message', $message, $setting );
185 } elseif ( 'text' === $setting['email-formatting'] ) {
186 $message = wp_strip_all_tags( $message );
187 }
188
189 $subject = $this->handle_global_user_shortcodes( $subject, $user->user_email );
190 $message = $this->handle_global_user_shortcodes( $message, $user->user_email );
191
192 wp_mail( $user->user_email, stripslashes( $subject ), $message, $headers );
193 }
194
195 /**
196 * Send user login notification email for admin.
197 *
198 * @since 1.1
199 * @param array $setting Notification setting.
200 * @param object $user User object.
201 */
202 public function send_user_login_email_for_admin( $setting, $user ) {
203
204 $trigger_notification = apply_filters( 'bnfw_trigger_user-login_notification', true, $setting, $user );
205
206 if ( ! $trigger_notification ) {
207 return;
208 }
209 $user_id = $user->ID;
210
211 $this->send_notification( $setting, $user_id );
212 }
213
214 /**
215 * Send comment reply notification email.
216 *
217 * @since 1.3
218 * @param array $setting Notification setting.
219 * @param object $comment Comment object.
220 * @param object $parent_comment Parent comment object.
221 */
222 public function send_comment_reply_email( $setting, $comment, $parent_comment ) {
223 $comment_id = $comment->comment_ID;
224
225 /**
226 * BNFW - Whether notification is disabled?
227 *
228 * @since 1.3.6
229 */
230 $notification_disabled = apply_filters( 'bnfw_notification_disabled', false, $comment_id, $setting );
231
232 if ( ! $notification_disabled ) {
233 $subject = $this->handle_shortcodes( $setting['subject'], $setting['notification'], $comment_id );
234 $message = $this->handle_shortcodes( $setting['message'], $setting['notification'], $comment_id );
235 $headers = array();
236 if ( 'html' === $setting['email-formatting'] ) {
237 $headers[] = 'Content-type: text/html';
238 } elseif ( 'text' === $setting['email-formatting'] ) {
239 $message = wp_strip_all_tags( $message );
240 }
241 if ( 'true' !== $setting['disable-autop'] && 'html' === $setting['email-formatting'] ) {
242 $message = wpautop( $message );
243 $message = apply_filters( 'bnfw_comment_reply_email_message', $message, $setting );
244 }
245
246 $subject = $this->handle_global_user_shortcodes( $subject, $parent_comment->comment_author_email );
247 $message = $this->handle_global_user_shortcodes( $message, $parent_comment->comment_author_email );
248 wp_mail( $parent_comment->comment_author_email, stripslashes( $subject ), $message, $headers );
249 }
250 }
251
252 /**
253 * Send user role changed email.
254 *
255 * @since 1.3.9
256 *
257 * @param array $setting Notification setting.
258 * @param int $user_id User ID.
259 * @param array $old_role Old User Role.
260 * @param array $new_role New User Role.
261 */
262 public function send_user_role_changed_email( $setting, $user_id, $old_role, $new_role ) {
263 $subject = $this->handle_shortcodes( $setting['subject'], $setting['notification'], $user_id );
264 $message = $this->handle_shortcodes( $setting['message'], $setting['notification'], $user_id );
265
266 $subject = $this->handle_user_role_shortcodes( $subject, $old_role, $new_role );
267 $message = $this->handle_user_role_shortcodes( $message, $old_role, $new_role );
268 $headers = array();
269 if ( 'true' !== $setting['disable-autop'] && 'html' === $setting['email-formatting'] ) {
270 $message = wpautop( $message );
271 }
272
273 if ( 'html' === $setting['email-formatting'] ) {
274 $headers[] = 'Content-type: text/html';
275 $message = apply_filters( 'bnfw_user_role_changed_email_message', $message, $setting );
276 } elseif ( 'text' === $setting['email-formatting'] ) {
277 $message = wp_strip_all_tags( $message );
278 }
279
280 $user = get_user_by( 'id', $user_id );
281 $subject = $this->handle_global_user_shortcodes( $subject, $user->user_email );
282 $message = $this->handle_global_user_shortcodes( $message, $user->user_email );
283 wp_mail( $user->user_email, stripslashes( $subject ), $message, $headers );
284 }
285
286 /**
287 * Send user role added support User Role Editor by Members Plugin.
288 *
289 * @since 1.3.9
290 *
291 * @param array $setting Notification setting.
292 * @param int $user_id User ID.
293 * @param array $old_role Old User Role.
294 * @param array $new_role New User Role.
295 */
296 public function send_user_role_added_email( $setting, $user_id, $old_role, $new_role ) {
297 $subject = $this->handle_shortcodes( $setting['subject'], $setting['notification'], $user_id );
298 $message = $this->handle_shortcodes( $setting['message'], $setting['notification'], $user_id );
299
300 $subject = $this->handle_user_added_role_shortcodes( $subject, $old_role, $new_role );
301 $message = $this->handle_user_added_role_shortcodes( $message, $old_role, $new_role );
302
303 $headers = array();
304 if ( 'true' !== $setting['disable-autop'] && 'html' === $setting['email-formatting'] ) {
305 $message = wpautop( $message );
306 }
307
308 if ( 'html' === $setting['email-formatting'] ) {
309 $headers[] = 'Content-type: text/html';
310 $message = apply_filters( 'bnfw_user_role_changed_email_message', $message, $setting );
311 } elseif ( 'text' === $setting['email-formatting'] ) {
312 $message = wp_strip_all_tags( $message );
313 }
314
315 $user = get_user_by( 'id', $user_id );
316
317 $subject = $this->handle_global_user_shortcodes( $subject, $user->user_email );
318 $message = $this->handle_global_user_shortcodes( $message, $user->user_email );
319 wp_mail( $user->user_email, stripslashes( $subject ), $message, $headers );
320 }
321
322 /**
323 * Handle User Role shortcodes.
324 *
325 * @param string $message String that needs shortcode processing.
326 * @param array $old_role Old User Role.
327 * @param array $new_role New User Role.
328 *
329 * @return string Processed string.
330 */
331 public function handle_user_role_shortcodes( $message, $old_role, $new_role ) {
332 $roles = wp_roles();
333
334 $old_role_name = '';
335 $new_role_name = '';
336
337 if ( isset( $roles->role_names[ $old_role ] ) ) {
338 $old_role_name = $roles->role_names[ $old_role ];
339 }
340
341 if ( isset( $roles->role_names[ $new_role ] ) ) {
342 $new_role_name = $roles->role_names[ $new_role ];
343 }
344
345 $message = str_replace( '[user_role_old]', $old_role_name, $message );
346 $message = str_replace( '[user_role_new]', $new_role_name, $message );
347
348 return $message;
349 }
350
351 /**
352 * Handle User Added Role shortcodes.
353 *
354 * @param string $message String that needs shortcode processing.
355 * @param array $old_roles Old User Role.
356 * @param array $new_roles New User Role.
357 *
358 * @return string Processed string.
359 */
360 public function handle_user_added_role_shortcodes( $message, $old_roles, $new_roles ) {
361 $roles = wp_roles();
362 $old_role_name = array();
363 $new_role_name = array();
364
365 foreach ( $old_roles as $key => $old_role ) {
366 if ( isset( $roles->role_names[ $old_role ] ) ) {
367 $old_role_name[] = $roles->role_names[ $old_role ];
368 }
369 }
370 foreach ( $new_roles as $key => $new_role ) {
371 if ( isset( $roles->role_names[ $new_role ] ) ) {
372 $new_role_name[] = $roles->role_names[ $new_role ];
373 }
374 }
375
376 $message = str_replace( '[user_role_old]', implode( ',', $old_role_name ), $message );
377 $message = str_replace( '[user_role_new]', implode( ',', $new_role_name ), $message );
378
379 return $message;
380 }
381
382 /**
383 * Handle shortcodes for filtered data notifications like `password_changed` and `email_changed`.
384 *
385 * @since 1.6
386 *
387 * @param array $email_data Email data.
388 * @param array $setting Notification settings.
389 * @param string|int $extra_data Extra data.
390 *
391 * @return array Modified email data.
392 */
393 public function handle_filtered_data_notification( $email_data, $setting, $extra_data ) {
394 $email_data['message'] = $this->handle_shortcodes( $setting['message'], $setting['notification'], $extra_data );
395 $email_data['subject'] = $this->handle_shortcodes( $setting['subject'], $setting['notification'], $extra_data );
396
397 $email_data['message'] = $this->handle_global_user_shortcodes( $email_data['message'], $email_data['to'] );
398 $email_data['subject'] = $this->handle_global_user_shortcodes( $email_data['subject'], $email_data['to'] );
399
400 if ( 'true' !== $setting['disable-autop'] && 'html' === $setting['email-formatting'] ) {
401 $email_data['message'] = wpautop( $email_data['message'] );
402 }
403 if ( 'html' === $setting['email-formatting'] ) {
404 $headers[] = 'Content-type: text/html';
405 } else {
406 $headers[] = 'Content-type: text/plain';
407 }
408 $email_data['headers'] = $headers;
409
410 return $email_data;
411 }
412
413 /**
414 * Handle shortcodes for core updated notification.
415 *
416 * @since 1.6
417 *
418 * @param array $email_data Email data.
419 * @param array $setting Notification settings.
420 * @param string $type Result of update.
421 *
422 * @return array Modified email data.
423 */
424 public function handle_core_updated_notification( $email_data, $setting, $type ) {
425 $email_data['body'] = $this->handle_shortcodes( $setting['message'], $setting['notification'], $type );
426 $email_data['subject'] = $this->handle_shortcodes( $setting['subject'], $setting['notification'], $type );
427
428 $emails = $this->get_emails( $setting, $type );
429 $headers = $this->get_headers( $emails );
430
431 $email_data['body'] = $this->handle_global_user_shortcodes( $email_data['body'], $emails['to'][0] );
432 $email_data['subject'] = $this->handle_global_user_shortcodes( $email_data['subject'], $emails['to'][0] );
433
434 if ( 'true' !== $setting['disable-autop'] && 'html' === $setting['email-formatting'] ) {
435 $email_data['body'] = wpautop( $email_data['body'] );
436 }
437
438 if ( 'html' === $setting['email-formatting'] ) {
439 $headers[] = 'Content-type: text/html';
440 } else {
441 $headers[] = 'Content-type: text/plain';
442 if ( 'text' === $setting['email-formatting'] ) {
443 $message = wp_strip_all_tags( $message );
444 }
445 }
446
447 $email_data['headers'] = $headers;
448
449 return $email_data;
450 }
451
452 /**
453 * Handle shortcode for password reset email message.
454 *
455 * @since 1.1
456 *
457 * @param string $setting Notification settings.
458 * @param string $key The activation key.
459 * @param string $user_login The username for the user.
460 * @param WP_User $user_data WP_User object.
461 *
462 * @return mixed|string
463 */
464 public function handle_password_reset_shortcodes( $setting, $key, $user_login, $user_data ) {
465 $message = '';
466
467 if ( '' !== $user_login ) {
468 // For WordPress version 4.1.0 or less, we could have empty user_login.
469 $message = $this->handle_shortcodes( $setting['message'], 'user-password', $user_data->ID );
470 $message = $this->handle_global_user_shortcodes( $message, $user_data->user_email );
471
472 $reset_link = network_site_url( "wp-login.php?action=rp&key=$key&login=" . rawurlencode( $user_login ), 'login' );
473 $message = str_replace( '[password_reset_link]', $reset_link, $message );
474 }
475
476 return $message;
477 }
478
479 /**
480 * Send Password Changed email.
481 *
482 * @param array $setting Notification Setting.
483 * @param WP_User $user User for whom the password has changed.
484 */
485 public function send_password_changed_email( $setting, $user ) {
486 $user_id = $user->ID;
487
488 $subject = $this->handle_shortcodes( $setting['subject'], $setting['notification'], $user_id );
489 $message = $this->handle_shortcodes( $setting['message'], $setting['notification'], $user_id );
490
491 if ( 'true' !== $setting['disable-autop'] && 'html' === $setting['email-formatting'] ) {
492 $message = wpautop( $message );
493 }
494
495 $headers = array();
496 if ( 'html' === $setting['email-formatting'] ) {
497 $headers[] = 'Content-type: text/html';
498 } elseif ( 'text' === $setting['email-formatting'] ) {
499 $message = wp_strip_all_tags( $message );
500 }
501
502 $subject = $this->handle_global_user_shortcodes( $subject, $user->user_email );
503 $message = $this->handle_global_user_shortcodes( $message, $user->user_email );
504 wp_mail( $user->user_email, stripslashes( $subject ), $message, $headers );
505 }
506
507 /**
508 * Generate message for notification.
509 *
510 * @since 1.0
511 * public since @since 1.6
512 *
513 * @param string $message String may have shortcode.
514 * @param string $notification Notification name.
515 * @param string|int $extra_data Additional data for shortcode.
516 *
517 * @return string Processed string.
518 */
519 public function handle_shortcodes( $message, $notification, $extra_data ) {
520
521 switch ( $notification ) {
522 case 'new-comment':
523 case 'new-trackback':
524 case 'new-pingback':
525 case 'reply-comment':
526 // handle new comments, trackbacks and pingbacks.
527 $message = $this->comment_shortcodes( $message, $extra_data );
528 $comment = get_comment( $extra_data );
529 $message = $this->post_shortcodes( $message, $comment->comment_post_ID );
530 if ( 0 !== $comment->user_id ) {
531 $message = $this->user_shortcodes( $message, $comment->user_id );
532 }
533 break;
534
535 case 'admin-password':
536 case 'admin-password-changed':
537 case 'admin-email-changed':
538 case 'admin-user':
539 case 'welcome-email':
540 case 'user-login':
541 $message = $this->user_shortcodes( $message, $extra_data );
542 break;
543 case 'admin-user-login':
544 $message = $this->user_shortcodes( $message, $extra_data );
545 break;
546 case 'new-user':
547 case 'user-role':
548 case 'admin-role':
549 case 'password-changed':
550 // handle users (lost password and new user registration).
551 $message = $this->user_shortcodes( $message, $extra_data );
552 break;
553
554 case 'email-changed':
555 case 'user-password':
556 // handle users (lost password and new user registration).
557 $message = $this->user_shortcodes( $message, $extra_data, 'email_' );
558 break;
559
560 case 'new-category':
561 // handle new category.
562 $message = $this->taxonomy_shortcodes( $message, 'category', $extra_data );
563 break;
564
565 case 'new-post_tag':
566 // handle new tag.
567 $message = $this->taxonomy_shortcodes( $message, 'post_tag', $extra_data );
568 break;
569
570 case 'core-updated':
571 // handle core updated type.
572 $message = $this->core_updated_shortcodes( $message, $extra_data );
573 break;
574
575 case 'data-export':
576 // handle data export email.
577 $message = $this->data_export_shortcodes( $message, $extra_data );
578 break;
579
580 case 'data-erased':
581 // handle data export email.
582 $message = $this->data_erased_shortcodes( $message, $extra_data );
583 break;
584
585 case 'new-media':
586 case 'update-media':
587 $message = $this->post_shortcodes( $message, $extra_data );
588 $post = get_post( $extra_data );
589 if ( $post instanceof WP_Post ) {
590 $message = $this->user_shortcodes( $message, $post->post_author );
591 }
592 break;
593
594 default:
595 $type = explode( '-', $notification, 2 );
596 if ( 'newterm' === $type[0] ) {
597 // handle new terms.
598 $message = $this->taxonomy_shortcodes( $message, $type[1], $extra_data );
599 } elseif ( 'new' === $type[0] || 'update' === $type[0] || 'pending' === $type[0] || 'future' === $type[0] || 'private' === $type[0] || 'trash' === $type[0] ) {
600 // handle new, update and pending posts.
601 $post_types = get_post_types( array( 'public' => true ), 'names' );
602 $post_types = array_diff( $post_types, array( BNFW_Notification::POST_TYPE ) );
603
604 if ( in_array( $type[1], $post_types, true ) ) {
605 $message = $this->post_shortcodes( $message, $extra_data );
606 $post = get_post( $extra_data );
607 if ( $post instanceof WP_Post ) {
608 $message = $this->user_shortcodes( $message, $post->post_author );
609 }
610 }
611 } elseif ( 'comment' === $type[0] || 'moderate' === $type[0] || 'commentreply' === $type[0] ) {
612 $message = $this->comment_shortcodes( $message, $extra_data );
613 $comment = get_comment( $extra_data );
614 $message = $this->post_shortcodes( $message, $comment->comment_post_ID );
615 if ( 0 !== $comment->user_id ) {
616 $message = $this->user_shortcodes( $message, $comment->user_id );
617 }
618 } elseif ( 'approve' === $type[0] ) {
619 // handle Approve comments notification.
620 $message = $this->comment_shortcodes( $message, $extra_data );
621 $comment = get_comment( $extra_data );
622 $message = $this->post_shortcodes( $message, $comment->comment_post_ID );
623 if ( 0 !== $comment->user_id ) {
624 $message = $this->user_shortcodes( $message, $comment->user_id );
625 }
626 break;
627 } elseif ( 'ca' === $type[0] ) {
628 $message = $this->confirm_action_shortcodes( $message, $extra_data );
629 $message = $this->handle_global_user_shortcodes( $message, $extra_data['email'] );
630 } elseif ( 'uc' === $type[0] ) {
631 $message = $this->confirmed_action_shortcodes( $message, $extra_data );
632 $message = $this->handle_global_user_shortcodes( $message, $extra_data['admin_email'] );
633 }
634 break;
635 }
636
637 $message = $this->global_shortcodes( $message );
638
639 $message = apply_filters( 'bnfw_shortcodes', $message, $notification, $extra_data, $this );
640 return $message;
641 }
642
643 /**
644 * Handle Global shortcodes.
645 *
646 * @since 1.5
647 *
648 * @param string $message String with shortcodes.
649 *
650 * @return string String after processing global shortcodes.
651 */
652 private function global_shortcodes( $message ) {
653 $message = str_replace( '[global_site_title]', get_bloginfo( 'name' ), $message );
654 $message = str_replace( '[global_site_tagline]', get_bloginfo( 'description' ), $message );
655 $message = str_replace( '[global_site_url]', get_bloginfo( 'url' ), $message );
656
657 $message = str_replace( '[current_time]', current_time( get_option( 'time_format' ) ), $message );
658 $message = str_replace( '[current_date]', date_i18n( get_option( 'date_format' ), current_time( 'timestamp' ) ), $message );
659 $message = str_replace( '[admin_email]', get_option( 'admin_email' ), $message );
660
661 return $message;
662 }
663
664 /**
665 * Handle Global shortcodes.
666 *
667 * @param string $message Message.
668 * @param string $email Email.
669 *
670 * @return string
671 */
672 public function handle_global_shortcodes( $message, $email ) {
673 $message = $this->global_shortcodes( $message );
674
675 return $this->handle_global_user_shortcodes( $message, $email );
676 }
677
678 /**
679 * Handle Global User Shortcodes.
680 *
681 * @param string $message String to be processed.
682 * @param string $email Email of the user.
683 *
684 * @return string Processed string.
685 */
686 public function handle_global_user_shortcodes( $message, $email ) {
687 $user = get_user_by( 'email', $email );
688
689 if ( false === $user ) {
690 $message = str_replace( '[global_user_firstname]', $email, $message );
691 $message = str_replace( '[global_user_lastname]', $email, $message );
692 $message = str_replace( '[global_user_username]', $email, $message );
693 } else {
694 $message = str_replace( '[global_user_firstname]', $user->first_name, $message );
695 $message = str_replace( '[global_user_lastname]', $user->last_name, $message );
696 $message = str_replace( '[global_user_username]', $user->user_login, $message );
697
698 $message = $this->user_shortcodes( $message, $user->ID, 'email_' );
699 }
700
701 $message = str_replace( '[privacy_policy_url]', get_privacy_policy_url(), $message );
702
703 $message = str_replace( array( '[global_user_email]', '[user_email]' ), $email, $message );
704
705 return $message;
706 }
707
708 /**
709 * Handle media post shortcodes.
710 *
711 * @since 1.0
712 * @param string $message Message.
713 * @param WP_Post $post post object.
714 * @return string
715 */
716 public function media_post_shortcodes( $message, $post ) {
717 $post_content = $this->may_be_strip_shortcode( $post->post_content );
718 $post_content = apply_filters( 'the_content', $post_content );
719 $post_content = str_replace( ']]>', ']]&gt;', $post_content );
720 $message = str_replace( '[ID]', $post->ID, $message );
721 $message = str_replace( '[media_date]', bnfw_format_date( $post->post_date ), $message );
722 $message = str_replace( '[media_date_gmt]', bnfw_format_date( $post->post_date_gmt ), $message );
723 $message = str_replace( '[media_description]', $post_content, $message );
724 $message = str_replace( '[media_title]', $post->post_title, $message );
725 $message = str_replace( '[media_alt_text]', get_post_meta( $post->ID, '_wp_attachment_image_alt', true ), $message );
726 $message = str_replace( '[media_caption]', $this->may_be_strip_shortcode( get_the_excerpt( $post ) ), $message );
727 $message = str_replace( '[media_status]', $post->post_status, $message );
728 $message = str_replace( '[media_modified]', bnfw_format_date( $post->post_modified ), $message );
729 $message = str_replace( '[media_modified_gmt]', bnfw_format_date( $post->post_modified_gmt ), $message );
730 $message = str_replace( '[media_content_filtered]', $post->post_content_filtered, $message );
731 $message = str_replace( '[media_type]', $post->post_type, $message );
732 $message = str_replace( '[media_mime_type]', $post->post_mime_type, $message );
733 $message = str_replace( '[media_slug]', $post->post_name, $message );
734 $dimensions = get_post_meta( $post->ID, '_wp_attachment_metadata', true );
735 $media_dimensions = $dimensions['width'] . ' x ' . $dimensions['height'];
736 $message = str_replace( '[media_dimensions]', $media_dimensions, $message );
737 $user_info = get_userdata( $post->post_author );
738 $message = str_replace( '[media_author]', $user_info->display_name, $message );
739
740 return $message;
741 }
742
743 /**
744 * Handle post shortcodes.
745 *
746 * @since 1.0
747 * @param string $message String to be processed.
748 * @param int $post_id Post id.
749 * @return string
750 */
751 public function post_shortcodes( $message, $post_id ) {
752 $post = get_post( $post_id );
753
754 if ( ! $post instanceof WP_Post ) {
755 return $message;
756 }
757
758 if ( 'attachment' === $post->post_type ) {
759 $message = $this->media_post_shortcodes( $message, $post );
760 }
761
762 $post_content = $this->may_be_strip_shortcode( $post->post_content );
763 $post_content = apply_filters( 'the_content', $post_content );
764 $post_content = str_replace( ']]>', ']]&gt;', $post_content );
765
766 $message = str_replace( '[ID]', $post->ID, $message );
767 $message = str_replace( '[post_date]', bnfw_format_date( $post->post_date ), $message );
768 $message = str_replace( '[post_date_gmt]', bnfw_format_date( $post->post_date_gmt ), $message );
769 $message = str_replace( '[post_content]', $post_content, $message );
770 $message = str_replace( '[post_title]', $post->post_title, $message );
771 $message = str_replace( '[post_excerpt]', $this->may_be_strip_shortcode( get_the_excerpt( $post ) ), $message );
772 $message = str_replace( '[post_status]', $post->post_status, $message );
773 $message = str_replace( '[comment_status]', $post->comment_status, $message );
774 $message = str_replace( '[ping_status]', $post->ping_status, $message );
775 $message = str_replace( '[post_password]', $post->post_password, $message );
776 $message = str_replace( '[post_name]', $post->post_name, $message );
777 $message = str_replace( '[post_slug]', $post->post_name, $message );
778 $message = str_replace( '[to_ping]', $post->to_ping, $message );
779 $message = str_replace( '[pinged]', $post->pinged, $message );
780 $message = str_replace( '[post_modified]', bnfw_format_date( $post->post_modified ), $message );
781 $message = str_replace( '[post_modified_gmt]', bnfw_format_date( $post->post_modified_gmt ), $message );
782 $message = str_replace( '[post_content_filtered]', $post->post_content_filtered, $message );
783 $message = str_replace( '[post_parent]', $post->post_parent, $message );
784 $message = str_replace( '[post_parent_permalink]', get_permalink( $post->post_parent ), $message );
785 $message = str_replace( '[guid]', $post->guid, $message );
786 $message = str_replace( '[menu_order]', $post->menu_order, $message );
787 $message = str_replace( '[post_type]', $post->post_type, $message );
788 $message = str_replace( '[post_mime_type]', $post->post_mime_type, $message );
789 $message = str_replace( '[comment_count]', $post->comment_count, $message );
790 $message = str_replace( '[permalink]', get_permalink( $post->ID ), $message );
791 $message = str_replace( '[post_type_archive]', get_post_type_archive_link( $post->post_type ), $message );
792
793 $message = str_replace( '[edit_post]', $this->get_edit_post_link( $post->ID, 'return' ), $message );
794
795 $featured_image = '';
796 if ( has_post_thumbnail( $post->ID ) ) {
797 $image_url = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'single-post-thumbnail' );
798 if ( is_array( $image_url ) ) {
799 $featured_image = $image_url[0];
800 }
801 }
802 $message = str_replace( '[featured_image]', $featured_image, $message );
803
804 $message = str_replace( '[first_image]', $this->get_first_image( $post->post_content ), $message );
805
806 if ( 'future' === $post->post_status ) {
807 $message = str_replace( '[post_scheduled_date]', bnfw_format_date( $post->post_date ), $message );
808 $message = str_replace( '[post_scheduled_date_gmt]', bnfw_format_date( $post->post_date_gmt ), $message );
809 } else {
810 $message = str_replace( '[post_scheduled_date]', 'Published', $message );
811 $message = str_replace( '[post_scheduled_date_gmt]', 'Published', $message );
812 }
813
814 $categories = wp_get_post_categories( $post_id, array( 'fields' => 'all' ) );
815
816 $message = str_replace( '[post_category]', implode( ', ', wp_list_pluck( $categories, 'name' ) ), $message );
817
818 if ( count( $categories ) > 0 ) {
819 $message = str_replace(
820 array(
821 '[post_category_slug]',
822 '[post_category_description]',
823 ),
824 array(
825 $categories[0]->slug,
826 $categories[0]->description,
827 ),
828 $message
829 );
830 }
831
832 $tag_list = implode( ', ', wp_get_post_tags( $post_id, array( 'fields' => 'names' ) ) );
833 $message = str_replace( '[post_tag]', $tag_list, $message );
834
835 $user_info = get_userdata( $post->post_author );
836 $message = str_replace( '[post_author]', $user_info->display_name, $message );
837
838 $message = str_replace( '[author_link]', get_author_posts_url( $post->post_author ), $message );
839 $last_id = get_post_meta( $post->ID, '_edit_lock', true );
840 if ( $last_id ) {
841 $last_id = explode( ':', $last_id );
842 if ( count( $last_id ) > 1 ) {
843 $last_id = end( $last_id );
844 }
845
846 if ( $post->post_author !== $last_id ) {
847 $last_user_info = get_userdata( $last_id );
848 } else {
849 $last_user_info = $user_info;
850 }
851
852 $message = str_replace( '[post_update_author]', $last_user_info->display_name, $message );
853 }
854
855 $message = str_replace( '[post_term', '[post_term id="' . $post_id . '"', $message );
856 add_shortcode( 'post_term', array( $this, 'post_term_shortcode_handler' ) );
857 $message = do_shortcode( $message );
858 remove_shortcode( 'post_term', array( $this, 'post_term_shortcode_handler' ) );
859
860 return apply_filters( 'bnfw_shortcodes_post', $message, $post_id );
861 }
862
863 /**
864 * Retrieves the edit post link for post.
865 *
866 * This is a copy of the built-in function without the user check.
867 *
868 * Can be used within the WordPress loop or outside of it. Can be used with
869 * pages, posts, attachments, and revisions.
870 *
871 * @param int|WP_Post $id Optional. Post ID or post object. Default is the global `$post`.
872 * @param string $context Optional. How to output the '&' character. Default '&amp;'.
873 * @return string|null The edit post link for the given post. null if the post type is invalid or does
874 * not allow an editing UI.
875 */
876 public function get_edit_post_link( $id = 0, $context = 'display' ) {
877 $post = get_post( $id );
878 if ( ! $post ) {
879 return;
880 }
881
882 if ( 'revision' === $post->post_type ) {
883 $action = '';
884 } elseif ( 'display' === $context ) {
885 $action = '&amp;action=edit';
886 } else {
887 $action = '&action=edit';
888 }
889
890 $post_type_object = get_post_type_object( $post->post_type );
891 if ( ! $post_type_object ) {
892 return;
893 }
894
895 if ( $post_type_object->_edit_link ) {
896 $link = admin_url( sprintf( $post_type_object->_edit_link . $action, $post->ID ) );
897 } else {
898 $link = '';
899 }
900
901 /**
902 * Filters the post edit link.
903 *
904 * @since 2.3.0
905 *
906 * @param string $link The edit link.
907 * @param int $post_id Post ID.
908 * @param string $context The link context. If set to 'display' then ampersands
909 * are encoded.
910 */
911 return apply_filters( 'get_edit_post_link', $link, $post->ID, $context );
912 }
913
914 /**
915 * Handle post term shortcode.
916 *
917 * @param array $atts Shortocde attributes.
918 *
919 * @return string Processed string.
920 */
921 public function post_term_shortcode_handler( $atts ) {
922 $atts = shortcode_atts(
923 array(
924 'taxonomy' => '',
925 'id' => 0,
926 ),
927 $atts
928 );
929
930 $terms = wp_get_post_terms( $atts['id'], $atts['taxonomy'], array( 'fields' => 'names' ) );
931
932 if ( ! is_wp_error( $terms ) ) {
933 return implode( ', ', $terms );
934 }
935
936 return '';
937 }
938
939 /**
940 * Strip shortcodes, unless disabled.
941 *
942 * @param string $content Content who's shortcodes should be stripped.
943 *
944 * @return string Processed content.
945 */
946 private function may_be_strip_shortcode( $content ) {
947 $enable_shortcode = get_option( 'bnfw_enable_shortcodes' );
948
949 if ( '1' === $enable_shortcode ) {
950 return $content;
951 }
952
953 return strip_shortcodes( $content );
954 }
955
956 /**
957 * Handle comment shortcodes.
958 *
959 * @since 1.0
960 *
961 * @param string $message String to be processed.
962 * @param int $comment_id Comment id.
963 *
964 * @return string Processed string.
965 */
966 private function comment_shortcodes( $message, $comment_id ) {
967 $comment = get_comment( $comment_id );
968
969 $message = str_replace( '[comment_ID]', $comment->comment_ID, $message );
970 $message = str_replace( '[comment_post_ID]', $comment->comment_post_ID, $message );
971 $message = str_replace( '[comment_author]', $comment->comment_author, $message );
972 $message = str_replace( '[comment_author_email]', $comment->comment_author_email, $message );
973 $message = str_replace( '[comment_author_url]', $comment->comment_author_url, $message );
974 $message = str_replace( '[comment_author_IP]', $comment->comment_author_IP, $message );
975 $message = str_replace( '[comment_date]', bnfw_format_date( $comment->comment_date ), $message );
976 $message = str_replace( '[comment_date_gmt]', bnfw_format_date( $comment->comment_date_gmt ), $message );
977 $message = str_replace( '[comment_content]', get_comment_text( $comment->comment_ID ), $message );
978 $message = str_replace( '[comment_karma]', $comment->comment_karma, $message );
979 $message = str_replace( '[comment_approved]', str_replace( array( '0', '1', 'spam' ), array( 'Awaiting Moderation', 'Approved', 'Spam' ), $comment->comment_approved ), $message );
980 $message = str_replace( '[comment_agent]', $comment->comment_agent, $message );
981 $message = str_replace( '[comment_type]', $comment->comment_type, $message );
982 $message = str_replace( '[comment_parent]', $comment->comment_parent, $message );
983 $message = str_replace( '[user_id]', $comment->user_id, $message );
984 $message = str_replace( '[permalink]', get_comment_link( $comment->comment_ID ), $message );
985 $message = str_replace( '[comment_moderation_link]', admin_url( 'comment.php?action=editcomment&c=' ) . $comment->comment_ID, $message );
986 $message = str_replace( '[comment_moderation_approve]', '<a href="' . wp_nonce_url( admin_url( "comment.php?action=approve&c={$comment->comment_ID}#wpbody-content" ) ) . '">Approve</a>', $message );
987 $message = str_replace( '[comment_moderation_spam]', '<a href="' . wp_nonce_url( admin_url( "comment.php?action=spam&c={$comment->comment_ID}#wpbody-content" ) ) . '">Spam</a>', $message );
988 $message = str_replace( '[comment_moderation_delete]', '<a href="' . wp_nonce_url( admin_url( "comment.php?action=trash&c={$comment->comment_ID}#wpbody-content" ) ) . '">Delete</a>', $message );
989
990 $parent_comment = get_comment( $comment->comment_parent );
991 if ( $parent_comment instanceof WP_Comment ) {
992 $message = str_replace( '[comment_parent_content]', $parent_comment->comment_content, $message );
993 }
994
995 return $message;
996 }
997
998 /**
999 * Handle user shortcodes.
1000 *
1001 * @since 1.0
1002 *
1003 * @param string $message String to be processed.
1004 * @param int $user_id User id.
1005 * @param string $prefix Prefix.
1006 *
1007 * @return string Processed string.
1008 */
1009 public function user_shortcodes( $message, $user_id, $prefix = '' ) {
1010 global $wp_roles;
1011
1012 $user_info = get_userdata( $user_id );
1013
1014 if ( ! $user_info instanceof WP_User ) {
1015 return $message;
1016 }
1017
1018 // deprecated.
1019 $message = str_replace( '[ID]', $user_info->ID, $message );
1020 $message = str_replace( '[display_name]', $user_info->display_name, $message );
1021 $message = str_replace( '[nickname]', $user_info->nickname, $message );
1022 $message = str_replace( '[commenter_avatar]', get_avatar_url( $user_id ), $message );
1023
1024 $message = str_replace( '[' . $prefix . 'user_id]', $user_info->ID, $message );
1025 $message = str_replace( '[' . $prefix . 'user_login]', $user_info->user_login, $message );
1026 $message = str_replace( '[' . $prefix . 'user_nicename]', $user_info->user_nicename, $message );
1027 $message = str_replace( '[' . $prefix . 'user_email]', $user_info->user_email, $message );
1028 $message = str_replace( '[' . $prefix . 'user_url]', $user_info->user_url, $message );
1029 $message = str_replace( '[' . $prefix . 'user_registered]', $user_info->user_registered, $message );
1030 $message = str_replace( '[' . $prefix . 'user_display_name]', $user_info->display_name, $message );
1031 $message = str_replace( '[' . $prefix . 'user_firstname]', $user_info->user_firstname, $message );
1032 $message = str_replace( '[' . $prefix . 'user_lastname]', $user_info->user_lastname, $message );
1033 $message = str_replace( '[' . $prefix . 'user_nickname]', $user_info->nickname, $message );
1034 $message = str_replace( '[' . $prefix . 'user_description]', $user_info->user_description, $message );
1035 $message = str_replace( '[' . $prefix . 'user_avatar]', get_avatar_url( $user_id ), $message );
1036
1037 $roles = array_map( array( $this, 'get_role_label_by_name' ), $user_info->roles );
1038 $message = str_replace( '[' . $prefix . 'user_role]', implode( ', ', $roles ), $message );
1039
1040 $user_capabilities = bnfw_format_user_capabilities( $user_info->wp_capabilities );
1041 if ( ! empty( $user_capabilities ) ) {
1042 $message = str_replace( '[wp_capabilities]', $user_capabilities, $message );
1043 $message = str_replace( '[' . $prefix . 'user_wp_capabilities]', $user_capabilities, $message );
1044 }
1045
1046 $message = apply_filters( 'bnfw_shortcodes_user', $message, $user_id, $prefix );
1047 return $message;
1048 }
1049
1050 /**
1051 * Handle taxonomy shortcodes.
1052 *
1053 * @access private
1054 * @since 1.1
1055 *
1056 * @param string $message String to be processed.
1057 * @param string $taxonomy Taxonomy name that `$term` is part of.
1058 * @param int $term_id Term ID.
1059 * @return string
1060 */
1061 private function taxonomy_shortcodes( $message, $taxonomy, $term_id ) {
1062 $term_info = get_term( $term_id, $taxonomy );
1063
1064 $message = str_replace( '[slug]', $term_info->slug, $message );
1065 $message = str_replace( '[name]', $term_info->name, $message );
1066 $message = str_replace( '[description]', $term_info->description, $message );
1067
1068 return $message;
1069 }
1070
1071 /**
1072 * Handle Core Updated Shortcodes.
1073 *
1074 * @since 1.6
1075 *
1076 * @param string $message Original message with shortcodes.
1077 * @param string $type The type of email being sent. Can be one of
1078 * 'success', 'fail', 'manual', 'critical'.
1079 *
1080 * @return string Modified content.
1081 */
1082 private function core_updated_shortcodes( $message, $type ) {
1083 $message = str_replace( '[core_update_status]', $type, $message );
1084
1085 return $message;
1086 }
1087
1088 /**
1089 * Get the list of emails from the notification settings.
1090 *
1091 * @since 1.0
1092 *
1093 * @param array $setting Notification settings.
1094 * @param int $id ID to be processed.
1095 * @param bool $process_post_authors If post author needs to be get notification.
1096 * @param bool $process_exclude_current_user If current user needs to be excluded.
1097 *
1098 * @return array Emails
1099 */
1100 public function get_emails( $setting, $id, $process_post_authors = true, $process_exclude_current_user = true ) {
1101 global $current_user;
1102
1103 $emails = array();
1104
1105 $exclude = null;
1106 if ( $process_exclude_current_user && 'true' === $setting['disable-current-user'] ) {
1107 if ( isset( $current_user->ID ) ) {
1108 $exclude = $current_user->ID;
1109 }
1110 }
1111
1112 $emails['to'] = array();
1113
1114 if ( ! empty( $setting['users'] ) ) {
1115 $emails['to'] = $this->get_emails_from_users( $setting['users'], $exclude, $id, $setting );
1116 }
1117
1118 /**
1119 * BNFW get to emails.
1120 */
1121 if ( $process_post_authors && 'true' === $setting['only-post-author'] ) {
1122 $post_id = $id;
1123
1124 if ( bnfw_is_comment_notification( $setting['notification'] ) ) {
1125 $comment = get_comment( $id );
1126 $post_id = $comment->comment_post_ID;
1127 }
1128
1129 $type = explode( '-', $setting['notification'], 2 );
1130 if ( 'approve' === $type[0] ) {
1131 if ( ! in_array( $comment->comment_author_email, $emails['to'], true ) ) {
1132 $emails['to'][] = $comment->comment_author_email;
1133 }
1134 } else {
1135 if ( 'user-customfield' === $setting['notification'] || 'user-customfieldvalue' === $setting['notification'] ) {
1136 $post_author = $post_id;
1137 } else {
1138 $post_author = get_post_field( 'post_author', $post_id );
1139 }
1140 $author = get_user_by( 'id', $post_author );
1141 if ( false !== $author && $post_author !== $exclude ) {
1142 if ( ! in_array( $author->user_email, $emails['to'], true ) ) {
1143 $emails['to'][] = $author->user_email;
1144 }
1145 }
1146 }
1147 }
1148
1149 if ( 'true' === $setting['show-fields'] ) {
1150 $default_from_field = get_option( 'blogname' ) . ' <' . get_option( 'admin_email' ) . '>';
1151
1152 if ( ! empty( $setting['from-name'] ) && ! empty( $setting['from-email'] ) && is_email( $setting['from-email'] ) ) {
1153 $default_from_field = $setting['from-name'] . ' <' . $setting['from-email'] . '>';
1154 }
1155
1156 /**
1157 * Filter Email From Field.
1158 */
1159 $emails['from'] = apply_filters( 'bnfw_from_field', $default_from_field, $setting, $id, $emails['to'] );
1160
1161 /**
1162 * Filter Reply Name Field.
1163 */
1164 $emails['reply-name'] = apply_filters( 'bnfw_reply_name_field', $setting['reply-name'], $setting, $id, $emails['to'] );
1165
1166 /**
1167 * Filter Reply Email Field.
1168 */
1169 $emails['reply-email'] = apply_filters( 'bnfw_reply_email_field', $setting['reply-email'], $setting, $id, $emails['to'] );
1170
1171 if ( ! empty( $setting['cc'] ) ) {
1172 $emails['cc'] = $this->get_emails_from_users( $setting['cc'], $exclude, $id, $setting );
1173 }
1174
1175 if ( ! empty( $setting['bcc'] ) ) {
1176 $emails['bcc'] = $this->get_emails_from_users( $setting['bcc'], $exclude, $id, $setting );
1177 }
1178 }
1179
1180 $excluded_emails = array();
1181
1182 if ( ! empty( $setting['exclude-users'] ) ) {
1183 $excluded_emails = $this->get_emails_from_users( $setting['exclude-users'] );
1184 }
1185
1186 if ( ! empty( $excluded_emails ) ) {
1187 $emails['to'] = array_diff( $emails['to'], $excluded_emails );
1188
1189 if ( ! empty( $emails['cc'] ) ) {
1190 $emails['cc'] = array_diff( $emails['cc'], $excluded_emails );
1191 }
1192
1193 if ( ! empty( $emails['bcc'] ) ) {
1194 $emails['bcc'] = array_diff( $emails['bcc'], $excluded_emails );
1195 }
1196 }
1197 $emails['to'] = apply_filters( 'bnfw_to_emails', $emails['to'], $setting, $id );
1198
1199 return $emails;
1200 }
1201
1202 /**
1203 * Get emails from users.
1204 *
1205 * @since 1.2
1206 *
1207 * @param array $users Users Array.
1208 * @param int $exclude User id to exclude.
1209 * @param int $post_id Post id.
1210 * @param array $setting Notification setting.
1211 *
1212 * @return array
1213 */
1214 public function get_emails_from_users( $users, $exclude = null, $post_id = 0, $setting = array() ) {
1215 $user_ids = array();
1216 $user_roles = array();
1217 $non_wp_users = array();
1218
1219 if ( empty( $users ) ) {
1220 return array();
1221 }
1222
1223 foreach ( $users as $user ) {
1224 if ( $this->starts_with( $user, 'role-' ) ) {
1225 $user_roles[] = str_replace( 'role-', '', $user );
1226 } elseif ( strpos( $user, '@' ) !== false ) {
1227 $non_wp_users[] = $user;
1228 continue;
1229 } elseif ( absint( $user ) > 0 ) {
1230 $user_ids[] = absint( $user );
1231 } else {
1232 $non_wp_users[] = $user;
1233 }
1234 }
1235
1236 if ( null !== $exclude ) {
1237 $user_ids = array_diff( $user_ids, array( $exclude ) );
1238 }
1239
1240 $emails_from_user_ids = $this->get_emails_from_id( $user_ids );
1241 $emails_from_user_roles = $this->get_emails_from_role( $user_roles, $exclude );
1242
1243 if ( ! empty( $setting ) ) {
1244 // for new comment notifications, we need to use post id instead of comment id.
1245 if ( bnfw_is_comment_notification( $setting['notification'] ) && $post_id ) {
1246 $comment = get_comment( $post_id );
1247 $post_id = $comment->comment_post_ID;
1248 }
1249 }
1250
1251 $non_wp_emails = apply_filters( 'bnfw_non_wp_emails', array(), $non_wp_users, $post_id );
1252
1253 return array_merge( $emails_from_user_roles, $emails_from_user_ids, $non_wp_emails );
1254 }
1255
1256 /**
1257 * Get user emails by user ids.
1258 *
1259 * @since 1.0
1260 *
1261 * @param array $user_ids An array of user IDs.
1262 *
1263 * @return array Emails.
1264 */
1265 private function get_emails_from_id( $user_ids ) {
1266 $email_list = array();
1267 if ( is_array( $user_ids ) && count( $user_ids ) > 0 ) {
1268 $user_query = new WP_User_Query( array( 'include' => $user_ids ) );
1269 foreach ( $user_query->results as $user ) {
1270 $email_list[] = $user->user_email;
1271 }
1272 }
1273 return $email_list;
1274 }
1275
1276 /**
1277 * Get emails of users based on role.
1278 *
1279 * @since 1.0
1280 * @param array $roles User Roles.
1281 * @param int $exclude User id to exclude.
1282 * @return array Email ids
1283 */
1284 private function get_emails_from_role( $roles, $exclude = null ) {
1285 if ( ! is_array( $roles ) ) {
1286 $roles = array( $roles );
1287 }
1288
1289 $email_list = array();
1290 foreach ( $roles as $role ) {
1291 $role_name = $this->get_role_name_by_label( $role );
1292 $users = get_users(
1293 array(
1294 'role' => $role_name,
1295 'fields' => array( 'user_email', 'ID' ),
1296 )
1297 );
1298
1299 foreach ( $users as $user ) {
1300 if ( null !== $exclude ) {
1301 if ( $user->ID === $exclude ) {
1302 continue;
1303 }
1304 }
1305
1306 if ( ! in_array( $user->user_email, $email_list, true ) ) {
1307 $email_list[] = $user->user_email;
1308 }
1309 }
1310 }
1311
1312 return $email_list;
1313 }
1314
1315 /**
1316 * Find if a string starts with another string.
1317 *
1318 * @since 1.2
1319 *
1320 * @param string $haystack The string to search in.
1321 * @param string $needle The substring to search for in the haystack.
1322 *
1323 * @return bool
1324 */
1325 private function starts_with( $haystack, $needle ) {
1326 // search backwards starting from haystack length characters from the end.
1327 return '' === $needle || strrpos( $haystack, $needle, -strlen( $haystack ) ) !== false;
1328 }
1329
1330 /**
1331 * Get User role name by label.
1332 *
1333 * @param mixed $role_label Role label.
1334 *
1335 * @return int|string
1336 */
1337 protected function get_role_name_by_label( $role_label ) {
1338 global $wp_roles;
1339 foreach ( $wp_roles->roles as $role_name => $role_info ) {
1340 if ( $role_label === $role_info['name'] || $role_name === $role_label ) {
1341 return $role_name;
1342 }
1343 }
1344
1345 // There is something wrong.
1346 return '';
1347 }
1348
1349 /**
1350 * Get the lable for a user role from name.
1351 *
1352 * @param string $role_name Role name.
1353 *
1354 * @return string Role Label.
1355 */
1356 public function get_role_label_by_name( $role_name ) {
1357 global $wp_roles;
1358
1359 if ( ! isset( $wp_roles->roles[ $role_name ] ) ) {
1360 return '';
1361 }
1362
1363 return translate_user_role( $wp_roles->roles[ $role_name ]['name'] );
1364 }
1365
1366 /**
1367 * Get first image in post.
1368 *
1369 * @param mixed $post_content Post content.
1370 *
1371 * @return string
1372 */
1373 protected function get_first_image( $post_content ) {
1374 if ( preg_match_all( '/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $post_content, $matches ) ) {
1375 return $matches[1][0];
1376 }
1377 }
1378
1379 /**
1380 * Generate email headers based on the emails.
1381 *
1382 * @since 1.0
1383 * @param array $emails Emails.
1384 * @return array
1385 */
1386 public function get_headers( $emails ) {
1387 $headers = array();
1388
1389 if ( ! empty( $emails['from'] ) ) {
1390 $headers[] = 'From:' . $emails['from'];
1391 }
1392
1393 if ( ! empty( $emails['reply-email'] ) && is_email( $emails['reply-email'] ) ) {
1394 $headers[] = 'Reply-To:' . $emails['reply-name'] . '<' . $emails['reply-email'] . '>';
1395 }
1396
1397 if ( ! empty( $emails['cc'] ) ) {
1398 $headers[] = 'Cc:' . implode( ',', $emails['cc'] );
1399 }
1400 if ( ! empty( $emails['bcc'] ) ) {
1401 $headers[] = 'Bcc:' . implode( ',', $emails['bcc'] );
1402 }
1403
1404 /**
1405 * Filter out mail headers.
1406 *
1407 * @param array $headers Headers.
1408 * @param array $emails Emails.
1409 */
1410 return apply_filters( 'bnfw_mail_headers', $headers, $emails );
1411 }
1412 /**
1413 * Handles user shortcode.
1414 *
1415 * @param string $message String to be processed.
1416 * @param array $setting Notification settings.
1417 * @param array $email_data Email data.
1418 * @return string
1419 */
1420 public function handle_user_request_email_shortcodes( $message, $setting, $email_data ) {
1421 $message = $this->handle_shortcodes( $message, $setting['notification'], $email_data );
1422
1423 return $message;
1424 }
1425 /**
1426 * Handles user confiemd action shortcode.
1427 *
1428 * @param string $message String to be processed.
1429 * @param array $setting Notification settings.
1430 * @param array $email_data Email data.
1431 * @return string
1432 */
1433 public function handle_user_confirmed_action_email_shortcodes( $message, $setting, $email_data ) {
1434 $message = $this->handle_shortcodes( $message, $setting['notification'], $email_data );
1435
1436 return $message;
1437 }
1438 /**
1439 * Handles user export shortcode.
1440 *
1441 * @param string $message String to be processed.
1442 * @param array $setting Notification settings.
1443 * @param int $request_id Request ID.
1444 * @return string
1445 */
1446 public function handle_data_export_email_shortcodes( $message, $setting, $request_id ) {
1447 $message = $this->handle_shortcodes( $message, $setting['notification'], $request_id );
1448 return $message;
1449 }
1450 /**
1451 * Handles user export shortcode.
1452 *
1453 * @param string $message String to be processed.
1454 * @param array $extra_data Extra data.
1455 * @return string
1456 */
1457 protected function confirm_action_shortcodes( $message, $extra_data ) {
1458 $message = $this->data_request_shortcodes( $message, $extra_data );
1459 $message = str_replace( '[request_confirmation_link]', $extra_data['confirm_url'], $message );
1460 if ( isset( $extra_data['email'] ) ) {
1461 $message = str_replace( '[request_email]', $extra_data['email'], $message );
1462 }
1463
1464 if ( isset( $extra_data['user_email'] ) ) {
1465 $message = str_replace( '[request_email]', $extra_data['user_email'], $message );
1466 }
1467
1468 return $message;
1469 }
1470 /**
1471 * Handles user export shortcode.
1472 *
1473 * @param string $message String to be processed.
1474 * @param array $extra_data Extra data.
1475 * @return string
1476 */
1477 protected function confirmed_action_shortcodes( $message, $extra_data ) {
1478 $message = $this->data_request_shortcodes( $message, $extra_data );
1479 $message = str_replace( '[data_privacy_requests_url]', $extra_data['manage_url'], $message );
1480 $message = str_replace( '[request_email]', $extra_data['user_email'], $message );
1481
1482 return $message;
1483 }
1484 /**
1485 * Handles data request shortcode.
1486 *
1487 * @param string $message String to be processed.
1488 * @param array $extra_data Extra data.
1489 * @return string
1490 */
1491 protected function data_request_shortcodes( $message, $extra_data ) {
1492 $message = str_replace( '[data_request_type]', $extra_data['description'], $message );
1493
1494 return $message;
1495 }
1496 /**
1497 * Handles data export shortcode.
1498 *
1499 * @param string $message String to be processed.
1500 * @param int $request_id Resuest ID.
1501 * @return string
1502 */
1503 protected function data_export_shortcodes( $message, $request_id ) {
1504 $export_file_url = get_post_meta( $request_id, '_export_file_url', true );
1505
1506 $export_file_url = 'Download File: ' . $this->get_export_downloadable_url( $request_id );
1507
1508 $message = str_replace( '[data_privacy_download_url]', $export_file_url, $message );
1509
1510 $expiration = apply_filters( 'wp_privacy_export_expiration', 3 * DAY_IN_SECONDS );
1511 $expiration_date = date_i18n( get_option( 'date_format' ), time() + $expiration );
1512 $message = str_replace( '[data_privacy_download_expiry]', $expiration_date, $message );
1513
1514 return $message;
1515 }
1516 /**
1517 * Handles data erased shortcode.
1518 *
1519 * @param string $message String to be processed.
1520 * @param array $extra_data Extra data.
1521 * @return string
1522 */
1523 protected function data_erased_shortcodes( $message, $extra_data ) {
1524 $privacy_policy_url = ( ! isset( $extra_data['privacy_policy_url'] ) ) ? get_privacy_policy_url() : $extra_data['privacy_policy_url'];
1525
1526 $message = str_replace( '[privacy_policy_url]', $privacy_policy_url, $message );
1527 $message = str_replace( '[sitename]', $extra_data['sitename'], $message );
1528
1529 return $message;
1530 }
1531 /**
1532 * Process shortcodes in email.
1533 *
1534 * @param array $email Emails.
1535 * @param int $post_id Post ID.
1536 * @param array $setting Notification settings.
1537 * @param array $to_emails Array of to emails.
1538 *
1539 * @return string
1540 */
1541 public function process_shortcodes_in_email( $email, $post_id, $setting, $to_emails ) {
1542 if ( ! empty( $setting ) ) {
1543 if ( $this->starts_with( $setting['notification'], 'comment-' ) || $this->starts_with( $setting['notification'], 'moderate-' ) ) {
1544 // For new comment notifications, we need to use post id instead of comment id.
1545 $post_id = bnfw_get_post_id_from_comment( $post_id );
1546 }
1547 }
1548
1549 $email = $this->handle_shortcodes( $email, $setting['notification'], $post_id );
1550
1551 if ( is_array( $to_emails ) && ! empty( $to_emails ) ) {
1552 $to_email = $to_emails[0];
1553
1554 $email = $this->handle_global_user_shortcodes( $email, $to_email );
1555 }
1556
1557 $processed_emails = array();
1558 if ( is_email( $email ) ) {
1559 $processed_emails[] = $email;
1560 }
1561
1562 $emails = apply_filters( 'bnfw_non_wp_emails', $processed_emails, array( $email ), $post_id );
1563
1564 if ( empty( $emails ) ) {
1565 return '';
1566 }
1567
1568 return $emails[0];
1569 }
1570
1571 /**
1572 * Check email content type.
1573 *
1574 * @param string $setting Setting.
1575 * @param string $content Content.
1576 *
1577 * @return string Content .
1578 */
1579 public function check_email_content_type( $setting, $content ) {
1580
1581 if ( 'html' === $setting['email-formatting'] ) {
1582 add_filter( 'wp_mail_content_type', array( $this, 'set_html_content_type' ) );
1583 if ( 'true' !== $setting['disable-autop'] ) {
1584 $content = wpautop( $content );
1585 }
1586 } else {
1587 add_filter( 'wp_mail_content_type', array( $this, 'set_text_content_type' ) );
1588 $content = wp_strip_all_tags( $content );
1589 }
1590
1591 return $content;
1592 }
1593
1594 /**
1595 * Set the email formatting to HTML.
1596 *
1597 * @since 1.4
1598 */
1599 public function set_html_content_type() {
1600 return 'text/html';
1601 }
1602
1603 /**
1604 * Set the email formatting to text.
1605 *
1606 * @since 1.4
1607 */
1608 public function set_text_content_type() {
1609 return 'text/plain';
1610 }
1611
1612 /**
1613 * Get user's download URL from data export request.
1614 *
1615 * @since 1.8.4
1616 * @param int $request_id Request ID.
1617 * @return string $download_url | string error message
1618 */
1619 public function get_export_downloadable_url( $request_id = null ) {
1620 if ( ! $request_id ) {
1621 return;
1622 }
1623
1624 global $wpdb;
1625 $table = $wpdb->prefix . 'posts';
1626 $query = 'SELECT ID FROM ' . $table . ' WHERE `post_type` = "user_request" AND `ID` = ' . $request_id;
1627 $query = apply_filters( 'export_downloadable_url_query', $query, $request_id );
1628 $get_id = $wpdb->get_var( $query ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared
1629 $file = get_post_meta( $get_id, '_export_file_name', true );
1630 $upload_url = wp_upload_dir();
1631 $dl_url = $upload_url['baseurl'] . '/wp-personal-data-exports/' . $file;
1632 $dl_url = apply_filters( 'export_downloadable_url_return', $dl_url );
1633
1634 if ( $dl_url ) {
1635 return $dl_url;
1636 } else {
1637 return __( 'Error: Download link is not available please contact support' );
1638 }
1639 }
1640
1641 }
1642 }
1643