Make WordPress Core

Changeset 47265


Ignore:
Timestamp:
02/11/2020 04:26:56 PM (7 years 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.