Skip to content

Comments: Update the "Mine" view count after AJAX moderation actions - #14114

Open
AbdiTolesa wants to merge 2 commits into
WordPress:trunkfrom
AbdiTolesa:fix/comments-mine-view-count-stale
Open

AbdiTolesa wants to merge 2 commits into
WordPress:trunkfrom
AbdiTolesa:fix/comments-mine-view-count-stale

Conversation

@AbdiTolesa

@AbdiTolesa AbdiTolesa commented Oct 8, 2026 •

Copy link
Copy Markdown

Trac ticket: https://core.trac.wordpress.org/ticket/66272

Summary

On the Comments screen, performing an AJAX moderation action (Approve, Unapprove, Spam, Trash, Delete Permanently, or Undo) live-updates several view tab counts in the DOM without a full page reload — edit-comments.js's delAfter handler bumps span.all-count, span.pending-count (via updatePending), span.approved-count (via updateApproved), span.spam-count, and span.trash-count.

The span.mine-count badge is never touched by this code, so after e.g. deleting one of your own comments via AJAX, the "Mine (N)" tab keeps showing the old count until the page is fully reloaded — inconsistent with every other tab.

"Mine" uses the same status scope as "All" (approved + pending comments; see WP_Comments_List_Table::get_views(), which queries with no status arg, defaulting to 'all'), just filtered to the current user's own comments. So it needs the same pendingDiff/approvedDiff updates that all-count gets, applied only when the affected comment belongs to the current user.

Changes

  • WP_Comments_List_Table::single_row() now renders a data-comment-user-id attribute on each comment <tr>.
  • The admin-comments script is localized with the current user's ID (adminCommentsSettings.currentUserId).
  • edit-comments.js compares the acted-upon row's data-comment-user-id to the current user ID and, when they match, also updates span.mine-count alongside span.all-count for both pendingDiff and approvedDiff.
  • Added test_single_row_includes_comment_user_id_for_mine_count_tracking to wpCommentsListTable.php.

Test plan

  • php -l on the changed PHP files; node --check and npx eslint on the changed JS file (no errors).
  • Ran Tests_Admin_wpCommentsListTable and Tests_Admin_wpPostCommentsListTable — 12 tests total, all passing.
  • Verified the new test fails against the unpatched class-wp-comments-list-table.php (no data-comment-user-id attribute) and passes with the fix.
  • The JS behavior itself (live DOM update of span.mine-count after an AJAX action) isn't covered by PHPUnit — manually verified the logic by tracing delAfter in edit-comments.js, but a browser/QUnit check of the actual tab count updating live would be good before merging.

Update: fix a type-mismatch bug caught in review

wp_localize_script() (via WP_Scripts::localize()) casts every scalar value to a string before JSON-encoding it, so adminCommentsSettings.currentUserId actually arrives in JS as a string (e.g. "7"), not a number. The isMine check compared it with === against a parseInt()'d number, which is always false for a string/number pair — so the "Mine" count was never actually updated, regardless of ownership. Fixed by wrapping adminCommentsSettings.currentUserId in parseInt(..., 10) too, so both sides of the comparison are numbers. Confirmed this matches WP_Scripts::localize()'s actual behavior by reading its source ((string) $value cast before wp_json_encode()).

After approving, unapproving, spamming, trashing, or deleting a comment
via AJAX on the Comments screen, edit-comments.js live-updates the
"All", "Pending", "Approved", "Spam", and "Trash" view tab counts in
the DOM. The "Mine" count was never touched, so it stayed stale until
a full page reload, unlike every other view.

"Mine" shares the same status scope as "All" (approved + pending),
just filtered to the current user's own comments, so it needs the same
pendingDiff/approvedDiff updates "All" gets, applied only when the
affected comment belongs to the current user.

To determine that client-side:
- WP_Comments_List_Table::single_row() now renders a
  data-comment-user-id attribute on each comment row.
- The admin-comments script is localized with the current user's ID
  (adminCommentsSettings.currentUserId).
- edit-comments.js compares the two to decide whether to also bump
  span.mine-count alongside span.all-count.

Added a test asserting single_row() renders the new attribute for the
comment's author.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props abditsori, sainathpoojary.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

@SainathPoojary SainathPoojary left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for working on this fix! The overall approach looks good and the unit test covers the new attribute nicely.

I left one comment regarding type casting adminCommentsSettings.currentUserId to ensure the strict equality check passes as expected.

unapproved = commentRow.hasClass( 'unapproved' ),
spammed = commentRow.hasClass( 'spam' ),
trashed = commentRow.hasClass( 'trash' ),
isMine = !! adminCommentsSettings.currentUserId &&

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Since adminCommentsSettings.currentUserId is passed via wp_localize_script(), it arrives as a string. Because we're using strict equality ===, this comparison evaluates to false even when the IDs match (e.g., 7 === "7").

Could we wrap adminCommentsSettings.currentUserId in parseInt(..., 10) as well?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

@SainathPoojary Thanks for bringing that up! The concern is addressed now.

wp_localize_script() (via WP_Scripts::localize()) casts every scalar
value to a string before JSON-encoding it, so
adminCommentsSettings.currentUserId arrives in JS as a string (e.g.
"7"), not a number. The isMine check compared it with === against a
parseInt()'d number, which is always false for a string/number pair,
so the "Mine" count was never actually updated via AJAX.

Wrap adminCommentsSettings.currentUserId in parseInt(..., 10) as well
so both sides of the comparison are numbers.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

@SainathPoojary SainathPoojary left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM! 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants