Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement core style of including revisions data on Post response #7495

Merged
merged 3 commits into from
Jun 25, 2018
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: 2 additions & 2 deletions editor/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ export function getCurrentPostId( state ) {
* @return {number} Number of revisions.
*/
export function getCurrentPostRevisionsCount( state ) {
return get( getCurrentPost( state ), [ 'revisions', 'count' ], 0 );
return get( getCurrentPost( state ), [ '_links', 'version-history', 0, 'count' ], 0 );
}

/**
Expand All @@ -167,7 +167,7 @@ export function getCurrentPostRevisionsCount( state ) {
* @return {?number} ID of the last revision.
*/
export function getCurrentPostLastRevisionId( state ) {
return get( getCurrentPost( state ), [ 'revisions', 'last_id' ], null );
return get( getCurrentPost( state ), [ '_links', 'predecessor-version', 0, 'id' ], null );
}

/**
Expand Down
16 changes: 12 additions & 4 deletions editor/store/test/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -515,8 +515,12 @@ describe( 'selectors', () => {
it( 'should return the last revision ID', () => {
const state = {
currentPost: {
revisions: {
last_id: 123,
_links: {
'predecessor-version': [
{
id: 123,
},
],
},
},
};
Expand All @@ -537,8 +541,12 @@ describe( 'selectors', () => {
it( 'should return the number of revisions', () => {
const state = {
currentPost: {
revisions: {
count: 5,
_links: {
'version-history': [
{
count: 5,
},
],
},
},
};
Expand Down
83 changes: 43 additions & 40 deletions lib/rest-api.php
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,48 @@ function gutenberg_add_target_schema_to_links( $response, $post, $request ) {
return $response;
}

/**
* Include revisions data on post response links.
*
* @see https://core.trac.wordpress.org/ticket/44321
*
* @param WP_REST_Response $response WP REST API response of a post.
* @param WP_Post $post The post being returned.
* @param WP_REST_Request $request WP REST API request.
* @return WP_REST_Response Response containing the new links.
*/
function gutenberg_add_revisions_data_to_links( $response, $post, $request ) {

$new_links = array();
$orig_links = $response->get_links();

if ( ! empty( $orig_links['version-history'] ) ) {
$version_history_link = array_shift( $orig_links['version-history'] );
// 'version-history' already exists and we don't want to duplicate it.
$response->remove_link( 'version-history' );

$revisions = wp_get_post_revisions( $post->ID, array( 'fields' => 'ids' ) );
$revisions_count = count( $revisions );

$new_links['version-history'] = array(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: If intent is to merge in the count attribute, may be more clear if used array_merge to indicate as such.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$orig_links['version-history'] has a different format and can't be used directly.

'href' => $version_history_link['href'],
'count' => $revisions_count,
);

if ( $revisions_count > 0 ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't it be greater than 1? I think we don't render the link if there is only 1 revision.

Yep, confirmed:

if ( ! lastRevisionId || revisionsCount < 2 ) {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't it be greater than 1? I think we don't render the link if there is only 1 revision.

That's a client specific detail. Seems to me the REST API should provide the raw value (maybe even if it were 0).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming it is still a correct url, is fine as is.

$last_revision = array_shift( $revisions );

$new_links['predecessor-version'] = array(
'href' => $version_history_link['href'] . '/' . $last_revision,
'id' => $last_revision,
);
}
}

$response->add_links( $new_links );
return $response;
}

/**
* Whenever a post type is registered, ensure we're hooked into it's WP REST API response.
*
Expand All @@ -348,6 +390,7 @@ function gutenberg_register_post_prepare_functions( $post_type ) {
add_filter( "rest_prepare_{$post_type}", 'gutenberg_add_permalink_template_to_posts', 10, 3 );
add_filter( "rest_prepare_{$post_type}", 'gutenberg_add_block_format_to_post_content', 10, 3 );
add_filter( "rest_prepare_{$post_type}", 'gutenberg_add_target_schema_to_links', 10, 3 );
add_filter( "rest_prepare_{$post_type}", 'gutenberg_add_revisions_data_to_links', 10, 3 );
add_filter( "rest_{$post_type}_collection_params", 'gutenberg_filter_post_collection_parameters', 10, 2 );
add_filter( "rest_{$post_type}_query", 'gutenberg_filter_post_query_arguments', 10, 2 );
return $post_type;
Expand All @@ -365,46 +408,6 @@ function gutenberg_register_taxonomy_prepare_functions( $taxonomy ) {
}
add_filter( 'registered_taxonomy', 'gutenberg_register_taxonomy_prepare_functions' );

/**
* Gets revisions details for the selected post.
*
* @since 1.6.0
*
* @param array $post The post object from the response.
* @return array|null Revisions details or null when no revisions present.
*/
function gutenberg_get_post_revisions( $post ) {
$revisions = wp_get_post_revisions( $post['id'] );
$revisions_count = count( $revisions );
if ( 0 === $revisions_count ) {
return null;
}

$last_revision = array_shift( $revisions );

return array(
'count' => $revisions_count,
'last_id' => $last_revision->ID,
);
}

/**
* Adds the custom field `revisions` to the REST API response of post.
*
* TODO: This is a temporary solution. Next step would be to find a solution that is limited to the editor.
*
* @since 1.6.0
*/
function gutenberg_register_rest_api_post_revisions() {
register_rest_field( get_post_types( '', 'names' ),
'revisions',
array(
'get_callback' => 'gutenberg_get_post_revisions',
)
);
}
add_action( 'rest_api_init', 'gutenberg_register_rest_api_post_revisions' );

/**
* Ensure that the wp-json index contains the 'theme-supports' setting as
* part of its site info elements.
Expand Down
23 changes: 23 additions & 0 deletions phpunit/class-gutenberg-rest-api-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -414,4 +414,27 @@ public function test_get_pages_unbounded_per_page_unauthorized() {
$data = $response->get_data();
$this->assertEquals( 'rest_forbidden_per_page', $data['code'] );
}

public function test_get_post_links_predecessor_version() {
$post_id = $this->factory->post->create();
wp_update_post(
array(
'post_content' => 'This content is marvelous.',
'ID' => $post_id,
)
);
$revisions = wp_get_post_revisions( $post_id );
$revision_1 = array_pop( $revisions );

$request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/posts/%d', $post_id ) );
$response = rest_get_server()->dispatch( $request );

$links = $response->get_links();

$this->assertEquals( rest_url( '/wp/v2/posts/' . $post_id . '/revisions' ), $links['version-history'][0]['href'] );
$this->assertEquals( 1, $links['version-history'][0]['attributes']['count'] );

$this->assertEquals( rest_url( '/wp/v2/posts/' . $post_id . '/revisions/' . $revision_1->ID ), $links['predecessor-version'][0]['href'] );
$this->assertEquals( $revision_1->ID, $links['predecessor-version'][0]['attributes']['id'] );
}
}