Make WordPress Core

Opened 3 weeks ago

Last modified 3 weeks ago

#65642 new defect (bug)

get_page_of_comment() counts internal notes, breaking comment permalink pagination

Reported by: dhrupo Owned by:
Priority: normal Milestone: Awaiting Review
Component: Comments Version: 6.9
Severity: normal Keywords: has-patch has-unit-tests has-screenshots
Cc: Focuses:

Description

Related: #64474

Since the block-notes feature (6.9), internal note-type comments share the comments table but are excluded from public comment displays. WP_Comment_Query excludes them by default, wp_update_comment_count_now() excludes them from the per-post count, and comment feeds exclude them (#65613).

get_page_of_comment() still counts them. It builds its count query with type => 'all' (its default), and WP_Comment_Query deliberately does not exclude the note type when the type is all — confirmed as intended behaviour in #64474:

When using the WP_Comment_Query class, it is correct behaviour that note comment types will be included when type=all is requested. However, on the comment table, the note comment type should always be excluded.

The public comment list (comments_template()) queries with type => '', which does exclude notes. So the two disagree: the displayed list omits notes, but the pagination math counts them. On a post that has a note and "Break comments into pages" enabled, a note dated before a given comment shifts that comment onto a later cpage than the one it actually renders on, so get_comment_link() links visitors to the wrong comments page.

Steps to reproduce

  1. Settings → Discussion → enable "Break comments into pages", 1 comment per page.
  2. On a post: add a regular comment, add an internal note dated after it, then add a second regular comment.
  3. get_page_of_comment() for the second comment returns 3 instead of 2 — the note occupies a phantom page.

Proposed fix

Exclude notes from the count query in get_page_of_comment() by passing type__not_in => array( 'note' ), aligning the pagination calculation with the public comment display. This mirrors the fix applied to the comments list table in [61525] / #64474, rather than changing WP_Comment_Query's intended type=all semantics.

PR: https://github.com/WordPress/wordpress-develop/pull/12552

Attachments (2)

65642-before-page3.png (307.3 KB ) - added by dhrupo 3 weeks ago.
BEFORE the fix: the internal note inflates get_page_of_comment(), so get_comment_link() sends Bob's comment permalink to comment-page-3. There are only two real comments (two pages), so the linked page does not contain the comment. See Trac #65642 / PR 12552.
65642-after-page2.png (325.8 KB ) - added by dhrupo 3 weeks ago.
AFTER the fix (PR 12552): the note is excluded from the count, so get_comment_link() points Bob's comment permalink to comment-page-2, where the comment is correctly shown (highlighted). See Trac #65642.

Download all attachments as: .zip

Change History (4)

This ticket was mentioned in PR #12552 on WordPress/wordpress-develop by @dhrupo.


3 weeks ago
#1

Follow-up to the notes work in #64474.

## Summary

Internal note comments (the block-notes feature, 6.9) inflate the page number returned by get_page_of_comment(), which can send visitors to the wrong comments page via get_comment_link().

get_page_of_comment() builds its count query with type => 'all' (its default). WP_Comment_Query deliberately does not exclude the note type when type is 'all' — this was confirmed as intended behavior in #64474:

When using the WP_Comment_Query class, it is correct behaviour that note comment types will be included when type=all is requested. However, on the comment table, the note comment type should always be excluded. — #64474

The public comment list (comments_template()) queries with type => '', which does exclude notes. So the two disagree: the displayed list omits notes, but the pagination math counts them. On a post that has a note and "Break comments into pages" enabled, a note dated before a given comment shifts that comment onto a later cpage than the one it actually renders on.

## Reproduction

  1. Settings → Discussion → enable "Break comments into pages", 1 comment per page.
  2. On a post: add a regular comment, add an internal note dated after it, then add a second regular comment.
  3. get_page_of_comment() for the second comment returns 3 instead of 2 — the note occupies a phantom page.

## Fix

Exclude notes from the count query in get_page_of_comment() by passing type__not_in => array( 'note' ), aligning the pagination calculation with the public comment display. This mirrors the fix applied to the comments list table in [61525] / #64474 (type__not_in => 'note' at the surface that must never show notes), rather than changing WP_Comment_Query's intended type=all semantics.

## Testing

Added test_notes_should_not_affect_page to Tests_Comment_GetPageOfComment.

  • Before the fix, it fails: Failed asserting that 3 is identical to 2.
  • After the fix, it passes.

Full comment group is green:

./vendor/bin/phpunit --group comment
OK (583 tests, 1428 assertions)

## Use of AI Tools

AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Opus 4.8
Used for: Investigating the notes-exclusion surfaces, reproducing the pagination bug, implementing the fix, and writing the regression test. All changes were reviewed by me.

@dhrupo
3 weeks ago

BEFORE the fix: the internal note inflates get_page_of_comment(), so get_comment_link() sends Bob's comment permalink to comment-page-3. There are only two real comments (two pages), so the linked page does not contain the comment. See Trac #65642 / PR 12552.

@dhrupo
3 weeks ago

AFTER the fix (PR 12552): the note is excluded from the count, so get_comment_link() points Bob's comment permalink to comment-page-2, where the comment is correctly shown (highlighted). See Trac #65642.

#2 @dhrupo
3 weeks ago

  • Keywords has-screenshots added
Note: See TracTickets for help on using tickets.