PluginProbe
Friends / trunk
Friends vtrunk
4.3.1 4.3.0 4.2.2 4.2.1 4.2.0 4.1.0 2.7.4 2.7.5 2.7.6 2.7.7 2.7.8 2.7.9 2.8.0 2.8.1 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.8.9 2.9.0 2.9.1 2.9.2 All 87 releases
friends / includes / class-notifications.php

class-notifications.php in Friends trunk, at includes/class-notifications.php

691 lines 23.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Friends Notifications
4 *
5 * This contains the functions for Notifications.
6 *
7 * @package Friends
8 */
9
10 namespace Friends;
11
12 /**
13 * This is the class for the Notifications part of the Friends Plugin.
14 *
15 * @since 0.6
16 *
17 * @package Friends
18 * @author Alex Kirk
19 */
20 class Notifications {
21 /**
22 * Contains a reference to the Friends class.
23 *
24 * @var Friends
25 */
26 private $friends;
27
28 /**
29 * Constructor
30 *
31 * @param Friends $friends A reference to the Friends object.
32 */
33 public function __construct( Friends $friends ) {
34 $this->friends = $friends;
35 $this->register_hooks();
36 }
37
38 /**
39 * Register the WordPress hooks
40 */
41 private function register_hooks() {
42 add_filter( 'friends_rewrite_mail_html', array( $this, 'rewrite_mail_html' ) );
43 add_filter( 'friends_rewrite_mail_html', array( $this, 'highlight_keywords' ), 10, 2 );
44 add_action( 'notify_new_friend_post', array( $this, 'notify_new_friend_post' ), 10, 3 );
45 add_filter( 'friends_notify_keyword_match_post', array( $this, 'notify_keyword_match_post' ), 10, 3 );
46 add_action( 'notify_friend_message_received', array( $this, 'notify_friend_message_received' ), 10, 5 );
47 add_action( 'notify_unknown_friend_message_received', array( $this, 'notify_unknown_friend_message_received' ), 10, 4 );
48 add_action( 'activitypub_new_follower_email', array( $this, 'activitypub_new_follower_email' ), 10, 3 );
49 add_action( 'activitypub_followers_post_follow', array( $this, 'activitypub_followers_post_follow' ), 10, 4 );
50 add_action( 'activitypub_followers_pre_remove_follower', array( $this, 'activitypub_followers_pre_remove_follower' ), 10, 3 );
51 }
52
53 /**
54 * Sets the friends plugin from email address when sending mail.
55 *
56 * If you're having issues with the receiver using the envelope From: address in favor of the mail header,
57 * you can use a filter like this:
58 * add_filter( 'wp_mail_from', function( $from ) {
59 * ini_set( 'sendmail_from', $from );
60 * return $from;
61 * }, 100 );
62 *
63 * @param string $from The from that's supposed to be used.
64 *
65 * @return string The friends plugin from email address.
66 */
67 public function use_friends_plugin_from_email_address( $from ) {
68 $from = preg_replace( '/^wordpress@/', 'friends-plugin@', $from );
69 return $from;
70 }
71
72
73 /**
74 * Gets the friends plugin from email address.
75 *
76 * @return string The friends plugin from email address.
77 */
78 public function get_friends_plugin_from_email_address() {
79 add_filter( 'wp_mail_from', array( $this, 'use_friends_plugin_from_email_address' ) );
80 $address = apply_filters( 'wp_mail_from', 'wordpress@' . preg_replace( '#^www\.#', '', wp_parse_url( network_home_url(), PHP_URL_HOST ) ) );
81 remove_filter( 'wp_mail_from', array( $this, 'use_friends_plugin_from_email_address' ) );
82 return $address;
83 }
84
85 /**
86 * Notify the users of this site about a new friend post
87 *
88 * @param \WP_Post $post The new post by a friend or subscription.
89 * @param User_Feed $user_feed The feed where the post came from.
90 * @param string|false $keyword If a post matched a keyword, the keyword is specified.
91 */
92 public function notify_new_friend_post( \WP_Post $post, User_Feed $user_feed, $keyword ) {
93 if (
94 // Post might be trashed through rules.
95 'trash' === $post->post_status
96 // Don't notify about posts older than a week.
97 || strtotime( $post->post_date_gmt ) + WEEK_IN_SECONDS < time()
98 ) {
99 return;
100 }
101 $user = new User( Friends::get_main_friend_user_id() );
102 if ( defined( 'WP_TESTS_EMAIL' ) ) {
103 $user->user_email = WP_TESTS_EMAIL;
104 }
105 if ( ! $user->user_email ) {
106 return;
107 }
108 $author = $user_feed->get_friend_user();
109
110 if ( ! get_post_format( $post ) ) {
111 $post_format = 'standard';
112 } else {
113 $post_format = get_post_format( $post );
114 }
115
116 $notify_user = ! get_user_option( 'friends_no_new_post_notification', $user->ID );
117 $notify_user = $notify_user && ! get_user_option( 'friends_no_new_post_notification_' . $author->user_login, $user->ID );
118 $notify_user = $notify_user && ! get_user_option( 'friends_no_new_post_format_notification_' . $post_format, $user->ID );
119 $notify_user = $notify_user && ! get_user_option( 'friends_no_new_post_by_parser_notification_' . $user_feed->get_parser(), $user->ID );
120
121 // If the post would notify anyway and it was a keyword match, notify that way.
122 if ( $notify_user && $keyword && get_user_option( 'friends_keyword_notification_override_disabled', $user->ID ) ) {
123 add_filter( 'get_user_option_friends_keyword_notification_override_disabled', '__return_false' );
124 $this->notify_keyword_match_post( false, $post, $keyword );
125 remove_filter( 'get_user_option_friends_keyword_notification_override_disabled', '__return_false' );
126 return;
127 }
128
129 if ( ! apply_filters( 'notify_user_about_friend_post', $notify_user, $user, $post, $author ) ) {
130 return;
131 }
132 $email_title = $post->post_title;
133
134 $params = array(
135 'author' => $author,
136 'post' => $post,
137 );
138
139 $email_message = array();
140 ob_start();
141 Friends::template_loader()->get_template_part( 'email/header', null, array( 'email_title' => $email_title ) );
142 Friends::template_loader()->get_template_part( 'email/new-friend-post', null, $params );
143 Friends::template_loader()->get_template_part( 'email/footer' );
144 $email_message['html'] = ob_get_contents();
145 ob_end_clean();
146
147 ob_start();
148 Friends::template_loader()->get_template_part( 'email/new-friend-post-text', null, $params );
149 Friends::template_loader()->get_template_part( 'email/footer-text' );
150 $email_message['text'] = ob_get_contents();
151 ob_end_clean();
152
153 $this->send_mail( $user->user_email, wp_specialchars_decode( $email_title, ENT_QUOTES ), $email_message, array(), array(), $author->user_login );
154 }
155
156 /**
157 * Notifies about a post that matched the keyword.
158 *
159 * @param bool $notified Whether a notification was sent.
160 * @param \WP_Post $post The new post by a friend or subscription.
161 * @param string $keyword The matched keyword.
162 */
163 public function notify_keyword_match_post( $notified, \WP_Post $post, $keyword ) {
164 if ( 'trash' === $post->post_status ) {
165 return $notified;
166 }
167
168 $user = new User( Friends::get_main_friend_user_id() );
169 if ( defined( 'WP_TESTS_EMAIL' ) ) {
170 $user->user_email = WP_TESTS_EMAIL;
171 }
172 if ( ! $user->user_email ) {
173 return $notified;
174 }
175 $notify_user = ! get_user_option( 'friends_no_keyword_notification_' . $post->post_author, $user->ID );
176 // If the override was disabled, don't notify. This could be temporarily disabled later.
177
178 if ( $notify_user && get_user_option( 'friends_keyword_notification_override_disabled', $user->ID ) ) {
179 return $notified;
180 }
181
182 if ( ! apply_filters( 'notify_user_about_keyword_post', $notify_user, $user, $post, $keyword ) ) {
183 return $notified;
184 }
185
186 $author = User::get_post_author( $post );
187 // translators: %s is a keyword string specified by the user.
188 $email_title = sprintf( __( 'Keyword matched: %s', 'friends' ), $keyword );
189
190 $params = array(
191 'author' => $author,
192 'post' => $post,
193 'keyword' => $keyword,
194 );
195
196 $email_message = array();
197 ob_start();
198 Friends::template_loader()->get_template_part( 'email/header', null, array( 'email_title' => $email_title ) );
199 Friends::template_loader()->get_template_part( 'email/keyword-match-post', null, $params );
200 Friends::template_loader()->get_template_part( 'email/footer' );
201 $email_message['html'] = ob_get_contents();
202 ob_end_clean();
203
204 ob_start();
205 Friends::template_loader()->get_template_part( 'email/keyword-match-post-text', null, $params );
206 Friends::template_loader()->get_template_part( 'email/footer-text' );
207 $email_message['text'] = ob_get_contents();
208 ob_end_clean();
209
210 $this->send_mail( $user->user_email, wp_specialchars_decode( $email_title, ENT_QUOTES ), $email_message, array(), array(), $author->user_login );
211
212 return true;
213 }
214
215 /**
216 * Notify the users of this site about a received message
217 *
218 * @param User $friend_user The user who sent the message.
219 * @param string $message The message.
220 * @param string $subject The subject.
221 * @param string $_feed_url The feed URL.
222 * @param string $remote_url The remote message URL.
223 */
224 public function notify_friend_message_received( User $friend_user, $message, $subject, $_feed_url = null, $remote_url = null ) {
225 $user = new User( Friends::get_main_friend_user_id() );
226 if ( defined( 'WP_TESTS_EMAIL' ) ) {
227 $user->user_email = WP_TESTS_EMAIL;
228 }
229 if ( ! $user->user_email ) {
230 return;
231 }
232
233 if ( ! apply_filters( 'notify_user_about_friend_message', true, $user, $friend_user ) ) {
234 return;
235 }
236
237 // translators: %s is a user display name.
238 $email_title = sprintf( __( '%s sent you a message', 'friends' ), $friend_user->display_name );
239
240 $params = array(
241 'user' => $user,
242 'friend_user' => $friend_user,
243 'subject' => $subject,
244 'message' => $message,
245 'message_url' => $this->get_friend_message_url( $friend_user, $remote_url ),
246 );
247
248 $email_message = array();
249 ob_start();
250 Friends::template_loader()->get_template_part( 'email/header', null, array( 'email_title' => $email_title ) );
251 Friends::template_loader()->get_template_part( 'email/friend-message-received', null, $params );
252 Friends::template_loader()->get_template_part( 'email/footer' );
253 $email_message['html'] = ob_get_contents();
254 ob_end_clean();
255
256 ob_start();
257 Friends::template_loader()->get_template_part( 'email/friend-message-received-text', null, $params );
258 Friends::template_loader()->get_template_part( 'email/footer-text' );
259 $email_message['text'] = ob_get_contents();
260 ob_end_clean();
261
262 $this->send_mail( $user->user_email, $email_title, $email_message );
263 }
264
265 /**
266 * Get the URL for replying to a received direct message.
267 *
268 * @param User $friend_user The message sender.
269 * @param string|null $remote_url The remote ActivityPub message URL.
270 * @return string The reply URL.
271 */
272 private function get_friend_message_url( User $friend_user, $remote_url = null ) {
273 if ( $remote_url ) {
274 add_filter( 'friends_frontend_post_types', array( $this, 'friends_frontend_post_types_only_messages' ), 999 );
275 $message_id = Feed::url_to_postid( $remote_url );
276 remove_filter( 'friends_frontend_post_types', array( $this, 'friends_frontend_post_types_only_messages' ), 999 );
277
278 if ( $message_id ) {
279 $message = get_post( $message_id );
280 if ( $message ) {
281 while ( $message && $message->post_parent ) {
282 $message = get_post( $message->post_parent );
283 }
284
285 if ( $message ) {
286 return add_query_arg( 'conversation', $message->ID, home_url( '/friends/messages/' ) );
287 }
288 }
289 }
290 }
291
292 return $friend_user->get_local_friends_page_url();
293 }
294
295 /**
296 * Limit frontend post type lookups to messages.
297 *
298 * @return array The message post type.
299 */
300 public function friends_frontend_post_types_only_messages() {
301 return array( Messages::CPT );
302 }
303
304 /**
305 * Notify the users of this site about a received message
306 *
307 * @param string $sender_name The user who sent the message.
308 * @param string $message The message.
309 * @param string $subject The subject.
310 * @param string $feed_url The url of the user who sent the message.
311 */
312 public function notify_unknown_friend_message_received( $sender_name, $message, $subject, $feed_url ) {
313 $user = new User( Friends::get_main_friend_user_id() );
314 if ( defined( 'WP_TESTS_EMAIL' ) ) {
315 $user->user_email = WP_TESTS_EMAIL;
316 }
317 if ( ! $user->user_email ) {
318 return;
319 }
320
321 if ( ! apply_filters( 'notify_user_about_friend_message', true, $user ) ) {
322 return;
323 }
324
325 // translators: %s is a user display name.
326 $email_title = sprintf( __( '%s sent you a message', 'friends' ), $sender_name );
327
328 $params = array(
329 'user' => $user,
330 'sender_name' => $sender_name,
331 'feed_url' => $feed_url,
332 'subject' => $subject,
333 'message' => $message,
334 );
335
336 $email_message = array();
337 ob_start();
338 Friends::template_loader()->get_template_part( 'email/header', null, array( 'email_title' => $email_title ) );
339 Friends::template_loader()->get_template_part( 'email/unknown-friend-message-received', null, $params );
340 Friends::template_loader()->get_template_part( 'email/footer' );
341 $email_message['html'] = ob_get_contents();
342 ob_end_clean();
343
344 ob_start();
345 Friends::template_loader()->get_template_part( 'email/unknown-friend-message-received-text', null, $params );
346 Friends::template_loader()->get_template_part( 'email/footer-text' );
347 $email_message['text'] = ob_get_contents();
348 ob_end_clean();
349
350 $this->send_mail( $user->user_email, $email_title, $email_message );
351 }
352
353 /**
354 * Augment the ActivityPub new follower e-mail
355 *
356 * @param array $actor The actor.
357 */
358 public function activitypub_new_follower_email( $actor ) {
359 if ( isset( $actor['id'] ) ) {
360 $url = $actor['id'];
361 } elseif ( isset( $actor['url'] ) ) {
362 $url = $actor['url'];
363 } else {
364 return;
365 }
366
367 $url = \ActivityPub\object_to_uri( $url );
368 $server = wp_parse_url( $url, PHP_URL_HOST );
369 $following = User_Feed::get_by_url( $url );
370 if ( ! $following || is_wp_error( $following ) ) {
371 $following = User_Feed::get_by_url( str_replace( '/users/', '/@', $url ) );
372 }
373 if ( $following && ! is_wp_error( $following ) ) {
374 $following = $following->get_friend_user();
375 } else {
376 $following = false;
377 }
378 echo '<p>';
379 if ( $following ) {
380 echo esc_html__( 'You are already following them!', 'friends' );
381 echo ' ';
382 // translators: %s is a URL.
383 echo wp_kses( sprintf( __( 'Go to their <a href="%s">friends page</a> to see what they recently posted about.', 'friends' ), esc_url( $following->get_local_friends_page_url() ) ), array( 'a' => array( 'href' => array() ) ) );
384 } else {
385 // translators: %s is a URL.
386 echo wp_kses( sprintf( __( 'Maybe you want to <a href="%s">follow them back</a> using the Friends plugin?', 'friends' ), esc_url( add_query_arg( 'url', $url, admin_url( 'admin.php?page=add-friend' ) ) ) ), array( 'a' => array( 'href' => array() ) ) );
387 }
388 echo '</p>';
389 }
390
391 /**
392 * Notify of a follower
393 *
394 * @param string $actor The Actor URL.
395 * @param array $activitypub_object The Activity object.
396 * @param int $user_id The ID of the WordPress User.
397 * @param \WP_Post|\Activitypub\Activity\Actor $follower The Actor post (since ActivityPub 7.5.0) or Actor object.
398 *
399 * @return void
400 */
401 public function activitypub_followers_post_follow( $actor, $activitypub_object, $user_id, $follower ) {
402 if ( ! get_user_option( 'friends_no_friend_follower_notification', $user_id ) ) {
403 return;
404 }
405 $user = new User( $user_id );
406 if ( defined( 'WP_TESTS_EMAIL' ) ) {
407 $user->user_email = WP_TESTS_EMAIL;
408 }
409 if ( ! $user->user_email ) {
410 return;
411 }
412
413 if ( is_wp_error( $follower ) ) {
414 return;
415 }
416
417 $follower_post = null;
418 if ( $follower instanceof \WP_Post ) {
419 $follower_post = $follower;
420 $follower = \Activitypub\Collection\Remote_Actors::get_actor( $follower_post );
421 if ( is_wp_error( $follower ) ) {
422 return;
423 }
424 }
425
426 if ( ! apply_filters( 'notify_user_about_new_follower', true, $user, $actor, $activitypub_object, $follower ) ) {
427 return;
428 }
429
430 $url = \ActivityPub\object_to_uri( $follower->get( 'id' ) );
431 $server = wp_parse_url( $url, PHP_URL_HOST );
432 $following = User_Feed::get_by_url( $url );
433 if ( ! $following || is_wp_error( $following ) ) {
434 $following = User_Feed::get_by_url( $follower->get_url() );
435 }
436 if ( $following && ! is_wp_error( $following ) ) {
437 $following = $following->get_friend_user();
438 } else {
439 $following = false;
440 }
441
442 $icon_url = $follower_post
443 ? \Activitypub\Collection\Remote_Actors::get_avatar_url( $follower_post->ID )
444 : \ActivityPub\object_to_uri( $follower->get_icon() );
445
446 // translators: %s is a user display name.
447 $email_title = sprintf( __( 'New Follower: %s', 'friends' ), $follower->get_name() . '@' . $server );
448
449 $params = array(
450 'user' => $user,
451 'url' => $url,
452 'follower' => $follower,
453 'icon_url' => $icon_url,
454 'server' => $server,
455 'following' => $following,
456 );
457
458 $email_message = array();
459 ob_start();
460 Friends::template_loader()->get_template_part( 'email/header', null, array( 'email_title' => $email_title ) );
461 Friends::template_loader()->get_template_part( 'email/new-follower', null, $params );
462 Friends::template_loader()->get_template_part( 'email/footer' );
463 $email_message['html'] = ob_get_contents();
464 ob_end_clean();
465
466 ob_start();
467 Friends::template_loader()->get_template_part( 'email/new-follower-text', null, $params );
468 Friends::template_loader()->get_template_part( 'email/footer-text' );
469 $email_message['text'] = ob_get_contents();
470 ob_end_clean();
471
472 $this->send_mail( $user->user_email, $email_title, $email_message );
473 }
474
475 /**
476 * Notify of a lost follower
477 *
478 * @param \WP_Post|\Activitypub\Activity\Actor $follower The Actor post (since ActivityPub 7.5.0) or Actor object.
479 * @param int $user_id The ID of the WordPress User.
480 * @param string|\Activitypub\Activity\Actor $actor The Actor URL or Actor object.
481 *
482 * @return void
483 */
484 public function activitypub_followers_pre_remove_follower( $follower, $user_id, $actor ) {
485 if ( ! get_user_option( 'friends_no_friend_follower_notification', $user_id ) ) {
486 return;
487 }
488 $user = new User( $user_id );
489 if ( defined( 'WP_TESTS_EMAIL' ) ) {
490 $user->user_email = WP_TESTS_EMAIL;
491 }
492 if ( ! $user->user_email ) {
493 return;
494 }
495
496 $follower_post = null;
497 $published = null;
498 if ( $follower instanceof \WP_Post ) {
499 $follower_post = $follower;
500 $published = $follower_post->post_date_gmt;
501 if ( $actor instanceof \Activitypub\Activity\Actor ) {
502 $follower = $actor;
503 } else {
504 $follower = \Activitypub\Collection\Remote_Actors::get_actor( $follower_post );
505 if ( is_wp_error( $follower ) ) {
506 return;
507 }
508 }
509 } else {
510 $published = $follower->get_published();
511 }
512
513 if ( ! apply_filters( 'notify_user_about_lost_follower', true, $user, $actor, $follower ) ) {
514 return;
515 }
516
517 $url = \ActivityPub\object_to_uri( $follower->get( 'id' ) );
518 $server = wp_parse_url( $url, PHP_URL_HOST );
519
520 $icon_url = $follower_post
521 ? \Activitypub\Collection\Remote_Actors::get_avatar_url( $follower_post->ID )
522 : \ActivityPub\object_to_uri( $follower->get_icon() );
523
524 // translators: %s is a user display name.
525 $email_title = sprintf( __( 'Lost Follower: %s', 'friends' ), $follower->get_name() . '@' . $server );
526
527 $params = array(
528 'user' => $user,
529 'url' => $url,
530 'follower' => $follower,
531 'icon_url' => $icon_url,
532 'server' => $server,
533 'duration' => human_time_diff( strtotime( $published ) ) . ' (' . sprintf(
534 // translators: %s is a time duration.
535 __( 'since %s', 'friends' ),
536 $published
537 ) . ')',
538
539 );
540
541 $email_message = array();
542 ob_start();
543 Friends::template_loader()->get_template_part( 'email/header', null, array( 'email_title' => $email_title ) );
544 Friends::template_loader()->get_template_part( 'email/lost-follower', null, $params );
545 Friends::template_loader()->get_template_part( 'email/footer' );
546 $email_message['html'] = ob_get_contents();
547 ob_end_clean();
548
549 ob_start();
550 Friends::template_loader()->get_template_part( 'email/lost-follower-text', null, $params );
551 Friends::template_loader()->get_template_part( 'email/footer-text' );
552 $email_message['text'] = ob_get_contents();
553 ob_end_clean();
554
555 $this->send_mail( $user->user_email, $email_title, $email_message );
556 }
557
558 /**
559 * Rewrite HTML for e-mail (by inlining some CSS styles)
560 *
561 * @param string $html The HTML.
562 *
563 * @return string The rewritten HTML.
564 */
565 public function rewrite_mail_html( $html ) {
566 $img_regex = '<figure\b[^>]*>\s*(<a\b[^>]*>\s*)?<img\b';
567 $html = preg_replace( '/' . $img_regex . '/i', '$0 style="max-width: 100% !important; height: auto !important;"', $html );
568 $html = preg_replace( '/(' . $img_regex . '.*?)width=[\'"]\d+[\'"]/i', '$1', $html );
569 $html = preg_replace( '/(' . $img_regex . '.*?)height=[\'"]\d+[\'"]/i', '$1', $html );
570 return $html;
571 }
572
573 public function highlight_keywords( $the_content, $args ) {
574 if ( ! isset( $args['keyword'] ) ) {
575 return $the_content;
576 }
577
578 $tag_stack = array();
579 $protected_tags = array(
580 'pre',
581 'code',
582 'textarea',
583 'style',
584 );
585 $new_content = '';
586 $in_protected_tag = false;
587 foreach ( wp_html_split( $the_content ) as $chunk ) {
588 if ( preg_match( '#^<!--[\s\S]*-->$#i', $chunk, $m ) ) {
589 $new_content .= $chunk;
590 continue;
591 }
592
593 if ( preg_match( '#^<(/)?([a-z-]+)\b[^>]*>$#i', $chunk, $m ) ) {
594 $tag = strtolower( $m[2] );
595 if ( '/' === $m[1] ) {
596 // Closing tag.
597 $i = array_search( $tag, $tag_stack );
598 // We can only remove the tag from the stack if it is in the stack.
599 if ( false !== $i ) {
600 $tag_stack = array_slice( $tag_stack, 0, $i );
601 }
602 } else {
603 // Opening tag, add it to the stack.
604 $tag_stack[] = $tag;
605 }
606
607 // If we're in a protected tag, the tag_stack contains at least one protected tag string.
608 // The protected tag state can only change when we encounter a start or end tag.
609 $in_protected_tag = array_intersect( $tag_stack, $protected_tags );
610
611 // Never inspect tags.
612 $new_content .= $chunk;
613 continue;
614 }
615
616 if ( $in_protected_tag ) {
617 // Don't inspect a chunk inside an inspected tag.
618 $new_content .= $chunk;
619 continue;
620 }
621 // Only reachable when there is no protected tag in the stack.
622 $new_content .= preg_replace( '/(' . preg_quote( $args['keyword'], '/' ) . ')/i', '<mark>$1</mark>', $chunk );
623 }
624
625 return $new_content;
626 }
627
628 /**
629 * Wrapper for wp_mail to be overridden in unit tests
630 *
631 * @param string|array $to Array or comma-separated list of email addresses to send message.
632 * @param string $subject Email subject.
633 * @param string $message Message contents.
634 * @param array $headers Optional. Additional headers.
635 * @param array $attachments Optional. Files to attach.
636 * @param string $override_sitename Optional. Override the sitename.
637 * @return bool Whether the email contents were sent successfully.
638 */
639 public function send_mail( $to, $subject, $message, array $headers = array(), array $attachments = array(), $override_sitename = false ) {
640 $sitename = get_option( 'blogname' );
641
642 if ( $override_sitename ) {
643 $sitename = $override_sitename;
644 }
645
646 // translators: %1$s is the site name, %2$s is the subject.
647 $subject = sprintf( _x( '[%1$s] %2$s', 'email subject', 'friends' ), wp_specialchars_decode( $sitename, ENT_QUOTES ), $subject );
648 $subject = apply_filters( 'friends_send_mail_subject', $subject );
649
650 if ( ! apply_filters( 'friends_send_mail', true, $to, $subject, $message, $headers, $attachments ) ) {
651 return;
652 }
653
654 $alt_function = null;
655 if ( is_array( $message ) ) {
656 if ( isset( $message['html'] ) ) {
657 if ( isset( $message['text'] ) ) {
658 $plain_text = $message['text'];
659 } else {
660 $plain_text = wp_strip_all_tags( $message['html'] );
661 }
662
663 $headers[] = 'Content-type: text/html';
664 $alt_function = function ( $mailer ) use ( $plain_text ) {
665 $mailer->{'AltBody'} = $plain_text;
666 };
667 add_action(
668 'phpmailer_init',
669 $alt_function
670 );
671
672 $message = $message['html'];
673 } elseif ( isset( $message['text'] ) ) {
674 $message = $message['text'];
675 }
676 }
677
678 add_filter( 'wp_mail_from', array( $this, 'use_friends_plugin_from_email_address' ) );
679
680 $mail = wp_mail( $to, $subject, $message, $headers, $attachments );
681
682 remove_filter( 'wp_mail_from', array( $this, 'use_friends_plugin_from_email_address' ) );
683
684 if ( $alt_function ) {
685 remove_action( 'phpmailer_init', $alt_function );
686 }
687
688 return $mail;
689 }
690 }
691