diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php index 58be931937..f07c8d2893 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php @@ -2024,8 +2024,8 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { } if ( in_array( $post->post_type, array( 'post', 'page' ), true ) || post_type_supports( $post->post_type, 'revisions' ) ) { - $revisions = wp_get_post_revisions( $post->ID, array( 'fields' => 'ids' ) ); - $revisions_count = count( $revisions ); + $revision = wp_get_lastest_revision_id_and_total_count( $post->ID ); + $revisions_count = ! is_wp_error( $revision ) ? $revision['count'] : 0; $links['version-history'] = array( 'href' => rest_url( trailingslashit( $base ) . $post->ID . '/revisions' ), @@ -2033,8 +2033,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { ); if ( $revisions_count > 0 ) { - $last_revision = array_shift( $revisions ); - + $last_revision = $revision['revision']; $links['predecessor-version'] = array( 'href' => rest_url( trailingslashit( $base ) . $post->ID . '/revisions/' . $last_revision ), 'id' => $last_revision, diff --git a/src/wp-includes/revision.php b/src/wp-includes/revision.php index 1c837d7b59..5f203fb730 100644 --- a/src/wp-includes/revision.php +++ b/src/wp-includes/revision.php @@ -527,6 +527,57 @@ function wp_get_post_revisions( $post = 0, $args = null ) { return $revisions; } +/** + * Get latest revision and count of revisions for a post. + * + * @since 6.1.0 + * + * @param int|WP_Post|null $post Optional. Post ID or WP_Post object. Default is global $post. + * @return WP_Error|array { + * Returns associative array with last revision and total count. + * + * @type int $revision The last revision post id or 0 if non existing. + * @type int $count The total count of revisions for $post_id. + * } + */ +function wp_get_lastest_revision_id_and_total_count( $post = null ) { + $post = get_post( $post ); + + if ( ! $post ) { + return new WP_Error( 'revision_error', __( 'Invalid post.' ) ); + } + + if ( ! wp_revisions_enabled( $post ) ) { + return new WP_Error( 'revision_error', __( 'Revisions not enabled.' ) ); + } + + $args = array( + 'post_parent' => $post->ID, + 'fields' => 'ids', + 'post_type' => 'revision', + 'post_status' => 'inherit', + 'order' => 'DESC', + 'orderby' => 'date ID', + 'posts_per_page' => 1, + 'ignore_sticky_posts' => true, + ); + + $revision_query = new WP_Query(); + $revisions = $revision_query->query( $args ); + + if ( ! $revisions ) { + return array( + 'revision' => 0, + 'count' => 0, + ); + } + + return array( + 'revision' => $revisions[0], + 'count' => $revision_query->found_posts, + ); +} + /** * Returns the url for viewing and potentially restoring revisions of a given post. * diff --git a/tests/phpunit/tests/post/revisions.php b/tests/phpunit/tests/post/revisions.php index 322114e474..69feaa0125 100644 --- a/tests/phpunit/tests/post/revisions.php +++ b/tests/phpunit/tests/post/revisions.php @@ -655,6 +655,57 @@ class Tests_Post_Revisions extends WP_UnitTestCase { $this->assertWPError( $revision ); } + /** + * Tests that wp_get_lastest_revision_id_and_total_count() returns last revision id and total count. + * + * @ticket 55857 + * @dataProvider data_wp_get_post_revisions_url + */ + public function test_wp_get_last_revision_id_and_total_count( $revisions ) { + $post_id = self::factory()->post->create(); + for ( $i = 0; $i < $revisions; ++$i ) { + wp_update_post( + array( + 'ID' => $post_id, + 'post_title' => 'Some Post', + ) + ); + } + + $post_revisions = wp_get_post_revisions( $post_id ); + $last_post_revision = current( $post_revisions ); + $revision = wp_get_lastest_revision_id_and_total_count( $post_id ); + + $this->assertSame( + $last_post_revision->ID, + $revision['revision'], + 'Failed asserting latest revision id.' + ); + + $this->assertSame( + count( $post_revisions ), + $revision['count'], + 'Failed asserting total count of revision.' + ); + } + + /** + * Tests that wp_get_lastest_revision_id_and_total_count() when no revisions. + * + * @ticket 55857 + */ + public function test_wp_get_last_revision_id_and_total_count_no_revisions() { + $revision = wp_get_lastest_revision_id_and_total_count( null ); + $this->assertWPError( $revision, 'Invalid Post, non existing revisions.' ); + $this->assertSame( $revision->get_error_message(), 'Invalid post.' ); + + add_filter( 'wp_revisions_to_keep', '__return_zero' ); + $post_id = self::factory()->post->create(); + $revision = wp_get_lastest_revision_id_and_total_count( $post_id ); + $this->assertWPError( $revision, 'Revisions should be not enabled.' ); + $this->assertSame( $revision->get_error_message(), 'Revisions not enabled.' ); + } + /** * Tests that wp_get_post_revisions_url() returns the revisions URL. * diff --git a/tests/phpunit/tests/rest-api/rest-posts-controller.php b/tests/phpunit/tests/rest-api/rest-posts-controller.php index a26bc45c19..6655c774fc 100644 --- a/tests/phpunit/tests/rest-api/rest-posts-controller.php +++ b/tests/phpunit/tests/rest-api/rest-posts-controller.php @@ -121,7 +121,9 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te } public function save_posts_clauses( $orderby, $query ) { - array_push( $this->posts_clauses, $orderby ); + if ( 'revision' !== $query->query_vars['post_type'] ) { + array_push( $this->posts_clauses, $orderby ); + } return $orderby; }