Make WordPress Core


Ignore:
Timestamp:
07/19/2018 06:48:52 PM (6 years ago)
Author:
kadamwhite
Message:

REST API: Support meta registration for specific object subtypes.

Introduce an object_subtype argument to the args array for register_meta() which can be used to limit meta registration to a single subtype (e.g. a custom post type or taxonomy, vs all posts or taxonomies).

Introduce register_post_meta() and register_term_meta() wrapper methods for register_meta to provide a convenient interface for the common case of registering meta for a specific taxonomy or post type. These methods work the way plugin developers have often expected register_meta to function, and should be used in place of direct register_meta where possible.

Props flixos90, tharsheblows, spacedmonkey.

Merges [43378] to the 4.9 branch.
Fixes #38323.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/4.9/tests/phpunit/tests/rest-api/rest-post-meta-fields.php

    r41176 r43510  
    1313    protected static $wp_meta_keys_saved;
    1414    protected static $post_id;
     15    protected static $cpt_post_id;
    1516
    1617    public static function wpSetUpBeforeClass( $factory ) {
     18        register_post_type( 'cpt', array(
     19            'show_in_rest' => true,
     20            'supports'     => array( 'custom-fields' ),
     21        ) );
     22
    1723        self::$wp_meta_keys_saved = $GLOBALS['wp_meta_keys'];
    1824        self::$post_id = $factory->post->create();
     25        self::$cpt_post_id        = $factory->post->create( array( 'post_type' => 'cpt' ) );
    1926    }
    2027
     
    2229        $GLOBALS['wp_meta_keys'] = self::$wp_meta_keys_saved;
    2330        wp_delete_post( self::$post_id, true );
     31        wp_delete_post( self::$cpt_post_id, true );
     32
     33        unregister_post_type( 'cpt' );
    2434    }
    2535
     
    99109        ));
    100110
     111        register_post_type( 'cpt', array(
     112            'show_in_rest' => true,
     113            'supports'     => array( 'custom-fields' ),
     114        ) );
     115
     116        register_post_meta( 'cpt', 'test_cpt_single', array(
     117            'show_in_rest'   => true,
     118            'single'         => true,
     119        ) );
     120
     121        register_post_meta( 'cpt', 'test_cpt_multi', array(
     122            'show_in_rest'   => true,
     123            'single'         => false,
     124        ) );
     125
     126        // Register 'test_single' on subtype to override for bad auth.
     127        register_post_meta( 'cpt', 'test_single', array(
     128            'show_in_rest'   => true,
     129            'single'         => true,
     130            'auth_callback'  => '__return_false',
     131        ) );
     132
    101133        /** @var WP_REST_Server $wp_rest_server */
    102134        global $wp_rest_server;
     
    10111043
    10121044    /**
     1045     * @ticket 38323
     1046     * @dataProvider data_get_subtype_meta_value
     1047     */
     1048    public function test_get_subtype_meta_value( $post_type, $meta_key, $single, $in_post_type ) {
     1049        $post_id  = self::$post_id;
     1050        $endpoint = 'posts';
     1051        if ( 'cpt' === $post_type ) {
     1052            $post_id  = self::$cpt_post_id;
     1053            $endpoint = 'cpt';
     1054        }
     1055
     1056        $meta_value = 'testvalue';
     1057
     1058        add_post_meta( $post_id, $meta_key, $meta_value );
     1059
     1060        $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/%s/%d', $endpoint, $post_id ) );
     1061        $response = rest_get_server()->dispatch( $request );
     1062
     1063        $this->assertEquals( 200, $response->get_status() );
     1064
     1065        $data = $response->get_data();
     1066
     1067        $this->assertArrayHasKey( 'meta', $data );
     1068        $this->assertInternalType( 'array', $data['meta'] );
     1069
     1070        if ( $in_post_type ) {
     1071            $expected_value = $meta_value;
     1072            if ( ! $single ) {
     1073                $expected_value = array( $expected_value );
     1074            }
     1075
     1076            $this->assertArrayHasKey( $meta_key, $data['meta'] );
     1077            $this->assertEquals( $expected_value, $data['meta'][ $meta_key ] );
     1078        } else {
     1079            $this->assertArrayNotHasKey( $meta_key, $data['meta'] );
     1080        }
     1081    }
     1082
     1083    public function data_get_subtype_meta_value() {
     1084        return array(
     1085            array( 'cpt', 'test_cpt_single', true, true ),
     1086            array( 'cpt', 'test_cpt_multi', false, true ),
     1087            array( 'cpt', 'test_single', true, true ),
     1088            array( 'cpt', 'test_multi', false, true ),
     1089            array( 'post', 'test_cpt_single', true, false ),
     1090            array( 'post', 'test_cpt_multi', false, false ),
     1091            array( 'post', 'test_single', true, true ),
     1092            array( 'post', 'test_multi', false, true ),
     1093        );
     1094    }
     1095
     1096    /**
     1097     * @ticket 38323
     1098     * @dataProvider data_set_subtype_meta_value
     1099     */
     1100    public function test_set_subtype_meta_value( $post_type, $meta_key, $single, $in_post_type, $can_write ) {
     1101        $post_id  = self::$post_id;
     1102        $endpoint = 'posts';
     1103        if ( 'cpt' === $post_type ) {
     1104            $post_id  = self::$cpt_post_id;
     1105            $endpoint = 'cpt';
     1106        }
     1107
     1108        $meta_value = 'value_to_set';
     1109
     1110        $this->grant_write_permission();
     1111
     1112        $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/%s/%d', $endpoint, $post_id ) );
     1113        $request->set_body_params( array(
     1114            'meta' => array(
     1115                $meta_key => $meta_value,
     1116            ),
     1117        ) );
     1118
     1119        $response = rest_get_server()->dispatch( $request );
     1120        if ( ! $can_write ) {
     1121            $this->assertEquals( 403, $response->get_status() );
     1122            $this->assertEmpty( get_post_meta( $post_id, $meta_key, $single ) );
     1123            return;
     1124        }
     1125
     1126        $this->assertEquals( 200, $response->get_status() );
     1127
     1128        $data = $response->get_data();
     1129        $this->assertArrayHasKey( 'meta', $data );
     1130        $this->assertInternalType( 'array', $data['meta'] );
     1131
     1132        if ( $in_post_type ) {
     1133            $expected_value = $meta_value;
     1134            if ( ! $single ) {
     1135                $expected_value = array( $expected_value );
     1136            }
     1137
     1138            $this->assertEquals( $expected_value, get_post_meta( $post_id, $meta_key, $single ) );
     1139            $this->assertArrayHasKey( $meta_key, $data['meta'] );
     1140            $this->assertEquals( $expected_value, $data['meta'][ $meta_key ] );
     1141        } else {
     1142            $this->assertEmpty( get_post_meta( $post_id, $meta_key, $single ) );
     1143            $this->assertArrayNotHasKey( $meta_key, $data['meta'] );
     1144        }
     1145    }
     1146
     1147    public function data_set_subtype_meta_value() {
     1148        $data = $this->data_get_subtype_meta_value();
     1149
     1150        foreach ( $data as $index => $dataset ) {
     1151            $can_write = true;
     1152
     1153            // This combination is not writable because of an auth callback of '__return_false'.
     1154            if ( 'cpt' === $dataset[0] && 'test_single' === $dataset[1] ) {
     1155                $can_write = false;
     1156            }
     1157
     1158            $data[ $index ][] = $can_write;
     1159        }
     1160
     1161        return $data;
     1162    }
     1163
     1164    /**
    10131165     * Internal function used to disable an insert query which
    10141166     * will trigger a wpdb error for testing purposes.
Note: See TracChangeset for help on using the changeset viewer.