REST API: Don't validate status if it hasn't changed.

In particular, this allows for sending `status=inherit` to an attachment if it's current status is `inherit`. This status would be rejected because it is an "internal" post status which isn't exposed.

As a general rule, a developer should always be able to PUT back a GET response without error.

Props dfenton, pputzer, TimothyBlynJacobs.
Fixes #40399.


Built from https://develop.svn.wordpress.org/trunk@49302


git-svn-id: http://core.svn.wordpress.org/trunk@49064 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
TimothyBlynJacobs 2020-10-24 16:04:05 +00:00
parent abbc108d19
commit 36c4c943ba
2 changed files with 38 additions and 3 deletions

View File

@ -1052,7 +1052,8 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
* @return stdClass|WP_Error Post object or WP_Error.
*/
protected function prepare_item_for_database( $request ) {
$prepared_post = new stdClass();
$prepared_post = new stdClass();
$current_status = '';
// Post ID.
if ( isset( $request['id'] ) ) {
@ -1062,6 +1063,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
}
$prepared_post->ID = $existing_post->ID;
$current_status = $existing_post->post_status;
}
$schema = $this->get_item_schema();
@ -1105,7 +1107,11 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
$post_type = get_post_type_object( $prepared_post->post_type );
// Post status.
if ( ! empty( $schema['properties']['status'] ) && isset( $request['status'] ) ) {
if (
! empty( $schema['properties']['status'] ) &&
isset( $request['status'] ) &&
( ! $current_status || $current_status !== $request['status'] )
) {
$status = $this->handle_status_param( $request['status'], $post_type );
if ( is_wp_error( $status ) ) {
@ -1255,6 +1261,32 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
}
/**
* Checks whether the status is valid for the given post.
*
* Allows for sending an update request with the current status, even if that status would not be acceptable.
*
* @since 5.6.0
*
* @param string $status The provided status.
* @param WP_REST_Request $request The request object.
* @param string $param The parameter name.
* @return true|WP_Error True if the status is valid, or WP_Error if not.
*/
public function check_status( $status, $request, $param ) {
if ( $request['id'] ) {
$post = $this->get_post( $request['id'] );
if ( ! is_wp_error( $post ) && $post->post_status === $status ) {
return true;
}
}
$args = $request->get_attributes()['args'][ $param ];
return rest_validate_value_from_schema( $status, $args, $param );
}
/**
* Determines validity and normalizes the given status parameter.
*
@ -2115,6 +2147,9 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
'type' => 'string',
'enum' => array_keys( get_post_stati( array( 'internal' => false ) ) ),
'context' => array( 'view', 'edit' ),
'arg_options' => array(
'validate_callback' => array( $this, 'check_status' ),
),
),
'type' => array(
'description' => __( 'Type of Post for the object.' ),

View File

@ -13,7 +13,7 @@
*
* @global string $wp_version
*/
$wp_version = '5.6-beta1-49301';
$wp_version = '5.6-beta1-49302';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.