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/meta/registerMeta.php

    r38398 r43510  
    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
     
    7084        $expected = array(
    7185            'post' => array(
    72                 'flight_number' => array(
    73                     'type' => 'string',
    74                     'description' => '',
    75                     'single' => false,
    76                     'sanitize_callback' => null,
    77                     'auth_callback' => '__return_true',
    78                     'show_in_rest' => false,
     86                '' => array(
     87                    'flight_number' => array(
     88                        'type'              => 'string',
     89                        'description'       => '',
     90                        'single'            => false,
     91                        'sanitize_callback' => null,
     92                        'auth_callback'     => '__return_true',
     93                        'show_in_rest'      => false,
     94                    ),
    7995                ),
    8096            ),
    8197        );
    8298
    83         $this->assertEquals( $actual, $expected );
     99        $this->assertEquals( $expected, $actual );
    84100    }
    85101
     
    92108        $expected = array(
    93109            'term' => array(
    94                 'category_icon' => array(
    95                     'type' => 'string',
    96                     'description' => '',
    97                     'single' => false,
    98                     'sanitize_callback' => null,
    99                     'auth_callback' => '__return_true',
    100                     'show_in_rest' => false,
     110                '' => array(
     111                    'category_icon' => array(
     112                        'type'              => 'string',
     113                        'description'       => '',
     114                        'single'            => false,
     115                        'sanitize_callback' => null,
     116                        'auth_callback'     => '__return_true',
     117                        'show_in_rest'      => false,
     118                    ),
    101119                ),
    102120            ),
    103121        );
    104122
    105         $this->assertEquals( $actual, $expected );
     123        $this->assertEquals( $expected, $actual );
    106124    }
    107125
     
    144162        $expected = array(
    145163            'post' => array(
    146                 'flight_number' => array(
    147                     'type' => 'string',
    148                     'description' => '',
    149                     'single' => false,
    150                     'sanitize_callback' => array( $this, '_new_sanitize_meta_cb' ),
    151                     'auth_callback' => '__return_true',
    152                     'show_in_rest' => false,
     164                '' => array(
     165                    'flight_number' => array(
     166                        'type'              => 'string',
     167                        'description'       => '',
     168                        'single'            => false,
     169                        'sanitize_callback' => array( $this, '_new_sanitize_meta_cb' ),
     170                        'auth_callback'     => '__return_true',
     171                        'show_in_rest'      => false,
     172                    ),
    153173                ),
    154174            ),
     
    297317        $this->assertEmpty( $meta );
    298318    }
     319
     320    /**
     321     * @ticket 38323
     322     * @dataProvider data_get_types_and_subtypes
     323     */
     324    public function test_register_meta_with_subtype_populates_wp_meta_keys( $type, $subtype ) {
     325        global $wp_meta_keys;
     326
     327        register_meta( $type, 'flight_number', array( 'object_subtype' => $subtype ) );
     328
     329        $expected = array(
     330            $type => array(
     331                $subtype => array(
     332                    'flight_number' => array(
     333                        'type'              => 'string',
     334                        'description'       => '',
     335                        'single'            => false,
     336                        'sanitize_callback' => null,
     337                        'auth_callback'     => '__return_true',
     338                        'show_in_rest'      => false,
     339                    ),
     340                ),
     341            ),
     342        );
     343
     344        $actual = $wp_meta_keys;
     345
     346        // Reset global so subsequent data tests do not get polluted.
     347        $wp_meta_keys = array();
     348
     349        $this->assertEquals( $expected, $actual );
     350    }
     351
     352    /**
     353     * @ticket 38323
     354     * @dataProvider data_get_types_and_subtypes
     355     */
     356    public function test_unregister_meta_with_subtype_unpopulates_wp_meta_keys( $type, $subtype ) {
     357        global $wp_meta_keys;
     358
     359        register_meta( $type, 'flight_number', array( 'object_subtype' => $subtype ) );
     360        unregister_meta_key( $type, 'flight_number', $subtype );
     361
     362        $actual = $wp_meta_keys;
     363
     364        // Reset global so subsequent data tests do not get polluted.
     365        $wp_meta_keys = array();
     366
     367        $this->assertEmpty( $actual );
     368    }
     369
     370    /**
     371     * @ticket 38323
     372     * @dataProvider data_get_types_and_subtypes
     373     */
     374    public function test_unregister_meta_without_subtype_keeps_subtype_meta_key( $type, $subtype ) {
     375        global $wp_meta_keys;
     376
     377        register_meta( $type, 'flight_number', array( 'object_subtype' => $subtype ) );
     378
     379        // Unregister meta key without subtype.
     380        unregister_meta_key( $type, 'flight_number' );
     381
     382        $expected = array(
     383            $type => array(
     384                $subtype => array(
     385                    'flight_number' => array(
     386                        'type'              => 'string',
     387                        'description'       => '',
     388                        'single'            => false,
     389                        'sanitize_callback' => null,
     390                        'auth_callback'     => '__return_true',
     391                        'show_in_rest'      => false,
     392                    ),
     393                ),
     394            ),
     395        );
     396
     397        $actual = $wp_meta_keys;
     398
     399        // Reset global so subsequent data tests do not get polluted.
     400        $wp_meta_keys = array();
     401
     402        $this->assertEquals( $expected, $actual );
     403    }
     404
     405    /**
     406     * @ticket 38323
     407     * @dataProvider data_get_types_and_subtypes
     408     */
     409    public function test_get_registered_meta_keys_with_subtype( $type, $subtype ) {
     410        register_meta( $type, 'registered_key1', array( 'object_subtype' => $subtype ) );
     411        register_meta( $type, 'registered_key2', array( 'object_subtype' => $subtype ) );
     412
     413        $meta_keys = get_registered_meta_keys( $type, $subtype );
     414
     415        $this->assertArrayHasKey( 'registered_key1', $meta_keys );
     416        $this->assertArrayHasKey( 'registered_key2', $meta_keys );
     417        $this->assertEmpty( get_registered_meta_keys( $type ) );
     418    }
     419
     420    /**
     421     * @ticket 38323
     422     * @dataProvider data_get_types_and_subtypes
     423     */
     424    public function test_get_registered_metadata_with_subtype( $type, $subtype ) {
     425        register_meta( $type, 'registered_key1', array() );
     426
     427        // This will override the above registration for objects of $subtype.
     428        register_meta( $type, 'registered_key1', array(
     429            'object_subtype' => $subtype,
     430            'single'         => true,
     431        ) );
     432
     433        // For testing with $single => false.
     434        register_meta( $type, 'registered_key2', array(
     435            'object_subtype' => $subtype,
     436        ) );
     437
     438        // Register another meta key for a different subtype.
     439        register_meta( $type, 'registered_key3', array(
     440            'object_subtype' => 'other_subtype',
     441        ) );
     442
     443        $object_property_name = $type . '_id';
     444        $object_id = self::$$object_property_name;
     445
     446        add_metadata( $type, $object_id, 'registered_key1', 'value1' );
     447        add_metadata( $type, $object_id, 'registered_key2', 'value2' );
     448        add_metadata( $type, $object_id, 'registered_key3', 'value3' );
     449
     450        $meta = get_registered_metadata( $type, $object_id );
     451
     452        $key1 = get_registered_metadata( $type, $object_id, 'registered_key1' );
     453        $key2 = get_registered_metadata( $type, $object_id, 'registered_key2' );
     454        $key3 = get_registered_metadata( $type, $object_id, 'registered_key3' );
     455
     456        $this->assertSame( array( 'registered_key1', 'registered_key2' ), array_keys( $meta ) );
     457        $this->assertSame( 'value1', $meta['registered_key1'][0] );
     458        $this->assertSame( 'value2', $meta['registered_key2'][0] );
     459
     460        $this->assertSame( 'value1', $key1 );
     461        $this->assertSame( array( 'value2' ), $key2 );
     462        $this->assertFalse( $key3 );
     463    }
     464
     465    /**
     466     * @ticket 38323
     467     * @dataProvider data_get_types_and_subtypes
     468     */
     469    public function test_get_object_subtype( $type, $expected_subtype ) {
     470        $object_property_name = $type . '_id';
     471        $object_id = self::$$object_property_name;
     472
     473        $this->assertSame( $expected_subtype, get_object_subtype( $type, $object_id ) );
     474    }
     475
     476    /**
     477     * @ticket 38323
     478     */
     479    public function test_get_object_subtype_custom() {
     480        add_filter( 'get_object_subtype_customtype', array( $this, 'filter_get_object_subtype_for_customtype' ), 10, 2 );
     481
     482        $subtype_for_3 = get_object_subtype( 'customtype', 3 );
     483        $subtype_for_4 = get_object_subtype( 'customtype', 4 );
     484
     485        $this->assertSame( 'odd', $subtype_for_3 );
     486        $this->assertSame( 'even', $subtype_for_4 );
     487    }
     488
     489    public function filter_get_object_subtype_for_customtype( $subtype, $object_id ) {
     490        if ( $object_id % 2 === 1 ) {
     491            return 'odd';
     492        }
     493
     494        return 'even';
     495    }
     496
     497    public function data_get_types_and_subtypes() {
     498        return array(
     499            array( 'post', 'page' ),
     500            array( 'term', 'category' ),
     501            array( 'comment', 'comment' ),
     502            array( 'user', 'user' ),
     503        );
     504    }
    299505}
Note: See TracChangeset for help on using the changeset viewer.