| 941 | | return apply_filters( "sanitize_{$meta_type}_meta_{$meta_key}", $meta_value, $meta_key, $meta_type ); |
| | 947 | $meta_value = apply_filters( "sanitize_{$object_type}_meta_{$meta_key}", $meta_value, $meta_key, $object_type ); |
| | 948 | |
| | 949 | /** |
| | 950 | * Filter the sanitization of a specific meta key of a specific meta object type and subtype. |
| | 951 | * |
| | 952 | * The dynamic portions of the hook name, `$object_type`, `$object_subtype`, and `$meta_key` |
| | 953 | * refer to the metadata object type (comment, post, or user), the subtype of that object type |
| | 954 | * and the meta key value respectively. |
| | 955 | * |
| | 956 | * @since 4.5.0 |
| | 957 | * |
| | 958 | * @param mixed $meta_value Meta value to sanitize. |
| | 959 | * @param string $meta_key Meta key. |
| | 960 | * @param string $object_type Meta type. |
| | 961 | * @param string $object_subtype Subtype of the object type. |
| | 962 | */ |
| | 963 | return apply_filters( "sanitize_{$object_type}_{$object_subtype}_meta_{$meta_key}", $meta_value, $meta_key, $object_type, $object_subtype ); |
| 949 | | * @param string $meta_type Type of meta |
| 950 | | * @param string $meta_key Meta key |
| 951 | | * @param string|array $sanitize_callback A function or method to call when sanitizing the value of $meta_key. |
| 952 | | * @param string|array $auth_callback Optional. A function or method to call when performing edit_post_meta, add_post_meta, and delete_post_meta capability checks. |
| 953 | | */ |
| 954 | | function register_meta( $meta_type, $meta_key, $sanitize_callback, $auth_callback = null ) { |
| 955 | | if ( is_callable( $sanitize_callback ) ) |
| 956 | | add_filter( "sanitize_{$meta_type}_meta_{$meta_key}", $sanitize_callback, 10, 3 ); |
| 957 | | |
| 958 | | if ( empty( $auth_callback ) ) { |
| 959 | | if ( is_protected_meta( $meta_key, $meta_type ) ) |
| 960 | | $auth_callback = '__return_false'; |
| 961 | | else |
| 962 | | $auth_callback = '__return_true'; |
| | 980 | * @type string $sanitize_callback A function or method to call when sanitizing `$meta_key` data. |
| | 981 | * @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. |
| | 982 | * @type bool $show_in_rest Whether data associated with this meta key can be considered public. |
| | 983 | * @type string $type The type of data associated with this meta key. |
| | 984 | * @type string $description A description of the data attached to this meta key. |
| | 985 | * } |
| | 986 | */ |
| | 987 | function register_meta( $object_type, $meta_key, $args ) { |
| | 988 | global $wp_meta_keys; |
| | 989 | |
| | 990 | if ( ! is_array( $wp_meta_keys ) ) { |
| | 991 | $wp_meta_keys = array(); |
| | 992 | } |
| | 993 | |
| | 994 | // @todo validate object type as post, comment, user, term? |
| | 995 | |
| | 996 | // @todo should this be an object similar to post types? |
| | 997 | $args = array( |
| | 998 | 'sanitize_callback' => null, |
| | 999 | 'old_sanitize_callback' => null, |
| | 1000 | 'auth_callback' => null, |
| | 1001 | 'old_auth_callback' => null, |
| | 1002 | 'object_subtype' => '', |
| | 1003 | 'show_in_rest' => false, |
| | 1004 | 'type' => 'string', |
| | 1005 | 'description' => '', |
| | 1006 | ); |
| | 1007 | |
| | 1008 | $passed_args = array_slice( func_get_args(), 2 ); |
| | 1009 | |
| | 1010 | if ( is_callable( $passed_args[0] ) ) { |
| | 1011 | $args['old_sanitize_callback'] = $passed_args[0]; |
| | 1012 | } elseif ( isset( $passed_args[0]['sanitize_callback'] ) ) { |
| | 1013 | $args['sanitize_callback'] = $passed_args[0]['sanitize_callback']; |
| | 1014 | } |
| | 1015 | |
| | 1016 | if ( isset( $passed_args[1] ) && is_callable( $passed_args[1] ) ) { |
| | 1017 | $args['old_auth_callback'] = $passed_args[1]; |
| | 1018 | } elseif ( isset( $passed_args[0]['auth_callback'] ) ) { |
| | 1019 | $args['auth_callback'] = $passed_args[0]['auth_callback']; |
| | 1020 | } |
| | 1021 | |
| | 1022 | // @todo is there more than one condition here? What if show_in_rest is true, but the |
| | 1023 | // user fails authentication. No schema? |
| | 1024 | if ( isset( $passed_args[0]['show_in_rest'] ) && $passed_args[0]['show_in_rest'] ) { |
| | 1025 | $args['show_in_rest'] = true; |
| | 1026 | } |
| | 1027 | |
| | 1028 | if ( isset( $passed_args[0]['type'] ) ) { |
| | 1029 | $args['type'] = $passed_args[0]['type']; |
| | 1030 | } |
| | 1031 | |
| | 1032 | if ( isset( $passed_args[0]['description'] ) ) { |
| | 1033 | $args['description'] = $passed_args[0]['description']; |
| | 1034 | } |
| | 1035 | |
| | 1036 | // @todo validate object sub types to only those objects that support custom object types? |
| | 1037 | if ( isset( $passed_args[0]['object_subtype'] ) ) { |
| | 1038 | $object_subtype = $passed_args[0]['object_subtype']; |
| | 1039 | } else { |
| | 1040 | $object_subtype = $object_type; |
| | 1041 | } |
| | 1042 | |
| | 1043 | $wp_meta_keys[ $object_type ][ $object_subtype ][ $meta_key ] = $args; |
| | 1044 | |
| | 1045 | // This legacy filter will fire for all subtypes of an object type. |
| | 1046 | if ( is_callable( $args['old_sanitize_callback'] ) ) { |
| | 1047 | add_filter( "sanitize_{$object_type}_meta_{$meta_key}", $args['old_sanitize_callback'], 10, 3 ); |
| 965 | | if ( is_callable( $auth_callback ) ) |
| 966 | | add_filter( "auth_{$meta_type}_meta_{$meta_key}", $auth_callback, 10, 6 ); |
| | 1050 | if ( is_callable( $args['sanitize_callback'] ) ) { |
| | 1051 | add_filter( "sanitize_{$object_type}_{$object_subtype}_meta_{$meta_key}", $args['sanitize_callback'], 10, 4 ); |
| | 1052 | } |
| | 1053 | |
| | 1054 | // If neither new or legacy `auth_callback` is provided, fallback to `is_protected_meta()`. |
| | 1055 | if ( empty( $args['auth_callback'] ) && empty( $args['old_auth_callback'] ) ) { |
| | 1056 | if ( is_protected_meta( $meta_key, $object_type ) ) { |
| | 1057 | $args['auth_callback'] = '__return_false'; |
| | 1058 | } else { |
| | 1059 | $args['auth_callback'] = '__return_true'; |
| | 1060 | } |
| | 1061 | } |
| | 1062 | |
| | 1063 | // @todo the only core application of this filter is for the `post` object type. What about users, comments, terms? |
| | 1064 | // The auth here is to edit or add meta, not to view. |
| | 1065 | if ( is_callable( $args['old_auth_callback'] ) ) { |
| | 1066 | add_filter( "auth_{$object_type}_meta_{$meta_key}", $args['old_auth_callback'], 10, 6 ); |
| | 1067 | } |
| | 1068 | |
| | 1069 | // @todo sort above out before going further |
| | 1070 | if ( is_callable( $args['auth_callback'] ) ) { |
| | 1071 | add_filter( "auth_{$object_type}_{$object_subtype}_meta_{$meta_key}", $args['auth_callback'], 10, 7 ); |
| | 1072 | } |
| | 1074 | |
| | 1075 | /** |
| | 1076 | * Check if a meta key is registered. |
| | 1077 | * |
| | 1078 | * @since 4.5.0 |
| | 1079 | * |
| | 1080 | * @param string $object_type |
| | 1081 | * @param string $meta_key |
| | 1082 | * @param string $object_subtype |
| | 1083 | * |
| | 1084 | * @return bool True if the meta key is registered to the object type and subtype. False if not. |
| | 1085 | */ |
| | 1086 | function registered_meta_key_exists( $object_type, $meta_key, $object_subtype = '' ) { |
| | 1087 | global $wp_meta_keys; |
| | 1088 | |
| | 1089 | if ( ! is_array( $wp_meta_keys ) ) { |
| | 1090 | return false; |
| | 1091 | } |
| | 1092 | |
| | 1093 | if ( empty( $object_subtype ) ) { |
| | 1094 | $object_subtype = $object_type; |
| | 1095 | } |
| | 1096 | |
| | 1097 | if ( ! isset( $wp_meta_keys[ $object_type] ) ) { |
| | 1098 | return false; |
| | 1099 | } |
| | 1100 | |
| | 1101 | if ( ! isset( $wp_meta_keys[ $object_type ][ $object_subtype ] ) ) { |
| | 1102 | return false; |
| | 1103 | } |
| | 1104 | |
| | 1105 | if ( isset( $wp_meta_keys[ $object_type][ $object_subtype][ $meta_key ] ) ) { |
| | 1106 | return true; |
| | 1107 | } |
| | 1108 | |
| | 1109 | return false; |
| | 1110 | } |
| | 1111 | |
| | 1112 | /** |
| | 1113 | * Unregister a meta key from the list of registered keys. |
| | 1114 | * |
| | 1115 | * @since 4.5.0 |
| | 1116 | * |
| | 1117 | * @param string $object_type The type of object. |
| | 1118 | * @param string $meta_key The meta key. |
| | 1119 | * @param string $object_subtype Optional. The subtype of the object type. |
| | 1120 | * |
| | 1121 | * @return bool|WP_Error True if successful. WP_Error if the meta key is invalid. |
| | 1122 | */ |
| | 1123 | function unregister_meta_key( $object_type, $meta_key, $object_subtype = '' ) { |
| | 1124 | global $wp_meta_keys; |
| | 1125 | |
| | 1126 | if ( ! registered_meta_key_exists( $object_type, $meta_key, $object_subtype ) ) { |
| | 1127 | return new WP_Error( 'invalid_meta_key', __( 'Invalid meta key' ) ); |
| | 1128 | } |
| | 1129 | |
| | 1130 | if ( empty( $object_subtype ) ) { |
| | 1131 | $object_subtype = $object_type; |
| | 1132 | } |
| | 1133 | |
| | 1134 | unset( $wp_meta_keys[ $object_type ][ $object_subtype ][ $meta_key ] ); |
| | 1135 | |
| | 1136 | return true; |
| | 1137 | } |
| | 1138 | |
| | 1139 | /** |
| | 1140 | * Retrieve a list of registered meta keys for an object type and subtype. |
| | 1141 | * |
| | 1142 | * @since 4.5.0 |
| | 1143 | * |
| | 1144 | * @param string $object_type The type of object. Post, comment, user, term. |
| | 1145 | * @param string $object_subtype A subtype of the object. |
| | 1146 | * |
| | 1147 | * @return array List of registered meta keys. |
| | 1148 | */ |
| | 1149 | function get_registered_meta_keys( $object_type = 'post', $object_subtype = '' ) { |
| | 1150 | global $wp_meta_keys; |
| | 1151 | |
| | 1152 | if ( ! isset( $wp_meta_keys[ $object_type ] ) ) { |
| | 1153 | return array(); |
| | 1154 | } |
| | 1155 | |
| | 1156 | if ( empty( $object_subtype ) ) { |
| | 1157 | $object_subtype = $object_type; |
| | 1158 | } |
| | 1159 | |
| | 1160 | if ( ! isset( $wp_meta_keys[ $object_subtype ] ) ) { |
| | 1161 | return array(); |
| | 1162 | } |
| | 1163 | |
| | 1164 | return $wp_meta_keys[ $object_type ][ $object_subtype ]; |
| | 1165 | } |
| | 1166 | |
| | 1167 | /** |
| | 1168 | * Retrieve registered metadata for a specified object. |
| | 1169 | * |
| | 1170 | * @since 4.5.0 |
| | 1171 | * |
| | 1172 | * @param string $object_type Type of object to request metadata for. (e.g. comment, post, term, user) |
| | 1173 | * @param int $object_id ID of the object the metadata is for. |
| | 1174 | * @param string $meta_key Optional. Registered metadata key. If not specified, retrieve all registered |
| | 1175 | * metadata for the specified object. |
| | 1176 | * @param bool $single Optional. If true, return only the first value associated |
| | 1177 | * with the specified meta key. If false, return an array of values. Default false. |
| | 1178 | * @param string $object_subtype The subtype of the object's type to request metadata for. (e.g. custom post type) |
| | 1179 | * |
| | 1180 | * @return mixed|WP_Error |
| | 1181 | */ |
| | 1182 | function get_registered_metadata( $object_type = 'post', $object_id, $meta_key = '', $single = false, $object_subtype = '' ) { |
| | 1183 | global $wp_meta_keys; |
| | 1184 | |
| | 1185 | if ( ! is_array( $wp_meta_keys ) ) { |
| | 1186 | return new WP_Error( 'invalid_meta_key', __( 'Invalid meta key. Not registered.' ) ); |
| | 1187 | } |
| | 1188 | |
| | 1189 | if ( empty( $object_subtype ) ) { |
| | 1190 | $object_subtype = $object_type; |
| | 1191 | } |
| | 1192 | |
| | 1193 | if ( ! empty( $meta_key ) && ! registered_meta_key_exists( $object_type, $meta_key, $object_subtype ) ) { |
| | 1194 | return new WP_Error( 'invalid_meta_key', __( 'Invalid meta key. Not registered.' ) ); |
| | 1195 | } |
| | 1196 | |
| | 1197 | if ( 'post' === $object_type && $object_subtype !== get_post_type( $object_id ) ) { |
| | 1198 | return new WP_Error( 'invalid_meta_key', __( 'Invalid meta key. Not registered for this subtype.' ) ); |
| | 1199 | } |
| | 1200 | |
| | 1201 | $data = get_metadata( $object_type, $object_id, $meta_key, $single ); |
| | 1202 | |
| | 1203 | // If a meta key was specified, return the value associated with that key. |
| | 1204 | if ( ! empty( $meta_key ) ) { |
| | 1205 | return $data; |
| | 1206 | } |
| | 1207 | |
| | 1208 | $meta_keys = get_registered_meta_keys( $object_type, $object_subtype ); |
| | 1209 | $registered_data = array(); |
| | 1210 | |
| | 1211 | foreach( $meta_keys as $k => $v ) { |
| | 1212 | if ( isset( $data[ $k ] ) ) { |
| | 1213 | $registered_data[ $k ] = $data[ $k ]; |
| | 1214 | } |
| | 1215 | } |
| | 1216 | |
| | 1217 | return $registered_data; |
| | 1218 | } |
| | 1219 | No newline at end of file |