Skip to content

Notes: mention notification emails are missing the fixes made during the Core review #81186

Closed

Description

@adamsilverstein

Description

The note @mention notification landed in WordPress Core as https://core.trac.wordpress.org/changeset/63012, and the review on that patch turned up a handful of bugs in the email composition. The plugin still ships the version those fixes were made against, in lib/compat/wordpress-7.1/notes-mentions.php.

This matters more than a normal "core caught up with the plugin" gap, because that file deliberately removes Core's wp_notify_note_mentions() from rest_insert_comment and registers its own copy instead:

/*
* Once the Core backport lands, WordPress registers its own
* wp_notify_note_mentions() on this same hook from default-filters.php. With
* both callbacks attached every mentioned user would be emailed twice, so the
* plugin's copy - the newer of the two - replaces Core's while Gutenberg is
* active. Core's post-author notification is deliberately left alone: this
* file never notifies the post author, so the two do not overlap.
*/
$gutenberg_note_mentions_priority = has_action( 'rest_insert_comment', 'wp_notify_note_mentions' );
if ( false !== $gutenberg_note_mentions_priority ) {
remove_action( 'rest_insert_comment', 'wp_notify_note_mentions', $gutenberg_note_mentions_priority );

So on WordPress 7.1 with Gutenberg active, the plugin's copy is the one that runs, and these are the emails users actually get.

The issues

1. The editor link is built for the sender, not the recipient.

$edit_link = $post ? get_edit_post_link( $post->ID, 'url' ) : '';

get_edit_post_link() answers for whoever is the current user. Everything else in that function is composed for the recipient (switch_to_user_locale() a few lines up), but this is evaluated as the note's author over REST. Under WP-Cron there is no current user at all, so it returns an empty string and the email goes out with no link.

2. The subject is decoded twice. $blogname is decoded on assignment and then the whole assembled subject is decoded again at the wp_mail() call. A site or post title where the author meant & to be read literally gets flattened.

3. Note content is decoded before its tags are stripped.

$content = wp_strip_all_tags( wp_specialchars_decode( $comment->comment_content ) );

Decoding first turns escaped text like <code> into a real tag, which wp_strip_all_tags() then removes, so that text disappears from the message body.

4. No Content-Type header. Nothing is passed to wp_mail(), so its default applies and a filter could turn the message into HTML. Core sends Content-Type: text/plain; charset=<blog_charset> here, matching wp_notify_postauthor().

5. A null comment is fatal.

function gutenberg_notify_note_mentions( WP_Comment $comment, $request = null, bool $creating = true ): void {

WP_REST_Comments_Controller does $comment = get_comment( $comment_id ) and passes the result straight into do_action( 'rest_insert_comment', ... ). If the comment is gone by then that is null, and the non-nullable WP_Comment type hint turns it into a TypeError. Unlikely to happen, but it is the plugin's own type hint that makes it fatal rather than harmless - Core widened the parameter to ?WP_Comment and guards.

6. A comment_post_ID of 0 picks up the global post.

$post = get_post( (int) $comment->comment_post_ID );

get_post() treats 0 as empty and substitutes $GLOBALS['post'], so a note with no post would compose the email about whatever post happened to be in scope.

There is also a small formatting difference: Core labels the link Edit This: <url> where the plugin emits a bare URL, so the email changes shape depending on whether the plugin is active. Worth aligning while we are in here.

Related

cc: @westonruter @Mamaduka

Metadata

Metadata

Labels

[Feature] NotesPhase 3 of the Gutenberg roadmap around block commenting[Status] In ProgressTracking issues with work in progress[Type] BugAn existing feature does not function as intended

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions