Make WordPress Core


Ignore:
Timestamp:
06/21/2018 09:06:50 PM (7 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/meta/registerMeta.php

    r42343 r43378  
    44 */
    55class Tests_Meta_Register_Meta extends WP_UnitTestCase {
     6
    67    protected static $post_id;
     8    protected static $term_id;
     9    protected static $comment_id;
     10    protected static $user_id;
    711
    812    public static function wpSetUpBeforeClass( $factory ) {
    9         self::$post_id = $factory->post->create();
     13        self::$post_id    = $factory->post->create( array( 'post_type' => 'page' ) );
     14        self::$term_id    = $factory->term->create( array( 'taxonomy' => 'category' ) );
     15        self::$comment_id = $factory->comment->create();
     16        self::$user_id    = $factory->user->create();
     17    }
     18
     19    public static function wpTearDownAfterClass() {
     20        wp_delete_post( self::$post_id, true );
     21        wp_delete_term( self::$term_id, 'category' );
     22        wp_delete_comment( self::$comment_id, true );
     23        self::delete_user( self::$user_id );
    1024    }
    1125
     
    7589        $expected = array(
    7690            'post' => array(
    77                 'flight_number' => array(
    78                     'type'              => 'string',
    79                     'description'       => '',
    80                     'single'            => false,
    81                     'sanitize_callback' => null,
    82                     'auth_callback'     => '__return_true',
    83                     'show_in_rest'      => false,
     91                '' => array(
     92                    'flight_number' => array(
     93                        'type'              => 'string',
     94                        'description'       => '',
     95                        'single'            => false,
     96                        'sanitize_callback' => null,
     97                        'auth_callback'     => '__return_true',
     98                        'show_in_rest'      => false,
     99                    ),
    84100                ),
    85101            ),
    86102        );
    87103
    88         $this->assertEquals( $actual, $expected );
     104        $this->assertEquals( $expected, $actual );
    89105    }
    90106
     
    97113        $expected = array(
    98114            'term' => array(
    99                 'category_icon' => array(
    100                     'type'              => 'string',
    101                     'description'       => '',
    102                     'single'            => false,
    103                     'sanitize_callback' => null,
    104                     'auth_callback'     => '__return_true',
    105                     'show_in_rest'      => false,
     115                '' => array(
     116                    'category_icon' => array(
     117                        'type'              => 'string',
     118                        'description'       => '',
     119                        'single'            => false,
     120                        'sanitize_callback' => null,
     121                        'auth_callback'     => '__return_true',
     122                        'show_in_rest'      => false,
     123                    ),
    106124                ),
    107125            ),
    108126        );
    109127
    110         $this->assertEquals( $actual, $expected );
     128        $this->assertEquals( $expected, $actual );
    111129    }
    112130
     
    149167        $expected = array(
    150168            'post' => array(
    151                 'flight_number' => array(
    152                     'type'              => 'string',
    153                     'description'       => '',
    154                     'single'            => false,
    155                     'sanitize_callback' => array( $this, '_new_sanitize_meta_cb' ),
    156                     'auth_callback'     => '__return_true',
    157                     'show_in_rest'      => false,
     169                '' => array(
     170                    'flight_number' => array(
     171                        'type'              => 'string',
     172                        'description'       => '',
     173                        'single'            => false,
     174                        'sanitize_callback' => array( $this, '_new_sanitize_meta_cb' ),
     175                        'auth_callback'     => '__return_true',
     176                        'show_in_rest'      => false,
     177                    ),
    158178                ),
    159179            ),
     
    302322        $this->assertEmpty( $meta );
    303323    }
     324
     325    /**
     326     * @ticket 38323
     327     * @dataProvider data_get_types_and_subtypes
     328     */
     329    public function test_register_meta_with_subtype_populates_wp_meta_keys( $type, $subtype ) {
     330        global $wp_meta_keys;
     331
     332        register_meta( $type, 'flight_number', array( 'object_subtype' => $subtype ) );
     333
     334        $expected = array(
     335            $type => array(
     336                $subtype => array(
     337                    'flight_number' => array(
     338                        'type'              => 'string',
     339                        'description'       => '',
     340                        'single'            => false,
     341                        'sanitize_callback' => null,
     342                        'auth_callback'     => '__return_true',
     343                        'show_in_rest'      => false,
     344                    ),
     345                ),
     346            ),
     347        );
     348
     349        $actual = $wp_meta_keys;
     350
     351        // Reset global so subsequent data tests do not get polluted.
     352        $wp_meta_keys = array();
     353
     354        $this->assertEquals( $expected, $actual );
     355    }
     356
     357    /**
     358     * @ticket 38323
     359     * @dataProvider data_get_types_and_subtypes
     360     */
     361    public function test_unregister_meta_with_subtype_unpopulates_wp_meta_keys( $type, $subtype ) {
     362        global $wp_meta_keys;
     363
     364        register_meta( $type, 'flight_number', array( 'object_subtype' => $subtype ) );
     365        unregister_meta_key( $type, 'flight_number', $subtype );
     366
     367        $actual = $wp_meta_keys;
     368
     369        // Reset global so subsequent data tests do not get polluted.
     370        $wp_meta_keys = array();
     371
     372        $this->assertEmpty( $actual );
     373    }
     374
     375    /**
     376     * @ticket 38323
     377     * @dataProvider data_get_types_and_subtypes
     378     */
     379    public function test_unregister_meta_without_subtype_keeps_subtype_meta_key( $type, $subtype ) {
     380        global $wp_meta_keys;
     381
     382        register_meta( $type, 'flight_number', array( 'object_subtype' => $subtype ) );
     383
     384        // Unregister meta key without subtype.
     385        unregister_meta_key( $type, 'flight_number' );
     386
     387        $expected = array(
     388            $type => array(
     389                $subtype => array(
     390                    'flight_number' => array(
     391                        'type'              => 'string',
     392                        'description'       => '',
     393                        'single'            => false,
     394                        'sanitize_callback' => null,
     395                        'auth_callback'     => '__return_true',
     396                        'show_in_rest'      => false,
     397                    ),
     398                ),
     399            ),
     400        );
     401
     402        $actual = $wp_meta_keys;
     403
     404        // Reset global so subsequent data tests do not get polluted.
     405        $wp_meta_keys = array();
     406
     407        $this->assertEquals( $expected, $actual );
     408    }
     409
     410    /**
     411     * @ticket 38323
     412     * @dataProvider data_get_types_and_subtypes
     413     */
     414    public function test_get_registered_meta_keys_with_subtype( $type, $subtype ) {
     415        register_meta( $type, 'registered_key1', array( 'object_subtype' => $subtype ) );
     416        register_meta( $type, 'registered_key2', array( 'object_subtype' => $subtype ) );
     417
     418        $meta_keys = get_registered_meta_keys( $type, $subtype );
     419
     420        $this->assertArrayHasKey( 'registered_key1', $meta_keys );
     421        $this->assertArrayHasKey( 'registered_key2', $meta_keys );
     422        $this->assertEmpty( get_registered_meta_keys( $type ) );
     423    }
     424
     425    /**
     426     * @ticket 38323
     427     * @dataProvider data_get_types_and_subtypes
     428     */
     429    public function test_get_registered_metadata_with_subtype( $type, $subtype ) {
     430        register_meta( $type, 'registered_key1', array() );
     431
     432        // This will override the above registration for objects of $subtype.
     433        register_meta( $type, 'registered_key1', array(
     434            'object_subtype' => $subtype,
     435            'single'         => true,
     436        ) );
     437
     438        // For testing with $single => false.
     439        register_meta( $type, 'registered_key2', array(
     440            'object_subtype' => $subtype,
     441        ) );
     442
     443        // Register another meta key for a different subtype.
     444        register_meta( $type, 'registered_key3', array(
     445            'object_subtype' => 'other_subtype',
     446        ) );
     447
     448        $object_property_name = $type . '_id';
     449        $object_id = self::$$object_property_name;
     450
     451        add_metadata( $type, $object_id, 'registered_key1', 'value1' );
     452        add_metadata( $type, $object_id, 'registered_key2', 'value2' );
     453        add_metadata( $type, $object_id, 'registered_key3', 'value3' );
     454
     455        $meta = get_registered_metadata( $type, $object_id );
     456
     457        $key1 = get_registered_metadata( $type, $object_id, 'registered_key1' );
     458        $key2 = get_registered_metadata( $type, $object_id, 'registered_key2' );
     459        $key3 = get_registered_metadata( $type, $object_id, 'registered_key3' );
     460
     461        $this->assertSame( array( 'registered_key1', 'registered_key2' ), array_keys( $meta ) );
     462        $this->assertSame( 'value1', $meta['registered_key1'][0] );
     463        $this->assertSame( 'value2', $meta['registered_key2'][0] );
     464
     465        $this->assertSame( 'value1', $key1 );
     466        $this->assertSame( array( 'value2' ), $key2 );
     467        $this->assertFalse( $key3 );
     468    }
     469
     470    /**
     471     * @ticket 38323
     472     * @dataProvider data_get_types_and_subtypes
     473     */
     474    public function test_get_object_subtype( $type, $expected_subtype ) {
     475        $object_property_name = $type . '_id';
     476        $object_id = self::$$object_property_name;
     477
     478        $this->assertSame( $expected_subtype, get_object_subtype( $type, $object_id ) );
     479    }
     480
     481    /**
     482     * @ticket 38323
     483     */
     484    public function test_get_object_subtype_custom() {
     485        add_filter( 'get_object_subtype_customtype', array( $this, 'filter_get_object_subtype_for_customtype' ), 10, 2 );
     486
     487        $subtype_for_3 = get_object_subtype( 'customtype', 3 );
     488        $subtype_for_4 = get_object_subtype( 'customtype', 4 );
     489
     490        $this->assertSame( 'odd', $subtype_for_3 );
     491        $this->assertSame( 'even', $subtype_for_4 );
     492    }
     493
     494    public function filter_get_object_subtype_for_customtype( $subtype, $object_id ) {
     495        if ( $object_id % 2 === 1 ) {
     496            return 'odd';
     497        }
     498
     499        return 'even';
     500    }
     501
     502    public function data_get_types_and_subtypes() {
     503        return array(
     504            array( 'post', 'page' ),
     505            array( 'term', 'category' ),
     506            array( 'comment', 'comment' ),
     507            array( 'user', 'user' ),
     508        );
     509    }
    304510}
Note: See TracChangeset for help on using the changeset viewer.