Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 .github/changelog/fix-reader-comments-feed
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: fixed

Replies to posts from accounts you follow no longer show up in your comments feed and comment widgets.
32 changes: 31 additions & 1 deletion includes/class-comment.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public static function init() {
\add_filter( 'comment_reply_link', array( self::class, 'comment_reply_link' ), 10, 3 );
\add_filter( 'comment_class', array( self::class, 'comment_class' ), 10, 3 );
\add_filter( 'comment_feed_where', array( static::class, 'comment_feed_where' ) );
\add_filter( 'widget_comments_args', array( static::class, 'widget_comments_args' ) );
\add_filter( 'get_comment_link', array( self::class, 'remote_comment_link' ), 11, 2 );
\add_action( 'pre_get_comments', array( static::class, 'comment_query' ) );
\add_filter( 'get_page_of_comment_query_args', array( static::class, 'get_page_of_comment_query_args' ) );
Expand Down Expand Up @@ -435,7 +436,8 @@ public static function comment_class( $classes, $css_class, $comment_id ) {
/**
* Makes the comment feed filterable by comment type.
*
* Also excludes ActivityPub comment types from the feed when no type is specified.
* Also excludes ActivityPub comment types from the feed when no type is specified,
* and replies to remote posts in any case.
*
* @param string $where The `WHERE` clause for the comment feed query.
*
Expand All @@ -444,6 +446,14 @@ public static function comment_class( $classes, $css_class, $comment_id ) {
public static function comment_feed_where( $where ) {
global $wpdb;

// Replies to remote posts belong to the reader, not to the site's comments.
$hide_for = self::hide_for();
if ( $hide_for ) {
$placeholders = \implode( ', ', \array_fill( 0, \count( $hide_for ), '%s' ) );
// phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber, WordPress.DB.PreparedSQL.NotPrepared
$where .= $wpdb->prepare( \sprintf( " AND {$wpdb->comments}.comment_post_ID NOT IN ( SELECT ID FROM {$wpdb->posts} WHERE post_type IN (%s) )", $placeholders ), ...$hide_for );
}

$comment_type = \get_query_var( 'type' );

if ( 'all' === $comment_type ) {
Expand All @@ -463,6 +473,26 @@ public static function comment_feed_where( $where ) {
return $where;
}

/**
* Keeps replies to remote posts out of the Recent Comments widget and the Latest Comments block.
*
* @since unreleased
*
* @param array $args The comment query arguments.
*
* @return array The filtered arguments.
*/
public static function widget_comments_args( $args ) {
$hide_for = self::hide_for();

// The comment query has no `post_type__not_in`, so list every other post type.
if ( $hide_for && empty( $args['post_type'] ) ) {
$args['post_type'] = \array_values( \array_diff( \get_post_types(), $hide_for ) );
}

return $args;
}

/**
* Gets the public comment id via the WordPress comments meta.
*
Expand Down
39 changes: 39 additions & 0 deletions tests/phpunit/tests/includes/class-test-comment.php
Original file line number Diff line number Diff line change
Expand Up @@ -872,6 +872,45 @@ public function test_comment_feed_where() {
\set_query_var( 'type', null );
}

/**
* Replies to remote posts stay out of the comments feed and the comment widgets.
*
* @covers ::comment_feed_where
* @covers ::widget_comments_args
*/
public function test_remote_post_replies_stay_out_of_public_lists() {
// Comments on post types without comment support stay in the lists.
\register_post_type( 'no_comment_support', array( 'supports' => array( 'title' ) ) );

$comment_ids = array();
foreach ( array( 'post', 'no_comment_support', Remote_Posts::POST_TYPE ) as $post_type ) {
$comment_ids[ $post_type ] = self::factory()->comment->create(
array(
'comment_approved' => '1',
'comment_post_ID' => self::factory()->post->create( array( 'post_type' => $post_type ) ),
)
);
}
$expected = array( (string) $comment_ids['post'], (string) $comment_ids['no_comment_support'] );

foreach ( array( null, 'all' ) as $type ) {
\set_query_var( 'type', $type );
$query = new \WP_Query(
array(
'feed' => 'comments-rss2',
'withcomments' => true,
)
);
$this->assertEqualSets( $expected, \wp_list_pluck( $query->comments, 'comment_ID' ) );
}
\set_query_var( 'type', null );

$args = \apply_filters( 'widget_comments_args', array( 'post_status' => 'publish' ), array() );
$this->assertEqualSets( $expected, \wp_list_pluck( \get_comments( $args ), 'comment_ID' ) );

\unregister_post_type( 'no_comment_support' );
}

/**
* Test that comments on ap_post are excluded from admin comment queries.
*
Expand Down
Loading