WordPress.org

Make WordPress Core

Ticket #38323: 38323.3.diff

File 38323.3.diff, 26.9 KB (added by flixos90, 3 years ago)
  • src/wp-includes/class-wp-meta-key.php

     
     1<?php
     2/**
     3 * Meta API: WP_Meta_Key class.
     4 *
     5 * @package WordPress
     6 * @subpackage Meta
     7 * @since 4.8.0
     8 */
     9
     10/**
     11 * Class representing a registered meta key.
     12 *
     13 * @since 4.8.0
     14 */
     15class WP_Meta_Key {
     16
     17        /**
     18         * Name of the meta key.
     19         *
     20         * @since 4.8.0
     21         * @access private
     22         * @var string
     23         */
     24        private $meta_key = '';
     25
     26        /**
     27         * Type of object this meta key is registered to.
     28         *
     29         * @since 4.8.0
     30         * @access private
     31         * @var string
     32         */
     33        private $object_type = '';
     34
     35        /**
     36         * Definition sets used to describe the meta key.
     37         *
     38         * @since 4.8.0
     39         * @access private
     40         * @var array
     41         */
     42        private $definition_sets = array();
     43
     44        /**
     45         * Constructor.
     46         *
     47         * Registers the initial meta key definition set.
     48         *
     49         * @since 4.8.0
     50         * @access public
     51         *
     52         * @param string $object_type Type of object this meta is registered to.
     53         * @param string $meta_key    Name of the meta key.
     54         * @param array  $args        $args {
     55         *     Data used to describe the meta key.
     56         *
     57         *     @type string $object_subtype    A subtype; e.g. if the object type is "post", the post type. If left empty,
     58         *                                     the meta key will be registered on the entire object type. Default empty.
     59         *     @type string $type              The type of data associated with this meta key.
     60         *     @type string $description       A description of the data attached to this meta key.
     61         *     @type bool   $single            Whether the meta key has one value per object, or an array of values per object.
     62         *     @type string $sanitize_callback A function or method to call when sanitizing `$meta_key` data.
     63         *     @type string $auth_callback     Optional. A function or method to call when performing edit_post_meta, add_post_meta, and delete_post_meta capability checks.
     64         *     @type bool   $show_in_rest      Whether data associated with this meta key can be considered public.
     65         * }
     66         */
     67        public function __construct( $object_type, $meta_key, $args ) {
     68                $this->object_type = $object_type;
     69                $this->meta_key    = $meta_key;
     70
     71                $this->register( $args );
     72        }
     73
     74        /**
     75         * Registers a new definition set for this meta key.
     76         *
     77         * @since 4.8.0
     78         * @access public
     79         *
     80         * @param array $args Data to describe the meta key. See `WP_Meta_Key::__construct()` for the list of supported arguments.
     81         * @return bool|WP_Error True on success, WP_Error on failure.
     82         */
     83        public function register( $args ) {
     84                $defaults = $this->get_defaults();
     85
     86                /**
     87                 * Filters the registration arguments when registering meta.
     88                 *
     89                 * @since 4.6.0
     90                 *
     91                 * @param array  $args        Array of meta registration arguments.
     92                 * @param array  $defaults    Array of default arguments.
     93                 * @param string $object_type Object type.
     94                 * @param string $meta_key    Meta key.
     95                 */
     96                $args = apply_filters( 'register_meta_args', $args, $defaults, $this->object_type, $this->meta_key );
     97                $args = wp_parse_args( $args, $defaults );
     98
     99                if ( empty( $args['auth_callback'] ) ) {
     100                        $args['auth_callback'] = self::get_default_auth_callback( $this->object_type, $this->meta_key );
     101                }
     102
     103                $object_subtype = isset( $args['object_subtype'] ) ? $args['object_subtype'] : '';
     104
     105                /*
     106                 * A meta key cannot be registered on a subtype if it is already registered for the entire type.
     107                 * It can also not be registered for the entire type if it is already registered on a subtype.
     108                 */
     109                if ( ! empty( $object_subtype ) && isset( $this->definition_sets[ '' ] )
     110                        || empty( $object_subtype ) && ! empty( $this->definition_sets ) ) {
     111                        return new WP_Error( 'meta_key_already_exists', sprintf( __( 'The meta key %1$s is already registered for the object type %2$s.' ), $this->meta_key, $this->object_type ) );
     112                }
     113
     114                $this->definition_sets[ $object_subtype ] = $args;
     115
     116                $this->add_filters( $object_subtype );
     117
     118                return true;
     119        }
     120
     121        /**
     122         * Unregisters an existing definition set for this meta key.
     123         *
     124         * @since 4.8.0
     125         * @access public
     126         *
     127         * @param string $object_subtype Optional. Name of the object subtype to remove its definition. When
     128         *                               this is left empty, the definition set for the entire object type is
     129         *                               unregistered. Default empty.
     130         * @return bool|WP_Error True on success, WP_Error on failure.
     131         */
     132        public function unregister( $object_subtype = '' ) {
     133                if ( ! isset( $this->definition_sets[ $object_subtype ] ) ) {
     134                        if ( empty( $object_subtype ) ) {
     135                                return new WP_Error( 'meta_key_not_exists', sprintf( __( 'The meta key %1$s is not registered for the object type %2$s.' ), $this->meta_key, $this->object_type ) );
     136                        }
     137
     138                        return new WP_Error( 'meta_key_not_exists', sprintf( __( 'The meta key %1$s is not registered for the object type %2$s and subtype %3$s.' ), $this->meta_key, $this->object_type, $object_subtype ) );
     139                }
     140
     141                $this->remove_filters( $object_subtype );
     142
     143                unset( $this->definition_sets[ $object_subtype ] );
     144
     145                return true;
     146        }
     147
     148        /**
     149         * Checks whether a definition set is registered for a specific subtype.
     150         *
     151         * If the meta key is not registered for $object_subtype specifically, the method will also check
     152         * whether it is registered for the entire object type.
     153         *
     154         * @since 4.8.0
     155         * @access public
     156         *
     157         * @param string $object_subtype Optional. Name of the object subtype to check for. When this is left
     158         *                               empty, the method checks for the definition set of the entire object
     159         *                               type. Default empty.
     160         * @return bool True if a definition set is registered, false otherwise.
     161         */
     162        public function is_registered( $object_subtype = '' ) {
     163                if ( ! isset( $this->definition_sets[ $object_subtype ] ) ) {
     164                        if ( empty( $object_subtype ) || ! isset( $this->definition_sets[''] ) ) {
     165                                return false;
     166                        }
     167                }
     168
     169                return true;
     170        }
     171
     172        /**
     173         * Returns the definition set for a specific subtype.
     174         *
     175         * If the meta key is not registered for $object_subtype, the method will return the definition set
     176         * registered for the entire type if available.
     177         *
     178         * @since 4.8.0
     179         * @access public
     180         *
     181         * @param string $object_subtype Optional. Name of the subtype to get its definition set. When this is left
     182         *                               empty, the method returns the definition set for the entire object type.
     183         *                               Default empty.
     184         * @return array|false Definition set data, or false if not registered.
     185         */
     186        public function get_definition_set( $object_subtype = '' ) {
     187                if ( ! isset( $this->definition_sets[ $object_subtype ] ) ) {
     188                        if ( empty( $object_subtype ) ) {
     189                                return false;
     190                        }
     191
     192                        $object_subtype = '';
     193
     194                        if ( ! isset( $this->definition_sets[ $object_subtype ] ) ) {
     195                                return false;
     196                        }
     197                }
     198
     199                return $this->definition_sets[ $object_subtype ];
     200        }
     201
     202        /**
     203         * Returns the definition sets of all subtypes.
     204         *
     205         * @since 4.8.0
     206         * @access public
     207         *
     208         * @return array Definition sets as `$object_subtype => $data` pairs.
     209         */
     210        public function get_subtype_definition_sets() {
     211                $definition_sets = $this->definition_sets;
     212                if ( isset( $definition_sets[''] ) ) {
     213                        unset( $definition_sets[''] );
     214                }
     215
     216                return $definition_sets;
     217        }
     218
     219        /**
     220         * Returns the default arguments for a definition set.
     221         *
     222         * @since 4.8.0
     223         * @access private
     224         *
     225         * @return array Array of default arguments.
     226         */
     227        private function get_defaults() {
     228                return array(
     229                        'object_subtype'    => '',
     230                        'type'              => 'string',
     231                        'description'       => '',
     232                        'single'            => false,
     233                        'sanitize_callback' => null,
     234                        'auth_callback'     => null,
     235                        'show_in_rest'      => false,
     236                );
     237        }
     238
     239        /**
     240         * Adds filters for sanitize and auth callbacks of this meta key.
     241         *
     242         * @since 4.8.0
     243         * @access private
     244         *
     245         * @param string $object_subtype Optional. Name of the object subtype to add the filters to. When this is left empty,
     246         *                               the method adds the filters to the entire object type. Default empty.
     247         */
     248        private function add_filters( $object_subtype = '' ) {
     249                $args = $this->definition_sets[ $object_subtype ];
     250
     251                self::add_legacy_filters( $this->object_type, $this->meta_key, $args['sanitize_callback'], $args['auth_callback'], $object_subtype );
     252        }
     253
     254        /**
     255         * Removes filters for sanitize and auth callbacks of this meta key.
     256         *
     257         * @since 4.8.0
     258         * @access private
     259         *
     260         * @param string $object_subtype Optional. Name of the object subtype to remove the filters from. When this is left empty,
     261         *                               the method removes the filters from the entire object type. Default empty.
     262         */
     263        private function remove_filters( $object_subtype = '' ) {
     264                $args = $this->definition_sets[ $object_subtype ];
     265
     266                if ( isset( $args['sanitize_callback'] ) && is_callable( $args['sanitize_callback'] ) ) {
     267                        if ( ! empty( $object_subtype ) ) {
     268                                remove_filter( "sanitize_{$this->object_type}_{$object_subtype}_meta_{$this->meta_key}", $args['sanitize_callback'] );
     269                        } else {
     270                                remove_filter( "sanitize_{$this->object_type}_meta_{$this->meta_key}", $args['sanitize_callback'] );
     271                        }
     272                }
     273
     274                if ( isset( $args['auth_callback'] ) && is_callable( $args['auth_callback'] ) ) {
     275                        if ( ! empty( $object_subtype ) ) {
     276                                remove_filter( "auth_{$this->object_type}_{$object_subtype}_meta_{$this->meta_key}", $args['auth_callback'] );
     277                        } else {
     278                                remove_filter( "auth_{$this->object_type}_meta_{$this->meta_key}", $args['auth_callback'] );
     279                        }
     280                }
     281        }
     282
     283        /**
     284         * Adds filters for sanitize and auth callbacks of a specific meta key.
     285         *
     286         * @since 4.8.0
     287         * @access public
     288         * @static
     289         *
     290         * @param string   $object_type       Object type.
     291         * @param string   $meta_key          Meta key.
     292         * @param callable $sanitize_callback A function or method to call when sanitizing `$meta_key` data.
     293         * @param callable $auth_callback     Optional. A function or method to call when performing edit_post_meta, add_post_meta, and delete_post_meta capability checks.
     294         * @param string   $object_subtype    Optional. Name of the object subtype to add the filters to. When this is left empty,
     295         *                                    the method adds the filters to the entire object type. Default empty.
     296         */
     297        public static function add_legacy_filters( $object_type, $meta_key, $sanitize_callback, $auth_callback = null, $object_subtype = '' ) {
     298                // If `auth_callback` is not provided, fall back to `is_protected_meta()`.
     299                if ( empty( $auth_callback ) ) {
     300                        $auth_callback = self::get_default_auth_callback( $object_type, $meta_key );
     301                }
     302
     303                if ( is_callable( $sanitize_callback ) ) {
     304                        if ( ! empty( $object_subtype ) ) {
     305                                add_filter( "sanitize_{$object_type}_{$object_subtype}_meta_{$meta_key}", $sanitize_callback, 10, 4 );
     306                        } else {
     307                                add_filter( "sanitize_{$object_type}_meta_{$meta_key}", $sanitize_callback, 10, 4 );
     308                        }
     309                }
     310
     311                if ( is_callable( $auth_callback ) ) {
     312                        if ( ! empty( $object_subtype ) ) {
     313                                add_filter( "auth_{$object_type}_{$object_subtype}_meta_{$meta_key}", $auth_callback, 10, 6 );
     314                        } else {
     315                                add_filter( "auth_{$object_type}_meta_{$meta_key}", $auth_callback, 10, 6 );
     316                        }
     317                }
     318        }
     319
     320        /**
     321         * Returns the default authorization callback.
     322         *
     323         * @since 4.8.0
     324         * @access private
     325         * @static
     326         *
     327         * @param string $object_type Object type.
     328         * @param string $meta_key    Meta key.
     329         * @return callable Default authorization callback.
     330         */
     331        private static function get_default_auth_callback( $object_type, $meta_key ) {
     332                if ( is_protected_meta( $meta_key, $object_type ) ) {
     333                        return '__return_false';
     334                }
     335
     336                return '__return_true';
     337        }
     338}
  • src/wp-includes/meta.php

    Property changes on: src/wp-includes/class-wp-meta-key.php
    ___________________________________________________________________
    Added: svn:executable
    ## -0,0 +1 ##
    +*
    \ No newline at end of property
     
    4444                return false;
    4545        }
    4646
     47        $meta_subtype = get_object_subtype( $meta_type, $object_id );
     48
    4749        $column = sanitize_key($meta_type . '_id');
    4850
    4951        // expected_slashed ($meta_key)
    5052        $meta_key = wp_unslash($meta_key);
    5153        $meta_value = wp_unslash($meta_value);
    52         $meta_value = sanitize_meta( $meta_key, $meta_value, $meta_type );
     54        $meta_value = sanitize_meta( $meta_key, $meta_value, $meta_type, $meta_subtype );
    5355
    5456        /**
    5557         * Filters whether to add metadata of a specific type.
     
    157159                return false;
    158160        }
    159161
     162        $meta_subtype = get_object_subtype( $meta_type, $object_id );
     163
    160164        $column = sanitize_key($meta_type . '_id');
    161165        $id_column = 'user' == $meta_type ? 'umeta_id' : 'meta_id';
    162166
     
    165169        $meta_key = wp_unslash($meta_key);
    166170        $passed_value = $meta_value;
    167171        $meta_value = wp_unslash($meta_value);
    168         $meta_value = sanitize_meta( $meta_key, $meta_value, $meta_type );
     172        $meta_value = sanitize_meta( $meta_key, $meta_value, $meta_type, $meta_subtype );
    169173
    170174        /**
    171175         * Filters whether to update metadata of a specific type.
     
    641645                        return false;
    642646                }
    643647
     648                $meta_subtype = get_object_subtype( $meta_type, $object_id );
     649
    644650                // Sanitize the meta
    645651                $_meta_value = $meta_value;
    646                 $meta_value = sanitize_meta( $meta_key, $meta_value, $meta_type );
     652                $meta_value = sanitize_meta( $meta_key, $meta_value, $meta_type, $meta_subtype );
    647653                $meta_value = maybe_serialize( $meta_value );
    648654
    649655                // Format the data query arguments.
     
    936942 * Sanitize meta value.
    937943 *
    938944 * @since 3.1.3
     945 * @since 4.8.0 The `$object_subtype` parameter was added.
    939946 *
    940947 * @param string $meta_key       Meta key.
    941948 * @param mixed  $meta_value     Meta value to sanitize.
     
    943950 *
    944951 * @return mixed Sanitized $meta_value.
    945952 */
    946 function sanitize_meta( $meta_key, $meta_value, $object_type ) {
     953function sanitize_meta( $meta_key, $meta_value, $object_type, $object_subtype = '' ) {
     954        if ( ! empty( $object_subtype ) ) {
     955                /**
     956                 * Filters the sanitization of a specific meta key of a specific meta type and subtype.
     957                 *
     958                 * The dynamic portions of the hook name, `$object_type`, `$object_subtype`
     959                 * and `$meta_key`, refer to the metadata object type (comment, post, term or user),
     960                 * the object subtype and the meta key value, respectively.
     961                 *
     962                 * @since 4.8.0
     963                 *
     964                 * @param mixed  $meta_value     Meta value to sanitize.
     965                 * @param string $meta_key       Meta key.
     966                 * @param string $object_type    Object type.
     967                 * @param string $object_subtype Object subtype.
     968                 */
     969                $meta_value = apply_filters( "sanitize_{$object_type}_{$object_subtype}_meta_{$meta_key}", $meta_value, $meta_key, $object_type, $object_subtype );
     970        }
     971
    947972        /**
    948973         * Filters the sanitization of a specific meta key of a specific meta type.
    949974         *
     
    952977         * key value, respectively.
    953978         *
    954979         * @since 3.3.0
     980         * @since 4.8.0 Added the `$object_subtype` parameter.
    955981         *
    956          * @param mixed  $meta_value      Meta value to sanitize.
    957          * @param string $meta_key        Meta key.
    958          * @param string $object_type     Object type.
     982         * @param mixed  $meta_value     Meta value to sanitize.
     983         * @param string $meta_key       Meta key.
     984         * @param string $object_type    Object type.
     985         * @param string $object_subtype Object subtype.
    959986         */
    960         return apply_filters( "sanitize_{$object_type}_meta_{$meta_key}", $meta_value, $meta_key, $object_type );
     987        return apply_filters( "sanitize_{$object_type}_meta_{$meta_key}", $meta_value, $meta_key, $object_type, $object_subtype );
    961988}
    962989
    963990/**
     
    967994 * @since 4.6.0 {@link https://core.trac.wordpress.org/ticket/35658 Modified
    968995 *              to support an array of data to attach to registered meta keys}. Previous arguments for
    969996 *              `$sanitize_callback` and `$auth_callback` have been folded into this array.
     997 * @since 4.8.0 Registered meta keys are now objects of the `WP_Meta_Key` class. Registering meta for
     998 *              specific object subtypes is now supported.
    970999 *
    971  * @param string $object_type    Type of object this meta is registered to.
    972  * @param string $meta_key       Meta key to register.
    973  * @param array  $args {
    974  *     Data used to describe the meta key when registered.
    975  *
    976  *     @type string $type              The type of data associated with this meta key.
    977  *     @type string $description       A description of the data attached to this meta key.
    978  *     @type bool   $single            Whether the meta key has one value per object, or an array of values per object.
    979  *     @type string $sanitize_callback A function or method to call when sanitizing `$meta_key` data.
    980  *     @type string $auth_callback     Optional. A function or method to call when performing edit_post_meta, add_post_meta, and delete_post_meta capability checks.
    981  *     @type bool   $show_in_rest      Whether data associated with this meta key can be considered public.
    982  * }
    983  * @param string|array $deprecated Deprecated. Use `$args` instead.
     1000 * @param string       $object_type Type of object this meta is registered to.
     1001 * @param string       $meta_key    Meta key to register.
     1002 * @param array        $args        Data used to describe the meta key when registered. See
     1003 *                                  `WP_Meta_Key::__construct()` for the list of supported arguments.
     1004 * @param string|array $deprecated  Deprecated. Use `$args` instead.
    9841005 *
    9851006 * @return bool True if the meta key was successfully registered in the global array, false if not.
    9861007 *                       Registering a meta key with distinct sanitize and auth callbacks will fire those
     
    9931014                $wp_meta_keys = array();
    9941015        }
    9951016
    996         $defaults = array(
    997                 'type'              => 'string',
    998                 'description'       => '',
    999                 'single'            => false,
    1000                 'sanitize_callback' => null,
    1001                 'auth_callback'     => null,
    1002                 'show_in_rest'      => false,
    1003         );
    1004 
    1005         // There used to be individual args for sanitize and auth callbacks
    1006         $has_old_sanitize_cb = false;
    1007         $has_old_auth_cb = false;
    1008 
    1009         if ( is_callable( $args ) ) {
    1010                 $args = array(
    1011                         'sanitize_callback' => $args,
    1012                 );
     1017        // Global registry only contains meta keys registered with the array of arguments added in 4.6.0.
     1018        if ( is_callable( $args ) || is_callable( $deprecated ) ) {
     1019                WP_Meta_Key::add_legacy_filters( $object_type, $meta_key, $args, $deprecated );
    10131020
    1014                 $has_old_sanitize_cb = true;
    1015         } else {
    1016                 $args = (array) $args;
     1021                return false;
    10171022        }
    10181023
    1019         if ( is_callable( $deprecated ) ) {
    1020                 $args['auth_callback'] = $deprecated;
    1021                 $has_old_auth_cb = true;
    1022         }
     1024        $args = (array) $args;
    10231025
    1024         /**
    1025          * Filters the registration arguments when registering meta.
    1026          *
    1027          * @since 4.6.0
    1028          *
    1029          * @param array  $args        Array of meta registration arguments.
    1030          * @param array  $defaults    Array of default arguments.
    1031          * @param string $object_type Object type.
    1032          * @param string $meta_key    Meta key.
    1033          */
    1034         $args = apply_filters( 'register_meta_args', $args, $defaults, $object_type, $meta_key );
    1035         $args = wp_parse_args( $args, $defaults );
     1026        if ( isset( $wp_meta_keys[ $object_type ][ $meta_key ] ) ) {
     1027                $meta_key_object = $wp_meta_keys[ $object_type ][ $meta_key ];
    10361028
    1037         // If `auth_callback` is not provided, fall back to `is_protected_meta()`.
    1038         if ( empty( $args['auth_callback'] ) ) {
    1039                 if ( is_protected_meta( $meta_key, $object_type ) ) {
    1040                         $args['auth_callback'] = '__return_false';
    1041                 } else {
    1042                         $args['auth_callback'] = '__return_true';
     1029                if ( is_wp_error( $meta_key_object->register( $args ) ) ) {
     1030                        return false;
    10431031                }
    1044         }
    1045 
    1046         // Back-compat: old sanitize and auth callbacks are applied to all of an object type.
    1047         if ( is_callable( $args['sanitize_callback'] ) ) {
    1048                 add_filter( "sanitize_{$object_type}_meta_{$meta_key}", $args['sanitize_callback'], 10, 3 );
    1049         }
    1050 
    1051         if ( is_callable( $args['auth_callback'] ) ) {
    1052                 add_filter( "auth_{$object_type}_meta_{$meta_key}", $args['auth_callback'], 10, 6 );
    1053         }
    1054 
    1055         // Global registry only contains meta keys registered with the array of arguments added in 4.6.0.
    1056         if ( ! $has_old_auth_cb && ! $has_old_sanitize_cb ) {
    1057                 $wp_meta_keys[ $object_type ][ $meta_key ] = $args;
     1032        } else {
     1033                $meta_key_object = new WP_Meta_Key( $object_type, $meta_key, $args );
    10581034
    1059                 return true;
     1035                $wp_meta_keys[ $object_type ][ $meta_key ] = $meta_key_object;
    10601036        }
    10611037
    1062         return false;
     1038        return true;
    10631039}
    10641040
    10651041/**
    10661042 * Checks if a meta key is registered.
    10671043 *
    10681044 * @since 4.6.0
     1045 * @since 4.8.0 The `$object_subtype` parameter was added.
    10691046 *
    10701047 * @param string $object_type    The type of object.
    10711048 * @param string $meta_key       The meta key.
     1049 * @param string $object_subtype Optional. The subtype of the object type.
    10721050 *
    10731051 * @return bool True if the meta key is registered to the object type. False if not.
    10741052 */
    1075 function registered_meta_key_exists( $object_type, $meta_key ) {
     1053function registered_meta_key_exists( $object_type, $meta_key, $object_subtype = '' ) {
    10761054        global $wp_meta_keys;
    10771055
    10781056        if ( ! is_array( $wp_meta_keys ) ) {
     
    10831061                return false;
    10841062        }
    10851063
    1086         if ( isset( $wp_meta_keys[ $object_type ][ $meta_key ] ) ) {
    1087                 return true;
     1064        if ( ! isset( $wp_meta_keys[ $object_type ][ $meta_key ] ) ) {
     1065                return false;
    10881066        }
    10891067
    1090         return false;
     1068        if ( ! $wp_meta_keys[ $object_type ][ $meta_key ]->is_registered( $object_subtype ) ) {
     1069                return false;
     1070        }
     1071
     1072        return true;
    10911073}
    10921074
    10931075/**
    10941076 * Unregisters a meta key from the list of registered keys.
    10951077 *
    10961078 * @since 4.6.0
     1079 * @since 4.8.0 The `$object_subtype` parameter was added.
    10971080 *
    1098  * @param string $object_type The type of object.
    1099  * @param string $meta_key    The meta key.
     1081 * @param string $object_type    The type of object.
     1082 * @param string $meta_key       The meta key.
     1083 * @param string $object_subtype Optional. The subtype of the object type.
    11001084 * @return bool True if successful. False if the meta key was not registered.
    11011085 */
    1102 function unregister_meta_key( $object_type, $meta_key ) {
     1086function unregister_meta_key( $object_type, $meta_key, $object_subtype = '' ) {
    11031087        global $wp_meta_keys;
    11041088
    1105         if ( ! registered_meta_key_exists( $object_type, $meta_key ) ) {
     1089        if ( ! isset( $wp_meta_keys[ $object_type ][ $meta_key ] ) ) {
    11061090                return false;
    11071091        }
    11081092
    1109         $args = $wp_meta_keys[ $object_type ][ $meta_key ];
    1110 
    1111         if ( isset( $args['sanitize_callback'] ) && is_callable( $args['sanitize_callback'] ) ) {
    1112                 remove_filter( "sanitize_{$object_type}_meta_{$meta_key}", $args['sanitize_callback'] );
    1113         }
     1093        $meta_key_object = $wp_meta_keys[ $object_type ][ $meta_key ];
    11141094
    1115         if ( isset( $args['auth_callback'] ) && is_callable( $args['auth_callback'] ) ) {
    1116                 remove_filter( "auth_{$object_type}_meta_{$meta_key}", $args['auth_callback'] );
     1095        if ( is_wp_error( $meta_key_object->unregister( $object_subtype ) ) ) {
     1096                return false;
    11171097        }
    11181098
    1119         unset( $wp_meta_keys[ $object_type ][ $meta_key ] );
    1120 
    11211099        // Do some clean up
     1100        if ( ! $meta_key_object->get_definition_set() && empty( $meta_key_object->get_subtype_definition_sets() ) ) {
     1101                unset( $wp_meta_keys[ $object_type ][ $meta_key ] );
     1102        }
    11221103        if ( empty( $wp_meta_keys[ $object_type ] ) ) {
    11231104                unset( $wp_meta_keys[ $object_type ] );
    11241105        }
     
    11301111 * Retrieves a list of registered meta keys for an object type.
    11311112 *
    11321113 * @since 4.6.0
     1114 * @since 4.8.0 The `$object_subtype` parameter was added.
    11331115 *
    1134  * @param string $object_type The type of object. Post, comment, user, term.
     1116 * @param string $object_type    The type of object. Post, comment, user, term.
     1117 * @param string $object_subtype Optional. The subtype of the object type.
    11351118 * @return array List of registered meta keys.
    11361119 */
    1137 function get_registered_meta_keys( $object_type ) {
     1120function get_registered_meta_keys( $object_type, $object_subtype = '' ) {
    11381121        global $wp_meta_keys;
    11391122
    11401123        if ( ! is_array( $wp_meta_keys ) || ! isset( $wp_meta_keys[ $object_type ] ) ) {
    11411124                return array();
    11421125        }
    11431126
    1144         return $wp_meta_keys[ $object_type ];
     1127        $meta_keys = array();
     1128        foreach ( $wp_meta_keys[ $object_type ] as $meta_key => $meta_key_object ) {
     1129                if ( ! $meta_key_object->is_registered( $object_subtype ) ) {
     1130                        continue;
     1131                }
     1132
     1133                $meta_keys[ $meta_key ] = $meta_key_object->get_definition_set( $object_subtype );
     1134        }
     1135
     1136        return $meta_keys;
    11451137}
    11461138
    11471139/**
    11481140 * Retrieves registered metadata for a specified object.
    11491141 *
     1142 * The results include both meta that is registered specifically for the
     1143 * object's subtype and meta that is registered for the entire object type.
     1144 *
    11501145 * @since 4.6.0
    11511146 *
    11521147 * @param string $object_type Type of object to request metadata for. (e.g. comment, post, term, user)
     
    11571152 *               and values for an object ID if not.
    11581153 */
    11591154function get_registered_metadata( $object_type, $object_id, $meta_key = '' ) {
     1155        $object_subtype = get_object_subtype( $object_type, $object_id );
     1156
    11601157        if ( ! empty( $meta_key ) ) {
    1161                 if ( ! registered_meta_key_exists( $object_type, $meta_key ) ) {
     1158                if ( ! registered_meta_key_exists( $object_type, $meta_key, $object_subtype ) ) {
    11621159                        return false;
    11631160                }
    1164                 $meta_keys = get_registered_meta_keys( $object_type );
     1161
     1162                $meta_keys = get_registered_meta_keys( $object_type, $object_subtype );
    11651163                $meta_key_data = $meta_keys[ $meta_key ];
    11661164
    11671165                $data = get_metadata( $object_type, $object_id, $meta_key, $meta_key_data['single'] );
     
    11711169
    11721170        $data = get_metadata( $object_type, $object_id );
    11731171
    1174         $meta_keys = get_registered_meta_keys( $object_type );
     1172        $meta_keys = get_registered_meta_keys( $object_type, $object_subtype );
    11751173        $registered_data = array();
    11761174
    11771175        // Someday, array_filter()
     
    12091207
    12101208        return $args;
    12111209}
     1210
     1211/**
     1212 * Returns the object subtype for a given object ID of a specific type.
     1213 *
     1214 * @since 4.8.0
     1215 *
     1216 * @param string $object_type Type of object to request metadata for. (e.g. comment, post, term, user)
     1217 * @param int    $object_id   ID of the object to retrieve its subtype.
     1218 * @return string The object subtype or an empty string if unspecified subtype.
     1219 */
     1220function get_object_subtype( $object_type, $object_id ) {
     1221        $object_subtype = '';
     1222
     1223        switch ( $object_type ) {
     1224                case 'post':
     1225                        $post_type = get_post_type( $object_id );
     1226                        if ( $post_type ) {
     1227                                $object_subtype = $post_type;
     1228                        }
     1229                        break;
     1230                case 'term':
     1231                        $term = get_term( $object_id );
     1232                        if ( $term ) {
     1233                                $object_subtype = $term->taxonomy;
     1234                        }
     1235                        break;
     1236                case 'comment':
     1237                        $comment = get_comment( $object_id );
     1238                        if ( $comment ) {
     1239                                $object_subtype = $comment->comment_type;
     1240                        }
     1241                        break;
     1242        }
     1243
     1244        return apply_filters( "get_object_subtype_{$object_type}", $object_subtype, $object_id );
     1245}
  • src/wp-settings.php

     
    159159require( ABSPATH . WPINC . '/class-wp-session-tokens.php' );
    160160require( ABSPATH . WPINC . '/class-wp-user-meta-session-tokens.php' );
    161161require( ABSPATH . WPINC . '/meta.php' );
     162require( ABSPATH . WPINC . '/class-wp-meta-key.php' );
    162163require( ABSPATH . WPINC . '/class-wp-meta-query.php' );
    163164require( ABSPATH . WPINC . '/class-wp-metadata-lazyloader.php' );
    164165require( ABSPATH . WPINC . '/general-template.php' );