diff --git a/src/wp-admin/includes/export.php b/src/wp-admin/includes/export.php index 9d5903a98c5c3..4fe697e7e6d4d 100644 --- a/src/wp-admin/includes/export.php +++ b/src/wp-admin/includes/export.php @@ -685,7 +685,12 @@ function wxr_filter_postmeta( $return_me, $meta_key ) { endforeach; $_comments = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_approved <> 'spam'", $post->ID ) ); - $comments = array_map( 'get_comment', $_comments ); + $comments = array_filter( + array_map( 'get_comment', $_comments ), + static function ( $comment ) { + return $comment instanceof WP_Comment; + } + ); foreach ( $comments as $c ) : ?> diff --git a/src/wp-includes/comment.php b/src/wp-includes/comment.php index 7ce49765237a7..bb4abf2cd7f7f 100644 --- a/src/wp-includes/comment.php +++ b/src/wp-includes/comment.php @@ -240,9 +240,12 @@ function get_comment( $comment = null, $output = OBJECT ) { * * @since 2.3.0 * - * @param WP_Comment $_comment Comment data. + * @param WP_Comment|null $_comment Comment data. */ $_comment = apply_filters( 'get_comment', $_comment ); + if ( ! ( $_comment instanceof WP_Comment ) ) { + return null; + } if ( OBJECT === $output ) { return $_comment; diff --git a/tests/phpunit/tests/admin/exportWp.php b/tests/phpunit/tests/admin/exportWp.php index ebb60018c0e7a..059dcab1a8351 100644 --- a/tests/phpunit/tests/admin/exportWp.php +++ b/tests/phpunit/tests/admin/exportWp.php @@ -290,4 +290,37 @@ private function populate_args_post_authors( array &$args, $expected_ids ) { $post_ids_key = $expected_ids[0]; $args['author'] = self::$post_ids[ $post_ids_key ]['post_author']; } + + /** + * @ticket 61244 + */ + public function test_export_wp_should_not_include_empty_comments_when_filtered() { + $post_id = self::factory()->post->create( array( 'post_title' => 'Test Post' ) ); + self::factory()->comment->create_post_comments( $post_id, 3 ); + + // Add filter to make get_comment return null. + add_action( + 'export_wp', + static function () { + add_filter( 'get_comment', '__return_null' ); + } + ); + + $xml_obj = $this->get_the_export( array() ); + $comment_tags = $xml_obj->xpath( '//wp:comment' ); + $this->assertCount( 0, $comment_tags, 'No tags should be present when comments are filtered out.' ); + } + + /** + * @ticket 61244 + */ + public function test_export_wp_includes_comments_when_not_filtered() { + $post_id = self::factory()->post->create( array( 'post_title' => 'Test Post' ) ); + $comment_count = 3; + self::factory()->comment->create_post_comments( $post_id, $comment_count ); + + $xml_obj = $this->get_the_export( array() ); + $comment_tags = $xml_obj->xpath( '//wp:comment' ); + $this->assertCount( $comment_count, $comment_tags, 'Export should include all comments when not filtered.' ); + } } diff --git a/tests/phpunit/tests/comment.php b/tests/phpunit/tests/comment.php index 592ad317003ee..11e78140f1020 100644 --- a/tests/phpunit/tests/comment.php +++ b/tests/phpunit/tests/comment.php @@ -1896,4 +1896,20 @@ public function test_wp_trash_comment_only_top_level_notes_trigger_child_deletio // Verify the sibling note is NOT trashed (no cascade since child is not top-level). $this->assertSame( '1', get_comment( $sibling_note )->comment_approved ); } + + /** + * @ticket 61244 + * + * @covers ::get_comment + */ + public function test_get_comment_filter() { + $comment_id = self::factory()->comment->create( array( 'comment_post_ID' => self::$post_id ) ); + + $comment = get_comment( $comment_id ); + $this->assertInstanceOf( WP_Comment::class, $comment ); + $this->assertSame( $comment_id, (int) $comment->comment_ID, 'Expected the same comment.' ); + + add_filter( 'get_comment', '__return_null' ); + $this->assertNull( get_comment( $comment_id ), 'Expected get_comment() to return null when get_comment filter returns null.' ); + } }