Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
eee5a9f
Use comment status and type to set $maybe_notify default
adamsilverstein Nov 7, 2025
19a8db7
Update filter doc block
adamsilverstein Nov 7, 2025
a45b3b4
Update comment.php
adamsilverstein Nov 10, 2025
7c217dd
Apply suggestion from @westonruter
adamsilverstein Feb 25, 2026
9adf0e5
Apply suggestions from Weston
adamsilverstein Feb 26, 2026
d9cb02a
Merge branch 'trunk' into fix/notification-filter-default
adamsilverstein Feb 26, 2026
314311f
Merge branch 'trunk' into fix/notification-filter-default
adamsilverstein Mar 17, 2026
bc0918c
Update src/wp-includes/comment.php
adamsilverstein Mar 17, 2026
e74d3cf
Use comment object ID after get_comment() call
adamsilverstein Mar 17, 2026
77bb46d
Merge branch 'trunk' into fix/notification-filter-default
adamsilverstein Mar 17, 2026
d1cffae
Merge branch 'trunk' into fix/notification-filter-default
adamsilverstein Mar 17, 2026
b7127fd
Merge branch 'trunk' into fix/notification-filter-default
adamsilverstein Jul 14, 2026
422599a
Use elseif and correct the @since version for the 7.1 milestone
adamsilverstein Jul 14, 2026
a7620c1
Add tests proving the notify_post_author filter has full control
adamsilverstein Jul 14, 2026
310d6d0
Fix the invalid-comment test to avoid the global comment fallback
adamsilverstein Jul 14, 2026
cdb026f
Merge branch 'trunk' into fix/notification-filter-default
adamsilverstein Jul 15, 2026
8997cf2
Merge branch 'trunk' into fix/notification-filter-default
adamsilverstein Jul 15, 2026
a878e69
Document the 7.1 behavior changes to wp_new_comment_notify_postauthor()
adamsilverstein Jul 15, 2026
2f8b701
Cast the comment ID to int before passing it to the filter
adamsilverstein Jul 15, 2026
0afaf8e
Add tests for the unapproved note and comments_notify defaults
adamsilverstein Jul 15, 2026
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
36 changes: 23 additions & 13 deletions src/wp-includes/comment.php
Original file line number Diff line number Diff line change
Expand Up @@ -2462,25 +2462,42 @@ function wp_new_comment_notify_moderator( $comment_id ) {
/**
* Sends a notification of a new comment to the post author.
*
* @since 4.4.0
*
* Uses the {@see 'notify_post_author'} filter to determine whether the post author
* should be notified when a new comment is added, overriding site setting.
*
* @since 4.4.0
* @since 7.1.0 The comment approval status is now checked before the
* {@see 'notify_post_author'} filter, and invalid comment IDs
* return false without firing the filter.
*
* @param int $comment_id Comment ID.
* @return bool True on success, false on failure.
*/
function wp_new_comment_notify_postauthor( $comment_id ) {
$comment = get_comment( $comment_id );
Comment thread
adamsilverstein marked this conversation as resolved.
$is_note = ( $comment && 'note' === $comment->comment_type );
if ( ! ( $comment instanceof WP_Comment ) ) {
Comment thread
westonruter marked this conversation as resolved.
return false;
}
$comment_id = (int) $comment->comment_ID;
$is_note = ( 'note' === $comment->comment_type );

$maybe_notify = $is_note ? get_option( 'wp_notes_notify', 1 ) : get_option( 'comments_notify' );
// By default, only notify for approved comments and notes.
if ( '1' !== $comment->comment_approved && ! $is_note ) {
$maybe_notify = false;
} elseif ( $is_note ) {
$maybe_notify = get_option( 'wp_notes_notify', 1 );
} else {
$maybe_notify = get_option( 'comments_notify' );
}

/**
* Filters whether to send the post author new comment notification emails,
* overriding the site setting.
* Filters whether to send the post author new comment and note notification emails,
* overriding the site settings and defaults. By default, notifications are sent for
* all notes and for approved comments.
*
* @since 4.4.0
Comment thread
adamsilverstein marked this conversation as resolved.
* @since 7.1.0 Comment approval status is checked before this filter,
* and the filter no longer fires for invalid comment IDs.
*
* @param bool $maybe_notify Whether to notify the post author about the new comment.
* @param int $comment_id The ID of the comment for the notification.
Expand All @@ -2495,13 +2512,6 @@ function wp_new_comment_notify_postauthor( $comment_id ) {
return false;
}

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

return wp_notify_postauthor( $comment_id );
}

Expand Down
131 changes: 131 additions & 0 deletions tests/phpunit/tests/comment.php
Original file line number Diff line number Diff line change
Expand Up @@ -1109,6 +1109,137 @@ public function test_wp_new_comment_notify_postauthor_should_not_send_email_when
$this->assertFalse( $sent );
}

/**
* @ticket 64217
*
* @covers ::wp_new_comment_notify_postauthor
*/
public function test_wp_new_comment_notify_postauthor_filter_should_receive_false_for_unapproved_comment() {
$c = self::factory()->comment->create(
array(
'comment_post_ID' => self::$post_id,
'comment_approved' => '0',
)
);

update_option( 'comments_notify', 1 );

$maybe_notify = null;
add_filter(
'notify_post_author',
static function ( $value ) use ( &$maybe_notify ) {
$maybe_notify = $value;
return $value;
}
);

$sent = wp_new_comment_notify_postauthor( $c );

$this->assertFalse( $maybe_notify, 'The filter should receive a default of false for an unapproved comment.' );
$this->assertFalse( $sent, 'No notification should be sent for an unapproved comment by default.' );
}

/**
* @ticket 64217
*
* @covers ::wp_new_comment_notify_postauthor
*/
public function test_wp_new_comment_notify_postauthor_filter_should_override_unapproved_comment() {
$c = self::factory()->comment->create(
array(
'comment_post_ID' => self::$post_id,
'comment_approved' => '0',
)
);

add_filter( 'notify_post_author', '__return_true' );

$sent = wp_new_comment_notify_postauthor( $c );

$this->assertTrue( $sent, 'The notify_post_author filter should be able to force a notification for an unapproved comment.' );
}

/**
* @ticket 64217
*
* @covers ::wp_new_comment_notify_postauthor
*/
public function test_wp_new_comment_notify_postauthor_should_not_send_email_for_invalid_comment() {
$filter_fired = false;
add_filter(
'notify_post_author',
static function ( $value ) use ( &$filter_fired ) {
$filter_fired = true;
return $value;
}
);

// An empty ID such as 0 would fall back to the global comment in get_comment().
$sent = wp_new_comment_notify_postauthor( PHP_INT_MAX );

$this->assertFalse( $sent, 'No notification should be sent for an invalid comment ID.' );
$this->assertFalse( $filter_fired, 'The notify_post_author filter should not fire for an invalid comment ID.' );
}

/**
* @ticket 64217
*
* @covers ::wp_new_comment_notify_postauthor
*/
public function test_wp_new_comment_notify_postauthor_filter_should_receive_truthy_default_for_unapproved_note() {
$c = self::factory()->comment->create(
array(
'comment_post_ID' => self::$post_id,
'comment_type' => 'note',
'comment_approved' => '0',
)
);

update_option( 'wp_notes_notify', 1 );

$maybe_notify = null;
add_filter(
'notify_post_author',
static function ( $value ) use ( &$maybe_notify ) {
$maybe_notify = $value;
return false;
}
);

wp_new_comment_notify_postauthor( $c );

$this->assertTrue( (bool) $maybe_notify, 'The filter should receive a truthy default for an unapproved note.' );
}

/**
* @ticket 64217
*
* @covers ::wp_new_comment_notify_postauthor
*/
public function test_wp_new_comment_notify_postauthor_filter_should_receive_option_value_for_approved_comment() {
$c = self::factory()->comment->create(
array(
'comment_post_ID' => self::$post_id,
)
);

update_option( 'comments_notify', 0 );

$maybe_notify = null;
add_filter(
'notify_post_author',
static function ( $value ) use ( &$maybe_notify ) {
$maybe_notify = $value;
return $value;
}
);

$sent = wp_new_comment_notify_postauthor( $c );

$this->assertFalse( (bool) $maybe_notify, 'The filter should receive the comments_notify option value as the default for an approved comment.' );
$this->assertFalse( $sent, 'No notification should be sent for an approved comment when comments_notify is disabled.' );
}

/**
* @ticket 43805
*
Expand Down
Loading