diff --git a/.github/changelog/fix-comment-query-type-not-in-merge b/.github/changelog/fix-comment-query-type-not-in-merge new file mode 100644 index 0000000000..9fffbd7984 --- /dev/null +++ b/.github/changelog/fix-comment-query-type-not-in-merge @@ -0,0 +1,4 @@ +Significance: patch +Type: fixed + +Fix likes and reposts appearing in the standard Comments block when another plugin also filters comment types. diff --git a/includes/class-comment.php b/includes/class-comment.php index de9d6d3615..eddc40a313 100644 --- a/includes/class-comment.php +++ b/includes/class-comment.php @@ -789,13 +789,16 @@ public static function comment_query( $query ) { return; } - // Do not exclude likes and reposts if the query is already excluding other comment types. + // Exclude likes and reposts by the ActivityPub plugin. + // Merge with any existing type__not_in values so other plugins' exclusions are preserved. + $excluded_types = self::get_comment_type_slugs(); + if ( ! empty( $query->query_vars['type__not_in'] ) ) { - return; + $existing = (array) $query->query_vars['type__not_in']; + $excluded_types = \array_unique( \array_merge( $existing, $excluded_types ) ); } - // Exclude likes and reposts by the ActivityPub plugin. - $query->query_vars['type__not_in'] = self::get_comment_type_slugs(); + $query->query_vars['type__not_in'] = $excluded_types; } /** diff --git a/tests/phpunit/tests/includes/class-test-comment.php b/tests/phpunit/tests/includes/class-test-comment.php index a314722256..a741d9e51a 100644 --- a/tests/phpunit/tests/includes/class-test-comment.php +++ b/tests/phpunit/tests/includes/class-test-comment.php @@ -1633,4 +1633,72 @@ public function test_comment_query_respects_explicit_type_in() { $this->assertContains( (string) $like_comment_id, $comment_ids, 'Like should be included when explicitly requested via type__in' ); $this->assertContains( (string) $repost_comment_id, $comment_ids, 'Repost should be included when explicitly requested via type__in' ); } + + /** + * Test that ActivityPub comment types are still excluded when another plugin sets type__not_in. + * + * Simulates a situation where another plugin (e.g. Friends, Webmention) adds its own + * comment types to type__not_in via pre_get_comments. ActivityPub types must also + * be excluded so that likes and reposts do not appear in the standard Comments block. + * + * @covers ::comment_query + */ + public function test_comment_query_merges_with_existing_type__not_in() { + $post_id = self::factory()->post->create( array( 'post_status' => 'publish' ) ); + + // Navigate to the single post page so that is_singular() returns true. + $this->go_to( \get_permalink( $post_id ) ); + + // Create a regular comment, a like, and a "webmention" comment (simulating another plugin's type). + $regular_comment_id = self::factory()->comment->create( + array( + 'comment_post_ID' => $post_id, + 'comment_type' => 'comment', + 'comment_content' => 'Regular comment', + 'comment_approved' => '1', + 'comment_author_email' => 'regular@example.com', + ) + ); + $like_comment_id = self::factory()->comment->create( + array( + 'comment_post_ID' => $post_id, + 'comment_type' => 'like', + 'comment_content' => 'Like', + 'comment_approved' => '1', + 'comment_author_email' => 'like@example.com', + ) + ); + $webmention_comment_id = self::factory()->comment->create( + array( + 'comment_post_ID' => $post_id, + 'comment_type' => 'webmention', + 'comment_content' => 'Webmention', + 'comment_approved' => '1', + 'comment_author_email' => 'webmention@example.com', + ) + ); + + // Simulate another plugin adding its own type to type__not_in via pre_get_comments + // at an earlier priority (runs before ActivityPub's priority-10 callback). + $other_plugin_filter = function ( $query ) { + if ( ! empty( $query->query_vars['type__not_in'] ) ) { + return; + } + $query->query_vars['type__not_in'] = array( 'webmention' ); + }; + \add_action( 'pre_get_comments', $other_plugin_filter, 5 ); + + // Query without explicit type restrictions — both the other plugin's type and + // ActivityPub's types (like, repost) should be excluded. + $query = new \WP_Comment_Query(); + $comments = $query->query( array( 'post_id' => $post_id ) ); + + \remove_action( 'pre_get_comments', $other_plugin_filter, 5 ); + + $comment_ids = \wp_list_pluck( $comments, 'comment_ID' ); + + $this->assertContains( (string) $regular_comment_id, $comment_ids, 'Regular comment should be included.' ); + $this->assertNotContains( (string) $like_comment_id, $comment_ids, 'Like should be excluded even when another plugin sets type__not_in first.' ); + $this->assertNotContains( (string) $webmention_comment_id, $comment_ids, 'Webmention (excluded by the other plugin) should also be excluded.' ); + } }