Make WordPress Core


Ignore:
Timestamp:
06/21/2018 09:06:50 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.
Fixes #38323.

File:
1 edited

Legend:

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

    r43340 r43378  
    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 = isset( $GLOBALS['wp_meta_keys'] ) ? $GLOBALS['wp_meta_keys'] : array();
    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
     
    121131        );
    122132
     133        register_post_type( 'cpt', array(
     134            'show_in_rest' => true,
     135            'supports'     => array( 'custom-fields' ),
     136        ) );
     137
     138        register_post_meta( 'cpt', 'test_cpt_single', array(
     139            'show_in_rest'   => true,
     140            'single'         => true,
     141        ) );
     142
     143        register_post_meta( 'cpt', 'test_cpt_multi', array(
     144            'show_in_rest'   => true,
     145            'single'         => false,
     146        ) );
     147
     148        // Register 'test_single' on subtype to override for bad auth.
     149        register_post_meta( 'cpt', 'test_single', array(
     150            'show_in_rest'   => true,
     151            'single'         => true,
     152            'auth_callback'  => '__return_false',
     153        ) );
     154
    123155        /** @var WP_REST_Server $wp_rest_server */
    124156        global $wp_rest_server;
     
    10491081
    10501082    /**
     1083     * @ticket 38323
     1084     * @dataProvider data_get_subtype_meta_value
     1085     */
     1086    public function test_get_subtype_meta_value( $post_type, $meta_key, $single, $in_post_type ) {
     1087        $post_id  = self::$post_id;
     1088        $endpoint = 'posts';
     1089        if ( 'cpt' === $post_type ) {
     1090            $post_id  = self::$cpt_post_id;
     1091            $endpoint = 'cpt';
     1092        }
     1093
     1094        $meta_value = 'testvalue';
     1095
     1096        add_post_meta( $post_id, $meta_key, $meta_value );
     1097
     1098        $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/%s/%d', $endpoint, $post_id ) );
     1099        $response = rest_get_server()->dispatch( $request );
     1100
     1101        $this->assertEquals( 200, $response->get_status() );
     1102
     1103        $data = $response->get_data();
     1104
     1105        $this->assertArrayHasKey( 'meta', $data );
     1106        $this->assertInternalType( 'array', $data['meta'] );
     1107
     1108        if ( $in_post_type ) {
     1109            $expected_value = $meta_value;
     1110            if ( ! $single ) {
     1111                $expected_value = array( $expected_value );
     1112            }
     1113
     1114            $this->assertArrayHasKey( $meta_key, $data['meta'] );
     1115            $this->assertEquals( $expected_value, $data['meta'][ $meta_key ] );
     1116        } else {
     1117            $this->assertArrayNotHasKey( $meta_key, $data['meta'] );
     1118        }
     1119    }
     1120
     1121    public function data_get_subtype_meta_value() {
     1122        return array(
     1123            array( 'cpt', 'test_cpt_single', true, true ),
     1124            array( 'cpt', 'test_cpt_multi', false, true ),
     1125            array( 'cpt', 'test_single', true, true ),
     1126            array( 'cpt', 'test_multi', false, true ),
     1127            array( 'post', 'test_cpt_single', true, false ),
     1128            array( 'post', 'test_cpt_multi', false, false ),
     1129            array( 'post', 'test_single', true, true ),
     1130            array( 'post', 'test_multi', false, true ),
     1131        );
     1132    }
     1133
     1134    /**
     1135     * @ticket 38323
     1136     * @dataProvider data_set_subtype_meta_value
     1137     */
     1138    public function test_set_subtype_meta_value( $post_type, $meta_key, $single, $in_post_type, $can_write ) {
     1139        $post_id  = self::$post_id;
     1140        $endpoint = 'posts';
     1141        if ( 'cpt' === $post_type ) {
     1142            $post_id  = self::$cpt_post_id;
     1143            $endpoint = 'cpt';
     1144        }
     1145
     1146        $meta_value = 'value_to_set';
     1147
     1148        $this->grant_write_permission();
     1149
     1150        $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/%s/%d', $endpoint, $post_id ) );
     1151        $request->set_body_params( array(
     1152            'meta' => array(
     1153                $meta_key => $meta_value,
     1154            ),
     1155        ) );
     1156
     1157        $response = rest_get_server()->dispatch( $request );
     1158        if ( ! $can_write ) {
     1159            $this->assertEquals( 403, $response->get_status() );
     1160            $this->assertEmpty( get_post_meta( $post_id, $meta_key, $single ) );
     1161            return;
     1162        }
     1163
     1164        $this->assertEquals( 200, $response->get_status() );
     1165
     1166        $data = $response->get_data();
     1167        $this->assertArrayHasKey( 'meta', $data );
     1168        $this->assertInternalType( 'array', $data['meta'] );
     1169
     1170        if ( $in_post_type ) {
     1171            $expected_value = $meta_value;
     1172            if ( ! $single ) {
     1173                $expected_value = array( $expected_value );
     1174            }
     1175
     1176            $this->assertEquals( $expected_value, get_post_meta( $post_id, $meta_key, $single ) );
     1177            $this->assertArrayHasKey( $meta_key, $data['meta'] );
     1178            $this->assertEquals( $expected_value, $data['meta'][ $meta_key ] );
     1179        } else {
     1180            $this->assertEmpty( get_post_meta( $post_id, $meta_key, $single ) );
     1181            $this->assertArrayNotHasKey( $meta_key, $data['meta'] );
     1182        }
     1183    }
     1184
     1185    public function data_set_subtype_meta_value() {
     1186        $data = $this->data_get_subtype_meta_value();
     1187
     1188        foreach ( $data as $index => $dataset ) {
     1189            $can_write = true;
     1190
     1191            // This combination is not writable because of an auth callback of '__return_false'.
     1192            if ( 'cpt' === $dataset[0] && 'test_single' === $dataset[1] ) {
     1193                $can_write = false;
     1194            }
     1195
     1196            $data[ $index ][] = $can_write;
     1197        }
     1198
     1199        return $data;
     1200    }
     1201
     1202    /**
    10511203     * Internal function used to disable an insert query which
    10521204     * will trigger a wpdb error for testing purposes.
Note: See TracChangeset for help on using the changeset viewer.