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. git-svn-id: https://develop.svn.wordpress.org/trunk@49302 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
ff989eccce
commit
e66f459435
@ -1052,7 +1052,8 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|||||||
* @return stdClass|WP_Error Post object or WP_Error.
|
* @return stdClass|WP_Error Post object or WP_Error.
|
||||||
*/
|
*/
|
||||||
protected function prepare_item_for_database( $request ) {
|
protected function prepare_item_for_database( $request ) {
|
||||||
$prepared_post = new stdClass();
|
$prepared_post = new stdClass();
|
||||||
|
$current_status = '';
|
||||||
|
|
||||||
// Post ID.
|
// Post ID.
|
||||||
if ( isset( $request['id'] ) ) {
|
if ( isset( $request['id'] ) ) {
|
||||||
@ -1062,6 +1063,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$prepared_post->ID = $existing_post->ID;
|
$prepared_post->ID = $existing_post->ID;
|
||||||
|
$current_status = $existing_post->post_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
$schema = $this->get_item_schema();
|
$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_type = get_post_type_object( $prepared_post->post_type );
|
||||||
|
|
||||||
// Post status.
|
// 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 );
|
$status = $this->handle_status_param( $request['status'], $post_type );
|
||||||
|
|
||||||
if ( is_wp_error( $status ) ) {
|
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.
|
* Determines validity and normalizes the given status parameter.
|
||||||
*
|
*
|
||||||
@ -2115,6 +2147,9 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
|||||||
'type' => 'string',
|
'type' => 'string',
|
||||||
'enum' => array_keys( get_post_stati( array( 'internal' => false ) ) ),
|
'enum' => array_keys( get_post_stati( array( 'internal' => false ) ) ),
|
||||||
'context' => array( 'view', 'edit' ),
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'arg_options' => array(
|
||||||
|
'validate_callback' => array( $this, 'check_status' ),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
'type' => array(
|
'type' => array(
|
||||||
'description' => __( 'Type of Post for the object.' ),
|
'description' => __( 'Type of Post for the object.' ),
|
||||||
|
@ -1007,6 +1007,53 @@ class WP_Test_REST_Attachments_Controller extends WP_Test_REST_Post_Type_Control
|
|||||||
$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
|
$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ticket 40399
|
||||||
|
*/
|
||||||
|
public function test_update_item_with_existing_inherit_status() {
|
||||||
|
wp_set_current_user( self::$editor_id );
|
||||||
|
$parent_id = self::factory()->post->create( array() );
|
||||||
|
$attachment_id = self::factory()->attachment->create_object(
|
||||||
|
$this->test_file,
|
||||||
|
$parent_id,
|
||||||
|
array(
|
||||||
|
'post_mime_type' => 'image/jpeg',
|
||||||
|
'post_excerpt' => 'A sample caption',
|
||||||
|
'post_author' => self::$editor_id,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$request = new WP_REST_Request( 'POST', '/wp/v2/media/' . $attachment_id );
|
||||||
|
$request->set_param( 'status', 'inherit' );
|
||||||
|
$response = rest_get_server()->dispatch( $request );
|
||||||
|
|
||||||
|
$this->assertNotWPError( $response->as_error() );
|
||||||
|
$this->assertEquals( 'inherit', $response->get_data()['status'] );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ticket 40399
|
||||||
|
*/
|
||||||
|
public function test_update_item_with_new_inherit_status() {
|
||||||
|
wp_set_current_user( self::$editor_id );
|
||||||
|
$attachment_id = self::factory()->attachment->create_object(
|
||||||
|
$this->test_file,
|
||||||
|
0,
|
||||||
|
array(
|
||||||
|
'post_mime_type' => 'image/jpeg',
|
||||||
|
'post_excerpt' => 'A sample caption',
|
||||||
|
'post_author' => self::$editor_id,
|
||||||
|
'post_status' => 'private',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$request = new WP_REST_Request( 'POST', '/wp/v2/media/' . $attachment_id );
|
||||||
|
$request->set_param( 'status', 'inherit' );
|
||||||
|
$response = rest_get_server()->dispatch( $request );
|
||||||
|
|
||||||
|
$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
|
||||||
|
}
|
||||||
|
|
||||||
public function verify_attachment_roundtrip( $input = array(), $expected_output = array() ) {
|
public function verify_attachment_roundtrip( $input = array(), $expected_output = array() ) {
|
||||||
// Create the post.
|
// Create the post.
|
||||||
$request = new WP_REST_Request( 'POST', '/wp/v2/media' );
|
$request = new WP_REST_Request( 'POST', '/wp/v2/media' );
|
||||||
|
Loading…
Reference in New Issue
Block a user