PluginProbe
ActivityPub / 5.7.0
ActivityPub v5.7.0
9.3.1 9.3.0 9.2.2 9.2.1 9.2.0 9.1.0 9.0.2 9.0.1 9.0.0 8.3.0 8.2.1 8.2.0 8.1.1 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.2.0 1.3.0 2.0.0 2.0.1 2.1.0 2.1.1 All 160 releases
← All changes | includes/class-mailer.php +61 -399 9.2.05.7.0 View file →
@@ -1,9 +1,9 @@
1 1 <?php
2 2 /**
3 3 * Mailer Class.
4 4 *
5 - * @package Activitypub
5 + * @package ActivityPub
6 6 */
7 7
8 8 namespace Activitypub;
9 9
@@ -19,15 +19,17 @@
19 19 public static function init() {
20 20 \add_filter( 'comment_notification_subject', array( self::class, 'comment_notification_subject' ), 10, 2 );
21 21 \add_filter( 'comment_notification_text', array( self::class, 'comment_notification_text' ), 10, 2 );
22 22
23 - \add_action( 'activitypub_handled_follow', array( self::class, 'new_follower' ), 10, 3 );
23 + // New follower notification.
24 + if ( '1' === \get_option( 'activitypub_mailer_new_follower', '0' ) ) {
25 + \add_action( 'activitypub_notification_follow', array( self::class, 'new_follower' ) );
26 + }
24 27
25 - \add_action( 'activitypub_inbox_create', array( self::class, 'direct_message' ), 10, 2 );
26 - \add_action( 'activitypub_inbox_create', array( self::class, 'mention' ), 20, 2 ); /** After @see \Activitypub\Handler\Create::handle_create() */
27 -
28 - \add_filter( 'notify_post_author', array( self::class, 'maybe_prevent_comment_notification' ), 10, 2 );
29 - \add_filter( 'notify_moderator', array( self::class, 'maybe_prevent_comment_notification' ), 10, 2 );
28 + // Direct message notification.
29 + if ( '1' === \get_option( 'activitypub_mailer_new_dm', '0' ) ) {
30 + \add_action( 'activitypub_inbox_create', array( self::class, 'direct_message' ), 10, 2 );
31 + }
30 32 }
31 33
32 34 /**
33 35 * Filter the subject line for Like and Announce notifications.
@@ -58,9 +60,9 @@
58 60
59 61 $post = \get_post( $comment->comment_post_ID );
60 62
61 63 /* translators: 1: Blog name, 2: Like or Repost, 3: Post title */
62 - return \sprintf( \esc_html__( '[%1$s] %2$s: %3$s', 'activitypub' ), \esc_html( \get_option( 'blogname' ) ), \esc_html( $singular ), \esc_html( $post->post_title ) );
64 + return \sprintf( \esc_html__( '[%1$s] %2$s: %3$s', 'activitypub' ), \esc_html( get_option( 'blogname' ) ), \esc_html( $singular ), \esc_html( $post->post_title ) );
63 65 }
64 66
65 67 /**
66 68 * Filter the notification text for Like and Announce notifications.
@@ -89,51 +91,16 @@
89 91 return $message;
90 92 }
91 93
92 94 $post = \get_post( $comment->comment_post_ID );
93 - $comment_author_domain = '';
95 + $comment_author_domain = \gethostbyaddr( $comment->comment_author_IP );
94 96
95 - // Only attempt to resolve hostname if we have a valid IP address.
96 - if ( \filter_var( $comment->comment_author_IP, FILTER_VALIDATE_IP ) ) {
97 - $comment_author_domain = \gethostbyaddr( $comment->comment_author_IP );
98 - }
99 -
100 - // Check if this is a reaction to a post or a comment.
101 - if ( 0 === (int) $comment->comment_parent ) {
102 - $notify_message = \sprintf(
103 - /* translators: 1: Comment type, 2: Post title */
104 - \html_entity_decode( \esc_html__( 'New %1$s on your post &#8220;%2$s&#8221;.', 'activitypub' ) ),
105 - \esc_html( $comment_type['singular'] ),
106 - \esc_html( $post->post_title )
107 - ) . PHP_EOL . PHP_EOL;
108 -
109 - } else {
110 - $parent_comment = \get_comment( $comment->comment_parent );
111 - $notify_message = \sprintf(
112 - /* translators: 1: Comment type, 2: Post title, 3: Parent comment author */
113 - \html_entity_decode( \esc_html__( 'New %1$s on your post &#8220;%2$s&#8221; in reply to %3$s&#8217;s comment.', 'activitypub' ) ),
114 - \esc_html( $comment_type['singular'] ),
115 - \esc_html( $post->post_title ),
116 - \esc_html( $parent_comment->comment_author )
117 - ) . PHP_EOL . PHP_EOL;
118 - }
119 -
97 + /* translators: 1: Comment type, 2: Post title */
98 + $notify_message = \sprintf( html_entity_decode( esc_html__( 'New %1$s on your post &#8220;%2$s&#8221;.', 'activitypub' ) ), \esc_html( $comment_type['singular'] ), \esc_html( $post->post_title ) ) . "\r\n\r\n";
120 99 /* translators: 1: Website name, 2: Website IP address, 3: Website hostname. */
121 100 $notify_message .= \sprintf( \esc_html__( 'From: %1$s (IP address: %2$s, %3$s)', 'activitypub' ), \esc_html( $comment->comment_author ), \esc_html( $comment->comment_author_IP ), \esc_html( $comment_author_domain ) ) . "\r\n";
122 101 /* translators: Reaction author URL. */
123 - $notify_message .= \sprintf( \esc_html__( 'URL: %s', 'activitypub' ), \esc_url( $comment->comment_author_url ) ) . "\r\n";
124 -
125 - // For quotes, link to the quoting post itself so the author can review and respond.
126 - if ( 'quote' === $comment->comment_type ) {
127 - $quote_url = Comment::get_source_url( $comment->comment_ID );
128 -
129 - if ( $quote_url ) {
130 - /* translators: Quoting post URL. */
131 - $notify_message .= \sprintf( \esc_html__( 'Quoting post: %s', 'activitypub' ), \esc_url( $quote_url ) ) . "\r\n";
132 - }
133 - }
134 -
135 - $notify_message .= "\r\n";
102 + $notify_message .= \sprintf( \esc_html__( 'URL: %s', 'activitypub' ), \esc_url( $comment->comment_author_url ) ) . "\r\n\r\n";
136 103 /* translators: Comment type label */
137 104 $notify_message .= \sprintf( \esc_html__( 'You can see all %s on this post here:', 'activitypub' ), \esc_html( $comment_type['label'] ) ) . "\r\n";
138 105 $notify_message .= \get_permalink( $comment->comment_post_ID ) . '#' . \esc_attr( $comment_type['type'] ) . "\r\n\r\n";
139 106
@@ -142,87 +109,47 @@
142 109
143 110 /**
144 111 * Send a notification email for every new follower.
145 112 *
146 - * @param array $activity The activity object.
147 - * @param int|int[] $user_ids The id(s) of the local blog-user(s).
148 - * @param bool $success True on success, false otherwise.
113 + * @param Notification $notification The notification object.
149 114 */
150 - public static function new_follower( $activity, $user_ids, $success ) {
151 - // Only send notification if the follow was successful.
152 - if ( ! $success ) {
115 + public static function new_follower( $notification ) {
116 + $actor = get_remote_metadata_by_actor( $notification->actor );
117 +
118 + if ( ! $actor || \is_wp_error( $actor ) ) {
153 119 return;
154 120 }
155 121
156 - // Extract the user ID (follows are always for a single user).
157 - $user_id = \is_array( $user_ids ) ? \reset( $user_ids ) : $user_ids;
122 + $email = \get_option( 'admin_email' );
123 + $admin_url = '/options-general.php?page=activitypub&tab=followers';
158 124
159 - if ( $user_id > Actors::BLOG_USER_ID ) {
160 - if ( ! \get_user_option( 'activitypub_mailer_new_follower', $user_id ) ) {
125 + if ( $notification->target > Actors::BLOG_USER_ID ) {
126 + $user = \get_user_by( 'id', $notification->target );
127 +
128 + if ( ! $user ) {
161 129 return;
162 130 }
163 131
164 - $email = \get_userdata( $user_id )->user_email;
132 + $email = $user->user_email;
165 133 $admin_url = '/users.php?page=activitypub-followers-list';
166 - } else {
167 - if ( '1' !== \get_option( 'activitypub_blog_user_mailer_new_follower', '1' ) ) {
168 - return;
169 - }
170 -
171 - $email = \get_option( 'admin_email' );
172 - $admin_url = '/options-general.php?page=activitypub&tab=followers';
173 134 }
174 135
175 - $actor = get_remote_metadata_by_actor( $activity['actor'] );
176 - if ( ! $actor || \is_wp_error( $actor ) ) {
177 - return;
178 - }
179 -
180 - $actor = self::normalize_actor( $actor );
181 -
182 - // Replace emoji in actor name and summary.
183 - if ( ! empty( $actor['name'] ) ) {
184 - $actor['name'] = Emoji::replace_for_actor( $actor['name'], $actor['url'] );
185 - }
186 - if ( ! empty( $actor['summary'] ) ) {
187 - $actor['summary'] = Emoji::replace_for_actor( $actor['summary'], $actor['url'] );
188 - }
189 -
190 - $template_args = \array_merge(
136 + $template_args = array_merge(
191 137 $actor,
192 138 array(
193 139 'admin_url' => $admin_url,
194 - 'user_id' => $user_id,
195 - 'stats' => array(
196 - 'outbox' => null,
197 - 'followers' => null,
198 - 'following' => null,
199 - ),
140 + 'target' => $notification->target,
200 141 )
201 142 );
202 143
203 - foreach ( $template_args['stats'] as $field => $value ) {
204 - if ( empty( $actor[ $field ] ) ) {
205 - continue;
206 - }
207 -
208 - $result = Http::get( $actor[ $field ], array(), true );
209 - if ( 200 === \wp_remote_retrieve_response_code( $result ) ) {
210 - $body = \json_decode( \wp_remote_retrieve_body( $result ), true );
211 - if ( isset( $body['totalItems'] ) ) {
212 - $template_args['stats'][ $field ] = $body['totalItems'];
213 - }
214 - }
215 - }
216 -
217 144 /* translators: 1: Blog name, 2: Follower name */
218 - $subject = \sprintf( \__( '[%1$s] New Follower: %2$s', 'activitypub' ), \get_option( 'blogname' ), $actor['name'] );
145 + $subject = \sprintf( \__( '[%1$s] New Follower: %2$s', 'activitypub' ), get_option( 'blogname' ), $actor['name'] );
219 146
220 147 \ob_start();
221 - \load_template( ACTIVITYPUB_PLUGIN_DIR . 'templates/emails/new-follower.php', false, $template_args );
148 + \load_template( ACTIVITYPUB_PLUGIN_DIR . 'templates/new-follower-email.php', false, $template_args );
222 149 $html_message = \ob_get_clean();
223 150
224 - $alt_function = static function ( $mailer ) use ( $actor, $admin_url ) {
151 + $alt_function = function ( $mailer ) use ( $actor, $admin_url ) {
225 152 /* translators: 1: Follower name */
226 153 $message = \sprintf( \__( 'New Follower: %1$s.', 'activitypub' ), $actor['name'] ) . "\r\n\r\n";
227 154 /* translators: Follower URL */
228 155 $message .= \sprintf( \__( 'URL: %s', 'activitypub' ), \esc_url( $actor['url'] ) ) . "\r\n\r\n";
@@ -239,319 +166,54 @@
239 166
240 167 /**
241 168 * Send a direct message.
242 169 *
243 - * @param array $activity The activity object.
244 - * @param int|int[] $user_ids The id(s) of the local blog-user(s).
170 + * @param array $activity The activity object.
171 + * @param int $user_id The id of the local blog-user.
245 172 */
246 - public static function direct_message( $activity, $user_ids ) {
247 - // Early return if activity is public or has no recipients.
248 - if ( is_activity_public( $activity ) || empty( $activity['to'] ) ) {
173 + public static function direct_message( $activity, $user_id ) {
174 + if (
175 + is_activity_public( $activity ) ||
176 + // Only accept messages that have the user in the "to" field.
177 + empty( $activity['to'] ) ||
178 + ! in_array( Actors::get_by_id( $user_id )->get_id(), (array) $activity['to'], true )
179 + ) {
249 180 return;
250 181 }
251 182
252 - // Normalize to array.
253 - $user_ids = (array) $user_ids;
183 + $actor = get_remote_metadata_by_actor( $activity['actor'] );
254 184
255 - // Build a map of user_id => actor_id and filter to only users in the "to" field.
256 - $recipients = array();
257 - foreach ( $user_ids as $user_id ) {
258 - $actor = Actors::get_by_id( $user_id );
259 - if ( \is_wp_error( $actor ) ) {
260 - continue;
261 - }
262 -
263 - $actor_id = $actor->get_id();
264 - if ( \in_array( $actor_id, (array) $activity['to'], true ) ) {
265 - $recipients[ $user_id ] = $actor_id;
266 - }
267 - }
268 -
269 - // No matching recipients.
270 - if ( empty( $recipients ) ) {
271 - return;
272 - }
273 -
274 - // Get actor metadata once (shared for all emails).
275 - $actor = get_remote_metadata_by_actor( $activity['actor'] );
276 185 if ( ! $actor || \is_wp_error( $actor ) || empty( $activity['object']['content'] ) ) {
277 186 return;
278 187 }
279 188
280 - $actor = self::normalize_actor( $actor );
189 + $email = \get_option( 'admin_email' );
281 190
282 - // Send email to each recipient.
283 - foreach ( $recipients as $user_id => $actor_id ) {
284 - // Check user preferences.
285 - if ( $user_id > Actors::BLOG_USER_ID ) {
286 - if ( ! \get_user_option( 'activitypub_mailer_new_dm', $user_id ) ) {
287 - continue;
288 - }
191 + if ( (int) $user_id > Actors::BLOG_USER_ID ) {
192 + $user = \get_user_by( 'id', $user_id );
289 193
290 - $email = \get_userdata( $user_id )->user_email;
291 - } else {
292 - if ( '1' !== \get_option( 'activitypub_blog_user_mailer_new_dm', '1' ) ) {
293 - continue;
294 - }
295 -
296 - $email = \get_option( 'admin_email' );
194 + if ( ! $user ) {
195 + return;
297 196 }
298 197
299 - $template_args = array(
300 - 'activity' => $activity,
301 - 'actor' => $actor,
302 - 'user_id' => $user_id,
303 - );
304 -
305 - /* translators: 1: Blog name, 2 Actor name */
306 - $subject = \sprintf( \esc_html__( '[%1$s] Direct Message from: %2$s', 'activitypub' ), \esc_html( \get_option( 'blogname' ) ), \esc_html( $actor['name'] ) );
307 -
308 - \ob_start();
309 - \load_template( ACTIVITYPUB_PLUGIN_DIR . 'templates/emails/new-dm.php', false, $template_args );
310 - $html_message = \ob_get_clean();
311 -
312 - $alt_function = static function ( $mailer ) use ( $actor, $activity ) {
313 - $content = \html_entity_decode(
314 - \wp_strip_all_tags(
315 - \str_replace( '</p>', PHP_EOL . PHP_EOL, $activity['object']['content'] )
316 - ),
317 - ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401
318 - );
319 -
320 - /* translators: Actor name */
321 - $message = \sprintf( \esc_html__( 'New Direct Message: %s', 'activitypub' ), $content ) . "\r\n\r\n";
322 - /* translators: Actor name */
323 - $message .= \sprintf( \esc_html__( 'From: %s', 'activitypub' ), \esc_html( $actor['name'] ) ) . "\r\n";
324 - /* translators: Message URL */
325 - $message .= \sprintf( \esc_html__( 'URL: %s', 'activitypub' ), \esc_url( $activity['object']['id'] ) ) . "\r\n\r\n";
326 -
327 - $mailer->{'AltBody'} = $message;
328 - };
329 - \add_action( 'phpmailer_init', $alt_function );
330 -
331 - \wp_mail( $email, $subject, $html_message, array( 'Content-type: text/html' ) );
332 -
333 - \remove_action( 'phpmailer_init', $alt_function );
334 - }
335 - }
336 -
337 - /**
338 - * Send a mention notification.
339 - *
340 - * @param array $activity The activity object.
341 - * @param int|int[] $user_ids The id(s) of the local blog-user(s).
342 - */
343 - public static function mention( $activity, $user_ids ) {
344 - // Early return if activity has no mentions.
345 - if ( empty( $activity['object']['tag'] ) ) {
346 - return;
347 - }
348 -
349 - // Do not send a mention notification if the activity is a reply to a local post or comment.
350 - if ( is_activity_reply( $activity ) && object_id_to_comment( $activity['object']['id'] ) ) {
351 - return;
352 - }
353 -
354 - $recipients = array();
355 - $mentions = \wp_list_filter( (array) $activity['object']['tag'], array( 'type' => 'Mention' ) );
356 - $mentions = \array_map( '\Activitypub\object_to_uri', $mentions );
357 - foreach ( (array) $user_ids as $user_id ) {
358 - $actor = Actors::get_by_id( $user_id );
359 - if ( \is_wp_error( $actor ) ) {
360 - continue;
361 - }
362 -
363 - $actor_id = $actor->get_id();
364 - if ( \in_array( $actor_id, $mentions, true ) ) {
365 - $recipients[ $user_id ] = $actor_id;
366 - }
367 - }
368 -
369 - // No matching recipients.
370 - if ( empty( $recipients ) ) {
371 - return;
372 - }
373 -
374 - // Get actor metadata once (shared for all emails).
375 - $actor = get_remote_metadata_by_actor( $activity['actor'] );
376 - if ( \is_wp_error( $actor ) ) {
377 - return;
378 - }
379 -
380 - $actor = self::normalize_actor( $actor );
381 -
382 - // Send email to each recipient.
383 - foreach ( $recipients as $user_id => $actor_id ) {
384 - // Check user preferences.
385 - if ( $user_id > Actors::BLOG_USER_ID ) {
386 - if ( ! \get_user_option( 'activitypub_mailer_new_mention', $user_id ) ) {
387 - continue;
388 - }
389 -
390 - $email = \get_userdata( $user_id )->user_email;
391 - } else {
392 - if ( '1' !== \get_option( 'activitypub_blog_user_mailer_new_mention', '1' ) ) {
393 - continue;
394 - }
395 -
396 - $email = \get_option( 'admin_email' );
397 - }
398 -
399 - $template_args = array(
400 - 'activity' => $activity,
401 - 'actor' => $actor,
402 - 'user_id' => $user_id,
403 - );
404 -
405 - /* translators: 1: Blog name, 2 Actor name */
406 - $subject = \sprintf( \esc_html__( '[%1$s] Mention from: %2$s', 'activitypub' ), \esc_html( \get_option( 'blogname' ) ), \esc_html( $actor['name'] ) );
407 -
408 - \ob_start();
409 - \load_template( ACTIVITYPUB_PLUGIN_DIR . 'templates/emails/new-mention.php', false, $template_args );
410 - $html_message = \ob_get_clean();
411 -
412 - $alt_function = static function ( $mailer ) use ( $actor, $activity ) {
413 - $content = \html_entity_decode(
414 - \wp_strip_all_tags(
415 - \str_replace( '</p>', PHP_EOL . PHP_EOL, $activity['object']['content'] )
416 - ),
417 - ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401
418 - );
419 -
420 - /* translators: Message content */
421 - $message = \sprintf( \esc_html__( 'New Mention: %s', 'activitypub' ), $content ) . "\r\n\r\n";
422 - /* translators: Actor name */
423 - $message .= \sprintf( \esc_html__( 'From: %s', 'activitypub' ), \esc_html( $actor['name'] ) ) . "\r\n";
424 - /* translators: Message URL */
425 - $message .= \sprintf( \esc_html__( 'URL: %s', 'activitypub' ), \esc_url( $activity['object']['id'] ) ) . "\r\n\r\n";
426 -
427 - $mailer->{'AltBody'} = $message;
428 - };
429 - \add_action( 'phpmailer_init', $alt_function );
430 -
431 - \wp_mail( $email, $subject, $html_message, array( 'Content-type: text/html' ) );
432 -
433 - \remove_action( 'phpmailer_init', $alt_function );
434 - }
435 - }
436 -
437 - /**
438 - * Send a templated email to a user.
439 - *
440 - * @param int $user_id The user ID (or BLOG_USER_ID for blog actor).
441 - * @param string $subject The email subject.
442 - * @param string $template The template name (without path/extension).
443 - * @param array $args Template arguments.
444 - * @param string $alt_body Optional plain text alternative. Auto-generated from HTML if empty.
445 - *
446 - * @return bool True if email was sent, false otherwise.
447 - */
448 - public static function send( $user_id, $subject, $template, $args = array(), $alt_body = '' ) {
449 - // Get the recipient email address.
450 - if ( $user_id > Actors::BLOG_USER_ID ) {
451 - $user = \get_userdata( $user_id );
452 - if ( ! $user || empty( $user->user_email ) ) {
453 - return false;
454 - }
455 198 $email = $user->user_email;
456 - } else {
457 - $email = \get_option( 'admin_email' );
458 199 }
459 200
460 - // Load the HTML template.
461 - $template_file = ACTIVITYPUB_PLUGIN_DIR . 'templates/emails/' . \sanitize_file_name( $template ) . '.php';
201 + $content = \html_entity_decode(
202 + \wp_strip_all_tags(
203 + str_replace( '</p>', PHP_EOL . PHP_EOL, $activity['object']['content'] )
204 + ),
205 + ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401
206 + );
462 207
463 - /**
464 - * Filter the email template file path.
465 - *
466 - * @param string $template_file The template file path.
467 - * @param string $template The template name.
468 - * @param int $user_id The user ID.
469 - * @param array $args Template arguments.
470 - */
471 - $template_file = \apply_filters( 'activitypub_email_template', $template_file, $template, $user_id, $args );
208 + /* translators: 1: Blog name, 2 Actor name */
209 + $subject = \sprintf( \esc_html__( '[%1$s] Direct Message from: %2$s', 'activitypub' ), \esc_html( get_option( 'blogname' ) ), \esc_html( $actor['name'] ) );
210 + /* translators: 1: Blog name, 2: Actor name */
211 + $message = \sprintf( \esc_html__( 'New Direct Message: %2$s', 'activitypub' ), \esc_html( get_option( 'blogname' ) ), $content ) . "\r\n\r\n";
212 + /* translators: Actor name */
213 + $message .= \sprintf( \esc_html__( 'From: %s', 'activitypub' ), \esc_html( $actor['name'] ) ) . "\r\n";
214 + /* translators: Actor URL */
215 + $message .= \sprintf( \esc_html__( 'URL: %s', 'activitypub' ), \esc_url( $actor['url'] ) ) . "\r\n\r\n";
472 216
473 - if ( ! \file_exists( $template_file ) ) {
474 - return false;
475 - }
476 -
477 - \ob_start();
478 - \load_template( $template_file, false, $args );
479 - $html_message = \ob_get_clean();
480 -
481 - // Build plain text alternative from HTML if not provided.
482 - if ( empty( $alt_body ) ) {
483 - $alt_body = \wp_strip_all_tags( $html_message );
484 - }
485 - $alt_function = static function ( $mailer ) use ( $alt_body ) {
486 - $mailer->{'AltBody'} = $alt_body;
487 - };
488 - \add_action( 'phpmailer_init', $alt_function );
489 -
490 - $result = \wp_mail( $email, $subject, $html_message, array( 'Content-type: text/html' ) );
491 -
492 - \remove_action( 'phpmailer_init', $alt_function );
493 -
494 - return $result;
495 - }
496 -
497 - /**
498 - * Apply defaults to the actor object.
499 - *
500 - * Ensure that the actor object has a name, url, and webfinger.
501 - *
502 - * @param array $actor The actor object.
503 - *
504 - * @return array The inflated actor object.
505 - */
506 - private static function normalize_actor( $actor ) {
507 - if ( empty( $actor['name'] ) ) {
508 - $actor['name'] = $actor['preferredUsername'];
509 - }
510 -
511 - if ( empty( $actor['url'] ) ) {
512 - $actor['url'] = $actor['id'];
513 - }
514 - $actor['url'] = object_to_uri( $actor['url'] );
515 -
516 - if ( empty( $actor['webfinger'] ) ) {
517 - $actor['webfinger'] = '@' . ( $actor['preferredUsername'] ?? $actor['name'] ) . '@' . \wp_parse_url( $actor['url'], PHP_URL_HOST );
518 - }
519 -
520 - return $actor;
521 - }
522 -
523 - /**
524 - * Maybe prevent email notifications for comments.
525 - *
526 - * This filter can prevent both post author and moderator notifications
527 - * for comments on specific post types, such as ActivityPub custom post types.
528 - *
529 - * @param bool $maybe_notify Whether to send the notification.
530 - * @param int $comment_id The comment ID.
531 - *
532 - * @return bool False to prevent notification, original value otherwise.
533 - */
534 - public static function maybe_prevent_comment_notification( $maybe_notify, $comment_id ) {
535 - // If already disabled, respect that.
536 - if ( ! $maybe_notify ) {
537 - return $maybe_notify;
538 - }
539 -
540 - $comment = \get_comment( $comment_id );
541 - if ( ! $comment ) {
542 - return $maybe_notify;
543 - }
544 -
545 - $post = \get_post( $comment->comment_post_ID );
546 - if ( ! $post ) {
547 - return $maybe_notify;
548 - }
549 -
550 - // Prevent notifications for comments on ap_post.
551 - if ( is_ap_post( $post ) ) {
552 - return false;
553 - }
554 -
555 - return $maybe_notify;
217 + \wp_mail( $email, $subject, $message );
556 218 }
557 219 }