Make WordPress Core

Changeset 49302


Ignore:
Timestamp:
10/24/2020 04:02:34 PM (6 years ago)
Author:
TimothyBlynJacobs
Message:

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.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php

    r49301 r49302  
    10531053         */
    10541054        protected function prepare_item_for_database( $request ) {
    1055                 $prepared_post = new stdClass();
     1055                $prepared_post  = new stdClass();
     1056                $current_status = '';
    10561057
    10571058                // Post ID.
     
    10631064
    10641065                        $prepared_post->ID = $existing_post->ID;
     1066                        $current_status    = $existing_post->post_status;
    10651067                }
    10661068
     
    11061108
    11071109                // Post status.
    1108                 if ( ! empty( $schema['properties']['status'] ) && isset( $request['status'] ) ) {
     1110                if (
     1111                        ! empty( $schema['properties']['status'] ) &&
     1112                        isset( $request['status'] ) &&
     1113                        ( ! $current_status || $current_status !== $request['status'] )
     1114                ) {
    11091115                        $status = $this->handle_status_param( $request['status'], $post_type );
    11101116
     
    12541260                return apply_filters( "rest_pre_insert_{$this->post_type}", $prepared_post, $request );
    12551261
     1262        }
     1263
     1264        /**
     1265         * Checks whether the status is valid for the given post.
     1266         *
     1267         * Allows for sending an update request with the current status, even if that status would not be acceptable.
     1268         *
     1269         * @since 5.6.0
     1270         *
     1271         * @param string          $status  The provided status.
     1272         * @param WP_REST_Request $request The request object.
     1273         * @param string          $param   The parameter name.
     1274         * @return true|WP_Error True if the status is valid, or WP_Error if not.
     1275         */
     1276        public function check_status( $status, $request, $param ) {
     1277                if ( $request['id'] ) {
     1278                        $post = $this->get_post( $request['id'] );
     1279
     1280                        if ( ! is_wp_error( $post ) && $post->post_status === $status ) {
     1281                                return true;
     1282                        }
     1283                }
     1284
     1285                $args = $request->get_attributes()['args'][ $param ];
     1286
     1287                return rest_validate_value_from_schema( $status, $args, $param );
    12561288        }
    12571289
     
    21162148                                        'enum'        => array_keys( get_post_stati( array( 'internal' => false ) ) ),
    21172149                                        'context'     => array( 'view', 'edit' ),
     2150                                        'arg_options' => array(
     2151                                                'validate_callback' => array( $this, 'check_status' ),
     2152                                        ),
    21182153                                ),
    21192154                                'type'         => array(
  • trunk/tests/phpunit/tests/rest-api/rest-attachments-controller.php

    r49215 r49302  
    10051005                $request->set_param( 'post', $attachment_id );
    10061006                $response = rest_get_server()->dispatch( $request );
     1007                $this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
     1008        }
     1009
     1010        /**
     1011         * @ticket 40399
     1012         */
     1013        public function test_update_item_with_existing_inherit_status() {
     1014                wp_set_current_user( self::$editor_id );
     1015                $parent_id     = self::factory()->post->create( array() );
     1016                $attachment_id = self::factory()->attachment->create_object(
     1017                        $this->test_file,
     1018                        $parent_id,
     1019                        array(
     1020                                'post_mime_type' => 'image/jpeg',
     1021                                'post_excerpt'   => 'A sample caption',
     1022                                'post_author'    => self::$editor_id,
     1023                        )
     1024                );
     1025
     1026                $request = new WP_REST_Request( 'POST', '/wp/v2/media/' . $attachment_id );
     1027                $request->set_param( 'status', 'inherit' );
     1028                $response = rest_get_server()->dispatch( $request );
     1029
     1030                $this->assertNotWPError( $response->as_error() );
     1031                $this->assertEquals( 'inherit', $response->get_data()['status'] );
     1032        }
     1033
     1034        /**
     1035         * @ticket 40399
     1036         */
     1037        public function test_update_item_with_new_inherit_status() {
     1038                wp_set_current_user( self::$editor_id );
     1039                $attachment_id = self::factory()->attachment->create_object(
     1040                        $this->test_file,
     1041                        0,
     1042                        array(
     1043                                'post_mime_type' => 'image/jpeg',
     1044                                'post_excerpt'   => 'A sample caption',
     1045                                'post_author'    => self::$editor_id,
     1046                                'post_status'    => 'private',
     1047                        )
     1048                );
     1049
     1050                $request = new WP_REST_Request( 'POST', '/wp/v2/media/' . $attachment_id );
     1051                $request->set_param( 'status', 'inherit' );
     1052                $response = rest_get_server()->dispatch( $request );
     1053
    10071054                $this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
    10081055        }
Note: See TracChangeset for help on using the changeset viewer.