Make WordPress Core

Ticket #35658: 35658.29.diff

File 35658.29.diff, 19.1 KB (added by jeremyfelt, 8 years ago)
  • src/wp-includes/meta.php

     
    10751075                }
    10761076        }
    10771077
     1078        $object_subtype = '';
     1079
     1080        if ( ! empty( $args['object_subtype'] ) ) {
     1081                $object_subtype = $args['object_subtype'];
     1082        }
     1083
    10781084        // Back-compat: old sanitize and auth callbacks applied to all of an object type
    10791085        if ( $has_old_sanitize_cb ) {
    1080                 add_filter( "sanitize_{$object_type}_meta_{$meta_key}", $args['sanitize_callback'], 10, 4 );
    1081                 add_filter( "auth_{$object_type}_meta_{$meta_key}", $args['auth_callback'], 10, 6 );
     1086                                add_filter( "sanitize_{$object_type}_meta_{$meta_key}", $args['sanitize_callback'], 10, 4 );
     1087                                add_filter( "auth_{$object_type}_meta_{$meta_key}", $args['auth_callback'], 10, 6 );
    10821088        } else {
     1089                // Back-compat: old sanitize and auth callbacks applied to all of an object type
    10831090                if ( is_callable( $args['sanitize_callback'] ) ) {
    1084                         add_filter( "sanitize_{$object_type}_{$object_subtype}_meta_{$meta_key}", $args['sanitize_callback'], 10, 4 );
     1091                        if ( empty( $object_subtype ) || $has_old_sanitize_cb ) {
     1092                                add_filter( "sanitize_{$object_type}_meta_{$meta_key}", $args['sanitize_callback'], 10, 4 );
     1093                        } else {
     1094                                add_filter( "sanitize_{$object_type}_{$object_subtype}_meta_{$meta_key}", $args['sanitize_callback'], 10, 4 );
     1095                        }
    10851096                }
    10861097
    10871098                if ( is_callable( $args['auth_callback'] ) ) {
    1088                         add_filter( "auth_{$object_type}_{$object_subtype}_meta_{$meta_key}", $args['auth_callback'], 10, 6 );
     1099                        if ( empty( $object_subtype ) || $has_old_sanitize_cb ) {
     1100                                add_filter( "auth_{$object_type}_meta_{$meta_key}", $args['auth_callback'], 10, 6 );
     1101                        } else {
     1102                                add_filter( "auth_{$object_type}_{$object_subtype}_meta_{$meta_key}", $args['auth_callback'], 10, 6 );
     1103                        }
    10891104                }
    10901105        }
    10911106
    10921107        // Global registry only contains meta keys registered in the new way with a subtype.
    1093         if ( ! empty( $args['object_subtype'] ) ) {
    1094                 $object_subtype = $args['object_subtype'];
     1108        if ( ! empty( $object_subtype ) ) {
    10951109                $wp_meta_keys[ $object_type ][ $object_subtype ][ $meta_key ] = $args;
    10961110
    10971111                return true;
     
    12341248                return $data;
    12351249        }
    12361250
    1237         $data = get_metadata( $object_type, $object_id, $meta_key );
     1251        $data = get_metadata( $object_type, $object_id );
    12381252
    12391253        $meta_keys = get_registered_meta_keys( $object_type, $object_subtype );
    12401254        $registered_data = array();
  • tests/phpunit/tests/meta/registerMeta.php

     
     1<?php
     2/**
     3 * @group meta
     4 */
     5class Tests_Meta_Register_Meta extends WP_UnitTestCase {
     6        protected static $editor_id;
     7        protected static $post_id;
     8        protected static $comment_id;
     9
     10        public static function wpSetUpBeforeClass( $factory ) {
     11                self::$editor_id = $factory->user->create( array( 'role' => 'editor' ) );
     12                self::$post_id = $factory->post->create();
     13                self::$comment_id = $factory->comment->create( array( 'comment_post_ID' => self::$post_id ) );
     14        }
     15
     16        public static function wpTearDownAfterClass() {
     17                self::delete_user( self::$editor_id );
     18                wp_delete_comment( self::$comment_id, true );
     19                wp_delete_post( self::$post_id, true );
     20        }
     21
     22        function setUp() {
     23                parent::setUp();
     24                wp_set_current_user( self::$editor_id );
     25
     26        }
     27
     28        public function _old_sanitize_meta_cb( $meta_value, $meta_key, $meta_type ) {
     29                return $meta_key . ' old sanitized';
     30        }
     31
     32        public function _new_sanitize_meta_cb( $meta_value, $meta_key, $object_type, $object_subtype ) {
     33                return $meta_key . ' new sanitized';
     34        }
     35
     36        public function test_register_meta_with_valid_object_type_and_object_subtype_returns_true() {
     37                $result = register_meta( 'post', 'flight_number', array( 'object_subtype' => 'post' ) );
     38                unregister_meta_key( 'post', 'post', 'flight_number' );
     39
     40                $this->assertTrue( $result );
     41        }
     42
     43        // @todo remove object_subtype from the meta key's array?
     44        public function test_register_meta_with_post_object_type_and_subtype_populates_wp_meta_keys() {
     45                global $wp_meta_keys;
     46
     47                register_meta( 'post', 'flight_number', array( 'object_subtype' => 'post' ) );
     48                $actual = $wp_meta_keys;
     49                unregister_meta_key( 'post', 'post', 'flight_number' );
     50
     51                $expected = array(
     52                        'post' => array(
     53                                'post' => array(
     54                                        'flight_number' => array(
     55                                                'object_subtype' => 'post',
     56                                                'type' => 'string',
     57                                                'description' => '',
     58                                                'single' => false,
     59                                                'sanitize_callback' => null,
     60                                                'auth_callback' => '__return_true',
     61                                                'show_in_rest' => false,
     62                                        ),
     63                                ),
     64                        ),
     65                );
     66
     67                $this->assertEquals( $actual, $expected );
     68        }
     69
     70        public function test_register_meta_with_post_object_type_and_unregistered_subtype_populates_wp_meta_keys() {
     71                global $wp_meta_keys;
     72
     73                register_meta( 'post', 'flight_number', array( 'object_subtype' => 'not_a_post_type' ) );
     74                $actual = $wp_meta_keys;
     75                unregister_meta_key( 'post', 'not_a_post_type', 'flight_number' );
     76
     77                $expected = array(
     78                        'post' => array(
     79                                'not_a_post_type' => array(
     80                                        'flight_number' => array(
     81                                                'object_subtype' => 'not_a_post_type',
     82                                                'type' => 'string',
     83                                                'description' => '',
     84                                                'single' => false,
     85                                                'sanitize_callback' => null,
     86                                                'auth_callback' => '__return_true',
     87                                                'show_in_rest' => false,
     88                                        ),
     89                                ),
     90                        ),
     91                );
     92
     93                $this->assertEquals( $actual, $expected );
     94        }
     95
     96        // @todo remove object_subtype from the meta key's array?
     97        public function test_register_meta_with_term_object_type_and_category_subtype_populates_wp_meta_keys() {
     98                global $wp_meta_keys;
     99                register_meta( 'term', 'category_icon', array( 'object_subtype' => 'category' ) );
     100                $actual = $wp_meta_keys;
     101                unregister_meta_key( 'term', 'category', 'category_icon' );
     102
     103                $expected = array(
     104                        'term' => array(
     105                                'category' => array(
     106                                        'category_icon' => array(
     107                                                'object_subtype' => 'category',
     108                                                'type' => 'string',
     109                                                'description' => '',
     110                                                'single' => false,
     111                                                'sanitize_callback' => null,
     112                                                'auth_callback' => '__return_true',
     113                                                'show_in_rest' => false,
     114                                        ),
     115                                ),
     116                        ),
     117                );
     118
     119                $this->assertEquals( $actual, $expected );
     120        }
     121
     122        public function test_register_meta_with_comment_object_type_and_subtype_populates_wp_meta_keys() {
     123                global $wp_meta_keys;
     124                register_meta( 'comment', 'comment_rating', array( 'object_subtype' => 'comment' ) );
     125                $actual = $wp_meta_keys;
     126                unregister_meta_key( 'comment', 'comment', 'comment_rating' );
     127
     128                $expected = array(
     129                        'comment' => array(
     130                                'comment' => array(
     131                                        'comment_rating' => array(
     132                                                'object_subtype' => 'comment',
     133                                                'type' => 'string',
     134                                                'description' => '',
     135                                                'single' => false,
     136                                                'sanitize_callback' => null,
     137                                                'auth_callback' => '__return_true',
     138                                                'show_in_rest' => false,
     139                                        ),
     140                                ),
     141                        ),
     142                );
     143
     144                $this->assertEquals( $actual, $expected );
     145        }
     146
     147        public function test_register_meta_with_deprecated_sanitize_callback_does_not_populate_wp_meta_keys() {
     148                global $wp_meta_keys;
     149
     150                register_meta( 'post', 'flight_number', array( $this, '_old_sanitize_meta_cb' ) );
     151                $actual = $wp_meta_keys;
     152                remove_filter( 'sanitize_post_meta_flight_number', array( $this, '_old_sanitize_meta_cb') );
     153                remove_filter( 'auth_post_meta_flight_number', '__return_true');
     154
     155                $this->assertEquals( array(), $actual );
     156        }
     157
     158        public function test_register_meta_with_deprecated_sanitize_callback_param_returns_false() {
     159                $actual = register_meta( 'post', 'flight_number', array( $this, '_old_sanitize_meta_cb' ) );
     160
     161                remove_filter( 'sanitize_post_meta_flight_number', array( $this, '_old_sanitize_meta_cb') );
     162                remove_filter( 'auth_post_meta_flight_number', '__return_true');
     163
     164                $this->assertFalse( $actual );
     165        }
     166
     167        public function test_register_meta_with_deprecated_sanitize_callback_parameter_passes_through_filter() {
     168                register_meta( 'post', 'old_sanitized_key', array( $this, '_old_sanitize_meta_cb' ) );
     169                $meta = sanitize_meta( 'old_sanitized_key', 'unsanitized', 'post', 'post' );
     170
     171                remove_filter( 'sanitize_post_meta_flight_number', array( $this, '_old_sanitize_meta_cb') );
     172                remove_filter( 'auth_post_meta_flight_number', '__return_true');
     173
     174                $this->assertEquals( 'old_sanitized_key old sanitized', $meta );
     175        }
     176
     177        public function test_register_meta_with_current_sanitize_callback_populates_wp_meta_keys() {
     178                global $wp_meta_keys;
     179                register_meta( 'post', 'flight_number', array( 'object_subtype' => 'post', 'sanitize_callback' => array( $this, '_new_sanitize_meta_cb' ) ) );
     180                $actual = $wp_meta_keys;
     181                unregister_meta_key( 'post', 'post', 'flight_number' );
     182
     183                $expected = array(
     184                        'post' => array(
     185                                'post' => array(
     186                                        'flight_number' => array(
     187                                                'object_subtype' => 'post',
     188                                                'type' => 'string',
     189                                                'description' => '',
     190                                                'single' => false,
     191                                                'sanitize_callback' => array( $this, '_new_sanitize_meta_cb' ),
     192                                                'auth_callback' => '__return_true',
     193                                                'show_in_rest' => false,
     194                                        ),
     195                                ),
     196                        ),
     197                );
     198                $this->assertEquals( $actual, $expected );
     199        }
     200
     201        public function test_register_meta_with_current_sanitize_callback_returns_true() {
     202                $result = register_meta( 'post', 'flight_number', array( 'object_subtype' => 'post', 'sanitize_callback' => array( $this, '_new_sanitize_meta_cb' ) ) );
     203                unregister_meta_key( 'post', 'post', 'flight_number' );
     204
     205                // @todo unregister_meta_key should do this for registered meta keys
     206                remove_filter( 'sanitize_post_post_meta_flight_number', array( $this, '_new_sanitize_meta_cb') );
     207                remove_filter( 'auth_post_post_meta_flight_number', '__return_true');
     208
     209                $this->assertTrue( $result );
     210        }
     211
     212        public function test_register_meta_with_new_sanitize_callback_parameter() {
     213                register_meta( 'post', 'new_sanitized_key', array( 'object_subtype' => 'post', 'sanitize_callback' => array( $this, '_new_sanitize_meta_cb' ) ) );
     214                $meta = sanitize_meta( 'new_sanitized_key', 'unsanitized', 'post', 'post' );
     215
     216                unregister_meta_key( 'post', 'post', 'new_sanitized_key' );
     217
     218                // @todo unregister_meta_key should do this for registered meta keys
     219                remove_filter( 'sanitize_post_post_meta_new_sanitized_key', array( $this, '_new_sanitize_meta_cb') );
     220                remove_filter( 'auth_post_post_meta_new_sanitized_key', '__return_true');
     221
     222                $this->assertEquals( 'new_sanitized_key new sanitized', $meta );
     223        }
     224
     225        public function test_unregister_meta_key_clears_key_from_wp_meta_keys() {
     226                global $wp_meta_keys;
     227                register_meta( 'post', 'registered_key', array( 'object_subtype' => 'post' ) );
     228                unregister_meta_key( 'post', 'post', 'registered_key' );
     229
     230                $this->assertEquals( array(), $wp_meta_keys );
     231        }
     232
     233        public function test_unregister_meta_key_with_invalid_key_returns_wp_error() {
     234                $this->assertWPError( unregister_meta_key( 'post', 'post', 'not_a_registered_key' ) );
     235        }
     236
     237        public function test_get_registered_meta_keys() {
     238                register_meta( 'post', 'registered_key1', array( 'object_subtype' => 'post' ) );
     239                register_meta( 'post', 'registered_key2', array( 'object_subtype' => 'post' ) );
     240
     241                $meta_keys = get_registered_meta_keys( 'post', 'post' );
     242
     243                unregister_meta_key( 'post', 'post', 'registered_key1' );
     244                unregister_meta_key( 'post', 'post', 'registered_key2' );
     245
     246                $this->assertArrayHasKey( 'registered_key1', $meta_keys );
     247                $this->assertArrayHasKey( 'registered_key2', $meta_keys );
     248        }
     249
     250        public function test_get_registered_meta_keys_with_subtype_without_registered_keys_is_empty() {
     251                register_meta( 'post', 'registered_key1', array( 'object_subtype' => 'post' ) );
     252                register_meta( 'post', 'registered_key2', array( 'object_subtype' => 'post' ) );
     253
     254                $meta_keys = get_registered_meta_keys( 'post', 'page' );
     255
     256                unregister_meta_key( 'post', 'post', 'registered_key1' );
     257                unregister_meta_key( 'post', 'post', 'registered_key2' );
     258
     259                $this->assertEmpty( $meta_keys );
     260        }
     261
     262        public function test_get_registered_meta_keys_with_invalid_type_is_empty() {
     263                register_meta( 'post', 'registered_key1', array( 'object_subtype' => 'post' ) );
     264                register_meta( 'post', 'registered_key2', array( 'object_subtype' => 'post' ) );
     265
     266                $meta_keys = get_registered_meta_keys( 'invalid-type' );
     267
     268                unregister_meta_key( 'post', 'post', 'registered_key1' );
     269                unregister_meta_key( 'post', 'post', 'registered_key2' );
     270
     271                $this->assertEmpty( $meta_keys );
     272        }
     273
     274        public function test_get_registered_meta_keys_has_count() {
     275                register_meta( 'post', 'registered_key1', array( 'object_subtype' => 'post' ) );
     276                register_meta( 'post', 'registered_key2', array( 'object_subtype' => 'page' ) );
     277
     278                $meta_keys = get_registered_meta_keys( 'post' );
     279
     280                $this->assertCount( 2, $meta_keys );
     281        }
     282
     283        public function test_get_registered_meta_keys_description_arg() {
     284                register_meta( 'post', 'registered_key1', array( 'object_subtype' => 'post', 'description' => 'I\'m just a field, take a good look at me' ) );
     285
     286                $meta_keys = get_registered_meta_keys( 'post', 'post' );
     287
     288                $this->assertEquals( 'I\'m just a field, take a good look at me', $meta_keys['registered_key1']['description'] );
     289        }
     290
     291        public function test_get_registered_meta_keys_invalid_arg() {
     292                register_meta( 'post', 'registered_key1', array( 'object_subtype' => 'post', 'invalid_arg' => 'invalid' ) );
     293
     294                $meta_keys = get_registered_meta_keys( 'post', 'post' );
     295
     296                $this->assertArrayNotHasKey( 'invalid_arg', $meta_keys['registered_key1'] );
     297        }
     298
     299        public function test_get_registered_metadata() {
     300                register_meta( 'post', 'flight_number', array( 'object_subtype' => 'post' ) );
     301
     302                add_post_meta( self::$post_id, 'flight_number', 'Oceanic 815' );
     303
     304                $meta = get_registered_metadata( 'post', 'post', self::$post_id );
     305
     306                $this->assertEquals( 'Oceanic 815', $meta['flight_number'][0] );
     307        }
     308
     309        public function test_get_registered_metadata_by_key() {
     310                register_meta( 'post', 'flight_number', array( 'object_subtype' => 'post' ) );
     311
     312                add_post_meta( self::$post_id, 'flight_number', 'Oceanic 815' );
     313
     314                $meta = get_registered_metadata( 'post', 'post', self::$post_id, 'flight_number' );
     315
     316                $this->assertEquals( 'Oceanic 815', $meta[0] );
     317        }
     318
     319        public function test_get_registered_metadata_by_key_single() {
     320                register_meta( 'post', 'flight_number', array( 'object_subtype' => 'post', 'single' => true ) );
     321
     322                add_post_meta( self::$post_id, 'flight_number', 'Oceanic 815' );
     323
     324                $meta = get_registered_metadata( 'post', 'post', self::$post_id, 'flight_number' );
     325
     326                $this->assertEquals( 'Oceanic 815', $meta );
     327        }
     328
     329        public function test_get_registered_metadata_by_invalid_key() {
     330                register_meta( 'post', 'flight_number', array( 'object_subtype' => 'post' ) );
     331
     332                add_post_meta( self::$post_id, 'flight_number', 'Oceanic 815' );
     333
     334                $meta = get_registered_metadata( 'post', 'post', self::$post_id, 'flight_pilot' );
     335
     336                $this->assertWPError( $meta );
     337        }
     338
     339        public function test_get_registered_metadata_invalid_object_type() {
     340                register_meta( 'post', 'flight_number', array( 'object_subtype' => 'post' ) );
     341
     342                add_post_meta( self::$post_id, 'flight_number', 'Oceanic 815' );
     343
     344                $meta = get_registered_metadata( 'invalid-type', 'invalid-subtype', self::$post_id );
     345
     346                $this->assertWPError( $meta );
     347        }
     348
     349        public function test_get_registered_metadata_invalid() {
     350                $meta = get_registered_metadata( 'invalid-type', 'invalid-subtype', self::$post_id );
     351
     352                $this->assertWPError( $meta );
     353        }
     354}
  • tests/phpunit/tests/user/capabilities.php

     
    772772                        $this->assertTrue( $admin->has_cap('add_post_meta',  $post) );
    773773                        $this->assertTrue( $admin->has_cap('delete_post_meta',  $post) );
    774774
     775                        // Test protected key access is false
    775776                        $this->assertFalse( $admin->has_cap('edit_post_meta', $post, '_protected') );
    776777                        $this->assertFalse( $admin->has_cap('add_post_meta', $post, '_protected') );
    777778                        $this->assertFalse( $admin->has_cap('delete_post_meta', $post, '_protected') );
    778779
    779                         register_meta( 'post', '_protected', array( $this, '_meta_filter' ), array( $this, '_meta_yes_you_can' ) );
     780                        // Register protected key and allow access
     781                        register_meta( 'post', '_protected', array( 'sanitize_callback' => array( $this, '_meta_filter' ), 'auth_callback' => array( $this, '_meta_yes_you_can' ) ) );
     782
     783                        // Test protected key access is now true
    780784                        $this->assertTrue( $admin->has_cap('edit_post_meta',  $post, '_protected') );
    781785                        $this->assertTrue( $admin->has_cap('add_post_meta',  $post, '_protected') );
    782786                        $this->assertTrue( $admin->has_cap('delete_post_meta',  $post, '_protected') );
    783787
     788                        // Test non protected key access is true
    784789                        $this->assertTrue( $admin->has_cap('edit_post_meta', $post, 'not_protected') );
    785790                        $this->assertTrue( $admin->has_cap('add_post_meta', $post, 'not_protected') );
    786791                        $this->assertTrue( $admin->has_cap('delete_post_meta', $post, 'not_protected') );
    787792
    788                         register_meta( 'post', 'not_protected', array( $this, '_meta_filter' ), array( $this, '_meta_no_you_cant' ) );
     793                        // Register non protected key and disallow access
     794                        register_meta( 'post', 'not_protected', array( 'sanitize_callback' => array( $this, '_meta_filter' ), 'auth_callback' => array( $this, '_meta_no_you_cant' ) ) );
     795
     796                        // Test non protected key access is now false
    789797                        $this->assertFalse( $admin->has_cap('edit_post_meta',  $post, 'not_protected') );
    790798                        $this->assertFalse( $admin->has_cap('add_post_meta',  $post, 'not_protected') );
    791799                        $this->assertFalse( $admin->has_cap('delete_post_meta',  $post, 'not_protected') );
     800
     801                        // Backwards compatibility tests for register_meta()
     802
     803                        // Test protected key access is false
     804                        $this->assertFalse( $admin->has_cap('edit_post_meta', $post, '_protected_backcompat') );
     805                        $this->assertFalse( $admin->has_cap('add_post_meta', $post, '_protected_backcompat') );
     806                        $this->assertFalse( $admin->has_cap('delete_post_meta', $post, '_protected_backcompat') );
     807
     808                        // Register protected key and allow access
     809                        register_meta( 'post', '_protected_backcompat', array( $this, '_meta_filter' ), array( $this, '_meta_yes_you_can' ) );
     810
     811                        // Test protected key access is now true
     812                        $this->assertTrue( $admin->has_cap('edit_post_meta',  $post, '_protected_backcompat') );
     813                        $this->assertTrue( $admin->has_cap('add_post_meta',  $post, '_protected_backcompat') );
     814                        $this->assertTrue( $admin->has_cap('delete_post_meta',  $post, '_protected_backcompat') );
     815
     816                        // Test non protected key access is true
     817                        $this->assertTrue( $admin->has_cap('edit_post_meta', $post, 'not_protected_backcompat') );
     818                        $this->assertTrue( $admin->has_cap('add_post_meta', $post, 'not_protected_backcompat') );
     819                        $this->assertTrue( $admin->has_cap('delete_post_meta', $post, 'not_protected_backcompat') );
     820
     821                        // Register non protected key and disallow access
     822                        register_meta( 'post', 'not_protected_backcompat', array( $this, '_meta_filter' ), array( $this, '_meta_no_you_cant' ) );
     823
     824                        // Test non protected key access is now false
     825                        $this->assertFalse( $admin->has_cap('edit_post_meta',  $post, 'not_protected_backcompat') );
     826                        $this->assertFalse( $admin->has_cap('add_post_meta',  $post, 'not_protected_backcompat') );
     827                        $this->assertFalse( $admin->has_cap('delete_post_meta',  $post, 'not_protected_backcompat') );
    792828                }
    793829        }
    794830