WordPress.org

Make WordPress Core

Changeset 47265


Ignore:
Timestamp:
02/11/2020 04:26:56 PM (4 months ago)
Author:
kadamwhite
Message:

REST API: Introduce rest_{$this->post_type}_item_schema filter to enable manipulation of schema values.

register_rest_field can be used to add properties to a schema, but no mechanism existed to alter existing properties like "content".
Running the schema through this filter lets plugins append additional sub-properties to existing schema definitions.

Props luisherranz, TimothyBlynJacobs, swissspidy, westonruter, kadamwhite.
Fixes #47779.

Location:
trunk
Files:
2 edited

Legend:

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

    r47233 r47265  
    24072407        }
    24082408
     2409        // Take a snapshot of which fields are in the schema pre-filtering.
     2410        $schema_fields = array_keys( $schema['properties'] );
     2411
     2412        /**
     2413         * Filter the post's schema.
     2414         *
     2415         * The dynamic portion of the filter, `$this->post_type`, refers to the
     2416         * post type slug for the controller.
     2417         *
     2418         * @since 5.4.0
     2419         *
     2420         * @param array $schema Item schema data.
     2421         */
     2422        $schema = apply_filters( "rest_{$this->post_type}_item_schema", $schema );
     2423
     2424        // Emit a _doing_it_wrong warning if user tries to add new properties using this filter.
     2425        $new_fields = array_diff( array_keys( $schema['properties'] ), $schema_fields );
     2426        if ( count( $new_fields ) > 0 ) {
     2427            _doing_it_wrong( __METHOD__, __( 'Please use register_rest_field to add new schema properties.' ), '5.4.0' );
     2428        }
     2429
    24092430        $this->schema = $schema;
    24102431
  • trunk/tests/phpunit/tests/rest-api/rest-posts-controller.php

    r47122 r47265  
    48424842    }
    48434843
     4844    /**
     4845     * @ticket 47779
     4846     */
     4847    public function test_rest_post_type_item_schema_filter_change_property() {
     4848        add_filter( 'rest_post_item_schema', array( $this, 'filter_post_item_schema' ) );
     4849
     4850        // Re-initialize the controller to cache-bust schemas from prior test runs.
     4851        $GLOBALS['wp_rest_server']->override_by_default = true;
     4852        $controller                                     = new WP_REST_Posts_Controller( 'post' );
     4853        $controller->register_routes();
     4854        $GLOBALS['wp_rest_server']->override_by_default = false;
     4855
     4856        $request    = new WP_REST_Request( 'OPTIONS', '/wp/v2/posts' );
     4857        $response   = rest_get_server()->dispatch( $request );
     4858        $data       = $response->get_data();
     4859        $properties = $data['schema']['properties']['content']['properties'];
     4860
     4861        $this->assertArrayHasKey( 'new_prop', $properties );
     4862        $this->assertEquals( array( 'new_context' ), $properties['new_prop']['context'] );
     4863    }
     4864
     4865    /**
     4866     * @ticket 47779
     4867     */
     4868    public function test_rest_post_type_item_schema_filter_add_property_triggers_doing_it_wrong() {
     4869        add_filter( 'rest_post_item_schema', array( $this, 'filter_post_item_schema_add_property' ) );
     4870        $this->setExpectedIncorrectUsage( 'WP_REST_Posts_Controller::get_item_schema' );
     4871
     4872        // Re-initialize the controller to cache-bust schemas from prior test runs.
     4873        $GLOBALS['wp_rest_server']->override_by_default = true;
     4874        $controller                                     = new WP_REST_Posts_Controller( 'post' );
     4875        $controller->register_routes();
     4876        $GLOBALS['wp_rest_server']->override_by_default = false;
     4877    }
     4878
    48444879    public function tearDown() {
    48454880        _unregister_post_type( 'private-post' );
     
    48694904        );
    48704905    }
     4906
     4907    public function filter_post_item_schema( $schema ) {
     4908        $schema['properties']['content']['properties']['new_prop'] = array(
     4909            'description' => __( 'A new prop added with a the rest_post_item_schema filter.' ),
     4910            'type'        => 'string',
     4911            'context'     => array( 'new_context' ),
     4912        );
     4913        return $schema;
     4914    }
     4915
     4916    public function filter_post_item_schema_add_property( $schema ) {
     4917        $schema['properties']['something_entirely_new'] = array(
     4918            'description' => __( 'A new prop added with a the rest_post_item_schema filter.' ),
     4919            'type'        => 'string',
     4920            'context'     => array( 'new_context' ),
     4921        );
     4922        return $schema;
     4923    }
    48714924}
Note: See TracChangeset for help on using the changeset viewer.