Skip to content

Commit

Permalink
Adding feedback:
Browse files Browse the repository at this point in the history
- Introducing pagination
- Updating tests
  • Loading branch information
ramonjd committed Jun 23, 2023
1 parent 4985364 commit 09a9053
Show file tree
Hide file tree
Showing 4 changed files with 756 additions and 88 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -435,9 +435,9 @@ protected function prepare_links( $id ) {
);

if ( post_type_supports( $this->post_type, 'revisions' ) ) {
$revisions = wp_get_latest_revision_id_and_total_count( $id );
$revisions_count = ! is_wp_error( $revisions ) ? $revisions['count'] : 0;
$revisions_base = sprintf( '/%s/%s/%d/revisions', $this->namespace, $this->rest_base, $id );
$revisions = wp_get_latest_revision_id_and_total_count( $id );
$revisions_count = ! is_wp_error( $revisions ) ? $revisions['count'] : 0;
$revisions_base = sprintf( '/%s/%d/revisions', $base, $id );
$links['version-history'] = array(
'href' => rest_url( $revisions_base ),
'count' => $revisions_count,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,74 @@ public function register_routes() {
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_items' ),
'permission_callback' => array( $this, 'get_item_permissions_check' ),
'args' => $this->get_collection_params(),
),
'schema' => array( $this, 'get_public_item_schema' ),
)
);
}

/**
* Returns revisions of the given global styles config custom post type.
* Retrieves the query params for collections.
* Taken mostly from WP_REST_Controller->get_collection_params().
*
* @since 6.3.0
*
* @return array Collection parameters.
*/
public function get_collection_params() {
return array(
'context' => array( 'default' => 'view' ),
'page' => array(
'description' => __( 'Current page of the collection.' ),
'type' => 'integer',
'default' => 1,
'sanitize_callback' => 'absint',
'validate_callback' => 'rest_validate_request_arg',
'minimum' => 1,
),
'per_page' => array(
'description' => __( 'Maximum number of items to be returned in result set.' ),
'type' => 'integer',
'minimum' => 1,
'maximum' => 100,
'sanitize_callback' => 'absint',
'validate_callback' => 'rest_validate_request_arg',
),
'offset' => array(
'description' => __( 'Offset the result set by a specific number of items.' ),
'type' => 'integer',
),
);
}

/**
* Returns decoded JSON from post content string,
* or a 404 if not found.
*
* @since 6.3.0
*
* @param string $raw_json Encoded JSON from global styles custom post content.
* @return Array|WP_Error
*/
private function get_decoded_global_styles_json( $raw_json ) {
$decoded_json = json_decode( $raw_json, true );

if ( is_array( $decoded_json ) && isset( $decoded_json['isGlobalStylesUserThemeJSON'] ) && true === $decoded_json['isGlobalStylesUserThemeJSON'] ) {
return $decoded_json;
}

return new WP_Error(
'rest_global_styles_not_found',
__( 'Cannot find user global styles revisions.' ),
array( 'status' => 404 )
);
}

/**
* Returns paginated revisions of the given global styles config custom post type.
* The bulk of the body is taken from WP_REST_Revisions_Controller->get_items,
* but global styles does not require as many parameters.
*
* @since 6.3.0
*
Expand All @@ -83,27 +143,112 @@ public function get_items( $request ) {
if ( is_wp_error( $parent ) ) {
return $parent;
}
$response = array();
$raw_config = json_decode( $parent->post_content, true );
$is_global_styles_user_theme_json = isset( $raw_config['isGlobalStylesUserThemeJSON'] ) && true === $raw_config['isGlobalStylesUserThemeJSON'];

if ( $is_global_styles_user_theme_json ) {
$user_theme_revisions = wp_get_post_revisions(
$parent->ID,
array(
'posts_per_page' => 100,
)
$global_styles_config = $this->get_decoded_global_styles_json( $parent->post_content );

if ( is_wp_error( $global_styles_config ) ) {
return $global_styles_config;
}

if ( wp_revisions_enabled( $parent ) ) {
$registered = $this->get_collection_params();
$query_args = array(
'post_parent' => $parent->ID,
'post_type' => 'revision',
'post_status' => 'inherit',
'posts_per_page' => -1,
'orderby' => 'date ID',
'order' => 'DESC',
);

if ( ! empty( $user_theme_revisions ) ) {
foreach ( $user_theme_revisions as $revision ) {
$revision = $this->prepare_item_for_response( $revision, $request );
$response[] = $this->prepare_response_for_collection( $revision );
$parameter_mappings = array(
'offset' => 'offset',
'page' => 'paged',
'per_page' => 'posts_per_page',
);

foreach ( $parameter_mappings as $api_param => $wp_param ) {
if ( isset( $registered[ $api_param ], $request[ $api_param ] ) ) {
$query_args[ $wp_param ] = $request[ $api_param ];
}
}

$revisions_query = new WP_Query();
$revisions = $revisions_query->query( $query_args );
$offset = isset( $query_args['offset'] ) ? (int) $query_args['offset'] : 0;
$page = (int) $query_args['paged'];
$total_revisions = $revisions_query->found_posts;

if ( $total_revisions < 1 ) {
// Out-of-bounds, run the query again without LIMIT for total count.
unset( $query_args['paged'], $query_args['offset'] );
$count_query = new WP_Query();
$count_query->query( $query_args );

$total_revisions = $count_query->found_posts;
}

if ( $revisions_query->query_vars['posts_per_page'] > 0 ) {
$max_pages = ceil( $total_revisions / (int) $revisions_query->query_vars['posts_per_page'] );
} else {
$max_pages = $total_revisions > 0 ? 1 : 0;
}
if ( $total_revisions > 0 ) {
if ( $offset >= $total_revisions ) {
return new WP_Error(
'rest_revision_invalid_offset_number',
__( 'The offset number requested is larger than or equal to the number of available revisions.' ),
array( 'status' => 400 )
);
} elseif ( ! $offset && $page > $max_pages ) {
return new WP_Error(
'rest_revision_invalid_page_number',
__( 'The page number requested is larger than the number of pages available.' ),
array( 'status' => 400 )
);
}
}
} else {
$revisions = array();
$total_revisions = 0;
$max_pages = 0;
$page = (int) $request['page'];
}

return rest_ensure_response( $response );
$response = array();

foreach ( $revisions as $revision ) {
$data = $this->prepare_item_for_response( $revision, $request );
$response[] = $this->prepare_response_for_collection( $data );
}

$response = rest_ensure_response( $response );

$response->header( 'X-WP-Total', (int) $total_revisions );
$response->header( 'X-WP-TotalPages', (int) $max_pages );

$request_params = $request->get_query_params();
$base_path = rest_url( sprintf( '%s/%s/%d/%s', $this->namespace, $this->parent_base, $request['parent'], $this->rest_base ) );
$base = add_query_arg( urlencode_deep( $request_params ), $base_path );

if ( $page > 1 ) {
$prev_page = $page - 1;

if ( $prev_page > $max_pages ) {
$prev_page = $max_pages;
}

$prev_link = add_query_arg( 'page', $prev_page, $base );
$response->link_header( 'prev', $prev_link );
}
if ( $max_pages > $page ) {
$next_page = $page + 1;
$next_link = add_query_arg( 'page', $next_page, $base );

$response->link_header( 'next', $next_link );
}

return $response;
}

/**
Expand Down Expand Up @@ -139,13 +284,18 @@ protected function prepare_date_response( $date_gmt, $date = null ) {
* @return WP_REST_Response Response object.
*/
public function prepare_item_for_response( $post, $request ) {
$parent = $this->get_parent( $request['parent'] );
// Retrieves global styles config as JSON.
$raw_revision_config = json_decode( $post->post_content, true );
$config = ( new WP_Theme_JSON( $raw_revision_config, 'custom' ) )->get_raw_data();
$parent = $this->get_parent( $request['parent'] );
$global_styles_config = $this->get_decoded_global_styles_json( $post->post_content );
$data = array();

if ( is_wp_error( $global_styles_config ) ) {
return rest_ensure_response( $data );
}

if ( ! empty( $global_styles_config['styles'] ) || ! empty( $global_styles_config['settings'] ) ) {
$global_styles_config = ( new WP_Theme_JSON( $global_styles_config, 'custom' ) )->get_raw_data();
}

// Prepares item data.
$data = array();
$fields = $this->get_fields_for_response( $request );

if ( rest_is_field_included( 'author', $fields ) ) {
Expand Down Expand Up @@ -177,11 +327,11 @@ public function prepare_item_for_response( $post, $request ) {
}

if ( rest_is_field_included( 'settings', $fields ) ) {
$data['settings'] = ! empty( $config['settings'] ) ? $config['settings'] : new stdClass();
$data['settings'] = ! empty( $global_styles_config['settings'] ) ? $global_styles_config['settings'] : new stdClass();
}

if ( rest_is_field_included( 'styles', $fields ) ) {
$data['styles'] = ! empty( $config['styles'] ) ? $config['styles'] : new stdClass();
$data['styles'] = ! empty( $global_styles_config['styles'] ) ? $global_styles_config['styles'] : new stdClass();
}

$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,6 @@ public function get_items( $request ) {
'posts_per_page' => -1,
'orderby' => 'date ID',
'order' => 'DESC',
'suppress_filters' => true,
);

$parameter_mappings = array(
Expand Down
Loading

0 comments on commit 09a9053

Please sign in to comment.