diff --git a/src/wp-includes/revision.php b/src/wp-includes/revision.php index 70051a07da..941002ffc6 100644 --- a/src/wp-includes/revision.php +++ b/src/wp-includes/revision.php @@ -516,6 +516,40 @@ function wp_get_post_revisions( $post_id = 0, $args = null ) { return $revisions; } +/** + * Returns the url for viewing and potentially restoring revisions of a given post. + * + * @since 5.9.0 + * + * @param int|WP_Post $post_id Optional. Post ID or WP_Post object. Default is global `$post`. + * @return null|string The URL for editing revisions on the given post, otherwise null. + */ +function wp_get_post_revisions_url( $post_id = 0 ) { + $post = get_post( $post_id ); + + if ( ! $post instanceof WP_Post ) { + return null; + } + + // If the post is a revision, return early. + if ( 'revision' === $post->post_type ) { + return get_edit_post_link( $post ); + } + + if ( ! wp_revisions_enabled( $post ) ) { + return null; + } + + $revisions = wp_get_post_revisions( $post->ID, array( 'posts_per_page' => 1 ) ); + + if ( 0 === count( $revisions ) ) { + return null; + } + + $revision = reset( $revisions ); + return get_edit_post_link( $revision ); +} + /** * Determine if revisions are enabled for a given post. * diff --git a/tests/phpunit/tests/post/revisions.php b/tests/phpunit/tests/post/revisions.php index 35e43f18ae..4ff458a012 100644 --- a/tests/phpunit/tests/post/revisions.php +++ b/tests/phpunit/tests/post/revisions.php @@ -654,4 +654,163 @@ class Tests_Post_Revisions extends WP_UnitTestCase { $this->assertWPError( $revision ); } + + /** + * Tests that wp_get_post_revisions_url() returns the revisions URL. + * + * @ticket 39062 + * + * @dataProvider data_wp_get_post_revisions_url + * + * @covers ::wp_get_post_revisions_url + * + * @param int $revisions The number of revisions to create. + */ + public function test_wp_get_post_revisions_url( $revisions ) { + wp_set_current_user( self::$admin_user_id ); + + $post_id = self::factory()->post->create( array( 'post_title' => 'Some Post' ) ); + $latest_revision_id = null; + + if ( 0 !== $revisions ) { + $latest_revision_id = $post_id; + + for ( $i = 0; $i < $revisions; ++$i ) { + wp_update_post( + array( + 'ID' => $post_id, + 'post_title' => 'Some Post ' . $i, + ) + ); + + $latest_revision_id++; + } + } + + $expected = admin_url( 'revision.php?revision=' . $latest_revision_id ); + + $this->assertSame( + $expected, + wp_get_post_revisions_url( $post_id ), + 'Failed when passed the Post ID' + ); + + $this->assertSame( + $expected, + wp_get_post_revisions_url( $latest_revision_id ), + 'Failed when passed the latest revision ID' + ); + } + + /** + * Tests that wp_get_post_revisions_url() returns the revisions URL + * when passed a WP_Post object. + * + * @ticket 39062 + * + * @dataProvider data_wp_get_post_revisions_url + * + * @covers ::wp_get_post_revisions_url + * + * @param int $revisions The number of revisions to create. + */ + public function test_wp_get_post_revisions_url_with_post_object( $revisions ) { + wp_set_current_user( self::$admin_user_id ); + + $post = self::factory()->post->create_and_get( array( 'post_title' => 'Some Post' ) ); + $latest_revision_id = null; + + if ( 0 !== $revisions ) { + $latest_revision_id = $post->ID; + + for ( $i = 0; $i < $revisions; ++$i ) { + wp_update_post( + array( + 'ID' => $post->ID, + 'post_title' => 'Some Post ' . $i, + ) + ); + + $latest_revision_id++; + } + } + + $expected = admin_url( 'revision.php?revision=' . $latest_revision_id ); + + $this->assertSame( + $expected, + wp_get_post_revisions_url( $post ), + 'Failed when passed the Post Object' + ); + + $this->assertSame( + $expected, + wp_get_post_revisions_url( $latest_revision_id ), + 'Failed when passed the latest revision ID' + ); + } + + /** + * Data provider. + * + * @return array + */ + public function data_wp_get_post_revisions_url() { + return array( + 'one revision' => array( 'revisions' => 1 ), + 'multiple revisions' => array( 'revisions' => 2 ), + ); + } + + /** + * Tests that wp_get_post_revisions_url() returns NULL when a post does not exist. + * + * @ticket 39062 + * + * @covers ::wp_get_post_revisions_url + */ + public function test_wp_get_post_revisions_url_returns_null_when_post_does_not_exist() { + wp_set_current_user( self::$admin_user_id ); + $post_id = 99999; + $this->assertNull( wp_get_post_revisions_url( $post_id ) ); + } + + /** + * Tests that wp_get_post_revisions_url() returns NULL when there are no revisions. + * + * @ticket 39062 + * + * @covers ::wp_get_post_revisions_url + */ + public function test_wp_get_post_revisions_url_returns_null_with_no_revisions() { + wp_set_current_user( self::$admin_user_id ); + $post_id = self::factory()->post->create( array( 'post_title' => 'Some Post' ) ); + $this->assertNull( wp_get_post_revisions_url( $post_id ) ); + } + + /** + * Tests that wp_get_post_revisions_url() returns NULL when revisions are disabled. + * + * @ticket 39062 + * + * @covers ::wp_get_post_revisions_url + */ + public function test_wp_get_post_revisions_url_returns_null_with_revisions_disabled() { + wp_set_current_user( self::$admin_user_id ); + + remove_post_type_support( 'post', 'revisions' ); + + $post_id = self::factory()->post->create( array( 'post_title' => 'Some Post' ) ); + + wp_update_post( + array( + 'ID' => $post_id, + 'post_title' => 'Some Post 2', + ) + ); + + $this->assertNull( wp_get_post_revisions_url( $post_id ) ); + + add_post_type_support( 'post', 'revisions' ); + } }