--- a/wp/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php Thu Sep 29 08:06:27 2022 +0200
+++ b/wp/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php Fri Sep 05 18:40:08 2025 +0200
@@ -25,6 +25,14 @@
private $parent_post_type;
/**
+ * Instance of a revision meta fields object.
+ *
+ * @since 6.4.0
+ * @var WP_REST_Post_Meta_Fields
+ */
+ protected $meta;
+
+ /**
* Parent controller.
*
* @since 4.7.0
@@ -48,16 +56,19 @@
* @param string $parent_post_type Post type of the parent.
*/
public function __construct( $parent_post_type ) {
- $this->parent_post_type = $parent_post_type;
+ $this->parent_post_type = $parent_post_type;
+ $post_type_object = get_post_type_object( $parent_post_type );
+ $parent_controller = $post_type_object->get_rest_controller();
+
+ if ( ! $parent_controller ) {
+ $parent_controller = new WP_REST_Posts_Controller( $parent_post_type );
+ }
+
+ $this->parent_controller = $parent_controller;
$this->rest_base = 'revisions';
- $post_type_object = get_post_type_object( $parent_post_type );
$this->parent_base = ! empty( $post_type_object->rest_base ) ? $post_type_object->rest_base : $post_type_object->name;
$this->namespace = ! empty( $post_type_object->rest_namespace ) ? $post_type_object->rest_namespace : 'wp/v2';
- $this->parent_controller = $post_type_object->get_rest_controller();
-
- if ( ! $this->parent_controller ) {
- $this->parent_controller = new WP_REST_Posts_Controller( $parent_post_type );
- }
+ $this->meta = new WP_REST_Post_Meta_Fields( $parent_post_type );
}
/**
@@ -126,7 +137,6 @@
'schema' => array( $this, 'get_public_item_schema' ),
)
);
-
}
/**
@@ -134,25 +144,29 @@
*
* @since 4.7.2
*
- * @param int $parent Supplied ID.
+ * @param int $parent_post_id Supplied ID.
* @return WP_Post|WP_Error Post object if ID is valid, WP_Error otherwise.
*/
- protected function get_parent( $parent ) {
+ protected function get_parent( $parent_post_id ) {
$error = new WP_Error(
'rest_post_invalid_parent',
__( 'Invalid post parent ID.' ),
array( 'status' => 404 )
);
- if ( (int) $parent <= 0 ) {
+
+ if ( (int) $parent_post_id <= 0 ) {
return $error;
}
- $parent = get_post( (int) $parent );
- if ( empty( $parent ) || empty( $parent->ID ) || $this->parent_post_type !== $parent->post_type ) {
+ $parent_post = get_post( (int) $parent_post_id );
+
+ if ( empty( $parent_post ) || empty( $parent_post->ID )
+ || $this->parent_post_type !== $parent_post->post_type
+ ) {
return $error;
}
- return $parent;
+ return $parent_post;
}
/**
@@ -294,7 +308,7 @@
}
if ( $revisions_query->query_vars['posts_per_page'] > 0 ) {
- $max_pages = ceil( $total_revisions / (int) $revisions_query->query_vars['posts_per_page'] );
+ $max_pages = (int) ceil( $total_revisions / (int) $revisions_query->query_vars['posts_per_page'] );
} else {
$max_pages = $total_revisions > 0 ? 1 : 0;
}
@@ -334,7 +348,8 @@
$response->header( 'X-WP-TotalPages', (int) $max_pages );
$request_params = $request->get_query_params();
- $base = add_query_arg( urlencode_deep( $request_params ), rest_url( sprintf( '%s/%s/%d/%s', $this->namespace, $this->parent_base, $request['parent'], $this->rest_base ) ) );
+ $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;
@@ -372,6 +387,7 @@
* Retrieves one revision from the collection.
*
* @since 4.7.0
+ * @since 6.5.0 Added a condition to check that parent id matches revision parent id.
*
* @param WP_REST_Request $request Full details about the request.
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
@@ -387,6 +403,15 @@
return $revision;
}
+ if ( (int) $parent->ID !== (int) $revision->post_parent ) {
+ return new WP_Error(
+ 'rest_revision_parent_id_mismatch',
+ /* translators: %d: A post id. */
+ sprintf( __( 'The revision does not belong to the specified parent with id of "%d"' ), $parent->ID ),
+ array( 'status' => 404 )
+ );
+ }
+
$response = $this->prepare_item_for_response( $revision, $request );
return rest_ensure_response( $response );
}
@@ -405,8 +430,6 @@
return $parent;
}
- $parent_post_type = get_post_type_object( $parent->post_type );
-
if ( ! current_user_can( 'delete_post', $parent->ID ) ) {
return new WP_Error(
'rest_cannot_delete',
@@ -537,13 +560,16 @@
* @since 4.7.0
* @since 5.9.0 Renamed `$post` to `$item` to match parent class for PHP 8 named parameter support.
*
+ * @global WP_Post $post Global post object.
+ *
* @param WP_Post $item Post revision object.
* @param WP_REST_Request $request Request object.
* @return WP_REST_Response Response object.
*/
public function prepare_item_for_response( $item, $request ) {
// Restores the more descriptive, specific name for use within this method.
- $post = $item;
+ $post = $item;
+
$GLOBALS['post'] = $post;
setup_postdata( $post );
@@ -614,13 +640,17 @@
);
}
+ if ( rest_is_field_included( 'meta', $fields ) ) {
+ $data['meta'] = $this->meta->get_value( $post->ID, $request );
+ }
+
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
$data = $this->add_additional_fields_to_object( $data, $request );
$data = $this->filter_response_by_context( $data, $context );
$response = rest_ensure_response( $data );
if ( ! empty( $data['parent'] ) ) {
- $response->add_link( 'parent', rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->parent_base, $data['parent'] ) ) );
+ $response->add_link( 'parent', rest_url( rest_get_route_for_post( $data['parent'] ) ) );
}
/**
@@ -747,6 +777,8 @@
$schema['properties']['guid'] = $parent_schema['properties']['guid'];
}
+ $schema['properties']['meta'] = $this->meta->get_field_schema();
+
$this->schema = $schema;
return $this->add_additional_fields_schema( $this->schema );