Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
8ec209c
Send a notification to the post author when a note is added
adamsilverstein Nov 5, 2025
6799a1d
phpcbf
adamsilverstein Nov 5, 2025
6faacfe
remove notes conditional
adamsilverstein Nov 5, 2025
b3487af
Only notify on notes REST insert
adamsilverstein Nov 5, 2025
0daba4c
update docblock
adamsilverstein Nov 6, 2025
cbfef88
Queue note notifications with cron
adamsilverstein Nov 6, 2025
f089d47
Skip notifications for empty notes
adamsilverstein Nov 6, 2025
79fd7e5
Update src/wp-includes/pluggable.php
adamsilverstein Nov 6, 2025
2aa7c96
Whitespace
adamsilverstein Nov 6, 2025
f9d4686
adjust since
adamsilverstein Nov 6, 2025
79aa49d
Revert "Queue note notifications with cron"
adamsilverstein Nov 6, 2025
8da27bc
update: Anyone posts a comment + "or note"
adamsilverstein Nov 6, 2025
98c2873
Add separate notes notification setting
adamsilverstein Nov 6, 2025
099de2f
Move notification hook so it is always available when action triggered
adamsilverstein Nov 6, 2025
887974e
Empty notes are resolution/reopen events
adamsilverstein Nov 6, 2025
62ed6c3
Fix notification logic
adamsilverstein Nov 6, 2025
25f0b56
phpcbf
adamsilverstein Nov 6, 2025
f3bee16
Check comment object returned before using
adamsilverstein Nov 6, 2025
0f6fff0
Merge branch 'trunk' into add/notes-notifications
adamsilverstein Nov 6, 2025
3b168e3
Update comment.php
adamsilverstein Nov 7, 2025
6fd6294
Update class-wp-rest-comments-controller.php
adamsilverstein Nov 7, 2025
93b9bd1
PHP not react
adamsilverstein Nov 7, 2025
7a1ed8e
rename notes_notify -> wp_ notes_notify
adamsilverstein Nov 7, 2025
2f4c927
Move wp_ notes_notify to bottom and add comment
adamsilverstein Nov 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/wp-admin/includes/schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,10 @@ function populate_options( array $options = array() ) {

// 6.4.0
'wp_attachment_pages_enabled' => 0,

// 6.9.0
'wp_notes_notify' => 1,

);

// 3.3.0
Expand Down
5 changes: 5 additions & 0 deletions src/wp-admin/options-discussion.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,11 @@
<label for="moderation_notify">
<input name="moderation_notify" type="checkbox" id="moderation_notify" value="1" <?php checked( '1', get_option( 'moderation_notify' ) ); ?> />
<?php _e( 'A comment is held for moderation' ); ?> </label>
<br />
<label for="wp_notes_notify">
<input name="wp_notes_notify" type="checkbox" id="wp_notes_notify" value="1" <?php checked( '1', get_option( 'wp_notes_notify' ) ); ?> />
<?php _e( 'Anyone posts a note' ); ?> </label>

</fieldset></td>
</tr>
<?php $before_comment_appears_title = __( 'Before a comment appears' ); ?>
Expand Down
1 change: 1 addition & 0 deletions src/wp-admin/options.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@
'comment_order',
'comment_registration',
'show_comments_cookies_opt_in',
'wp_notes_notify',
),
'media' => array(
'thumbnail_size_w',
Expand Down
11 changes: 7 additions & 4 deletions src/wp-includes/comment.php
Original file line number Diff line number Diff line change
Expand Up @@ -2425,8 +2425,9 @@ function wp_new_comment_notify_moderator( $comment_id ) {
*/
function wp_new_comment_notify_postauthor( $comment_id ) {
$comment = get_comment( $comment_id );
$is_note = ( $comment && 'note' === $comment->comment_type );

$maybe_notify = get_option( 'comments_notify' );
$maybe_notify = $is_note ? get_option( 'wp_notes_notify' ) : get_option( 'comments_notify' );

/**
* Filters whether to send the post author new comment notification emails,
Expand All @@ -2447,9 +2448,11 @@ function wp_new_comment_notify_postauthor( $comment_id ) {
return false;
}

// Only send notifications for approved comments.
if ( ! isset( $comment->comment_approved ) || '1' !== $comment->comment_approved ) {
return false;
// Send notifications for approved comments and all notes.
if (
! isset( $comment->comment_approved ) ||
( '1' !== $comment->comment_approved && ! $is_note ) ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the future, it could be nice to have filters for this instead of hardcoded behavior for notes

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏼 Yea, its a bit odd to have this logic here. There is a filter just above notify_post_author that can be used to opt out of notifications. The status and type should probably be used to set the default that is run thru that filter instead of being checked later.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ellatrix maybe something like this: 1f16c40

I can open a separate Trac ticket for this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return false;
}

return wp_notify_postauthor( $comment_id );
Expand Down
1 change: 1 addition & 0 deletions src/wp-includes/default-filters.php
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,7 @@
// Email notifications.
add_action( 'comment_post', 'wp_new_comment_notify_moderator' );
add_action( 'comment_post', 'wp_new_comment_notify_postauthor' );
add_action( 'rest_insert_comment', array( 'WP_REST_Comments_Controller', 'wp_new_comment_via_rest_notify_postauthor' ) );
add_action( 'after_password_reset', 'wp_password_change_notification' );
add_action( 'register_new_user', 'wp_send_new_user_notifications' );
add_action( 'edit_user_created_user', 'wp_send_new_user_notifications', 10, 2 );
Expand Down
24 changes: 21 additions & 3 deletions src/wp-includes/pluggable.php
Original file line number Diff line number Diff line change
Expand Up @@ -1894,6 +1894,20 @@ function wp_notify_postauthor( $comment_id, $deprecated = null ) {
$subject = sprintf( __( '[%1$s] Pingback: "%2$s"' ), $blogname, $post->post_title );
break;

case 'note':
/* translators: %s: Post title. */
$notify_message = sprintf( __( 'New note on your post "%s"' ), $post->post_title ) . "\r\n";
/* translators: 1: Note author's name, 2: Note author's IP address, 3: Note author's hostname. */
$notify_message .= sprintf( __( 'Author: %1$s (IP address: %2$s, %3$s)' ), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n";
/* translators: %s: Note author email. */
$notify_message .= sprintf( __( 'Email: %s' ), $comment->comment_author_email ) . "\r\n";
/* translators: %s: Note text. */
$notify_message .= sprintf( __( 'Note: %s' ), "\r\n" . ( empty( $comment_content ) ? __( 'resolved/reopened' ) : $comment_content ) ) . "\r\n\r\n";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to determine whether the status is resolved or reopened when empty? It's a little vague as is.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that should be doable based on comment meta or derived based on parent note status.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Meta is not yet saved at this hook, not sure the parent is helpful but I'll take a look.

$notify_message .= __( 'You can see all notes on this post here:' ) . "\r\n";
/* translators: Note notification email subject. 1: Site title, 2: Post title. */
$subject = sprintf( __( '[%1$s] Note: "%2$s"' ), $blogname, $post->post_title );
break;

default: // Comments.
/* translators: %s: Post title. */
$notify_message = sprintf( __( 'New comment on your post "%s"' ), $post->post_title ) . "\r\n";
Expand All @@ -1917,11 +1931,15 @@ function wp_notify_postauthor( $comment_id, $deprecated = null ) {
break;
}

$notify_message .= get_permalink( $comment->comment_post_ID ) . "#comments\r\n\r\n";
/* translators: %s: Comment URL. */
$notify_message .= sprintf( __( 'Permalink: %s' ), get_comment_link( $comment ) ) . "\r\n";
if ( 'note' === $comment->comment_type ) {
$notify_message .= get_edit_post_link( $comment->comment_post_ID, 'url' ) . "\r\n";
} else {
$notify_message .= get_permalink( $comment->comment_post_ID ) . "#comments\r\n\r\n";
$notify_message .= sprintf( __( 'Permalink: %s' ), get_comment_link( $comment ) ) . "\r\n";
}

if ( user_can( $post->post_author, 'edit_comment', $comment->comment_ID ) ) {
if ( 'note' !== $comment->comment_type && user_can( $post->post_author, 'edit_comment', $comment->comment_ID ) ) {
if ( EMPTY_TRASH_DAYS ) {
/* translators: Comment moderation. %s: Comment action URL. */
$notify_message .= sprintf( __( 'Trash it: %s' ), admin_url( "comment.php?action=trash&c={$comment->comment_ID}#wpbody-content" ) ) . "\r\n";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,18 @@ public function __construct() {
$this->meta = new WP_REST_Comment_Meta_Fields();
}

/**
* Send a notification to the post author when a new note is added via the REST API.
*
* @since 6.9.0
*
* @param WP_Comment $comment The comment object.
*/
public static function wp_new_comment_via_rest_notify_postauthor( $comment ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I wasn't able to find reasoning for moving this method here. So what was it?

IMO, seems odd and unrelated to have action callback in REST controller. It kind of goes against the idea of separation concerns. @TimothyBJacobs, what do you think?

Copy link
Member Author

@adamsilverstein adamsilverstein Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had it in comments.php previously, but noticed some unit test failure because the hook was being fired in the test with a null comment. I can move it back and add a guard for this instead. I wasn't really sure about the best location for this code.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why doesn't the comment_post action execute when comments are posted through the REST API?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let’s move it before RC so we don’t introduce accidental public function that we have to deprecate in next release.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why doesn't the comment_post action execute when comments are posted through the REST API?

@ellatrix comment_post is triggered in wp_new_comment, but the REST controller never calls that - it calls wp_insert_comment directly. This triggers wp_insert_comment so we could hook there, it also fires rest_insert_comment slightly later which I decided was appropriate since I'm explicitly targeting the REST insertion with this change.

Copy link
Member Author

@adamsilverstein adamsilverstein Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let’s move it before RC so we don’t introduce accidental public function that we have to deprecate in next release.

@Mamaduka I'm working on a follow up including moving the function here: #10488

if ( 'note' === $comment->comment_type ) {
wp_new_comment_notify_postauthor( $comment->comment_ID );
}
}
/**
* Registers the routes for comments.
*
Expand Down
Loading