Ticket #38323: 38323.4.diff
File 38323.4.diff, 14.5 KB (added by , 6 years ago) |
---|
-
src/wp-includes/capabilities.php
259 259 list( $_, $object_type, $_ ) = explode( '_', $cap ); 260 260 $object_id = (int) $args[0]; 261 261 262 switch ( $object_type ) { 263 case 'post': 264 $post = get_post( $object_id ); 265 if ( ! $post ) { 266 break; 267 } 268 269 $sub_type = get_post_type( $post ); 270 break; 271 272 case 'comment': 273 $comment = get_comment( $object_id ); 274 if ( ! $comment ) { 275 break; 276 } 277 278 $sub_type = empty( $comment->comment_type ) ? 'comment' : $comment->comment_type; 279 break; 280 281 case 'term': 282 $term = get_term( $object_id ); 283 if ( ! $term instanceof WP_Term ) { 284 break; 285 } 286 287 $sub_type = $term->taxonomy; 288 break; 289 290 case 'user': 291 $user = get_user_by( 'id', $object_id ); 292 if ( ! $user ) { 293 break; 294 } 295 296 $sub_type = 'user'; 297 break; 298 } 262 $sub_type = get_object_subtype( $object_type, $object_id ); 299 263 300 264 if ( empty( $sub_type ) ) { 301 265 $caps[] = 'do_not_allow'; -
src/wp-includes/meta.php
44 44 return false; 45 45 } 46 46 47 $meta_subtype = get_object_subtype( $meta_type, $object_id ); 48 47 49 $column = sanitize_key($meta_type . '_id'); 48 50 49 51 // expected_slashed ($meta_key) 50 52 $meta_key = wp_unslash($meta_key); 51 53 $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 ); 53 55 54 56 /** 55 57 * Filters whether to add metadata of a specific type. … … 157 159 return false; 158 160 } 159 161 162 $meta_subtype = get_object_subtype( $meta_type, $object_id ); 163 160 164 $column = sanitize_key($meta_type . '_id'); 161 165 $id_column = 'user' == $meta_type ? 'umeta_id' : 'meta_id'; 162 166 … … 165 169 $meta_key = wp_unslash($meta_key); 166 170 $passed_value = $meta_value; 167 171 $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 ); 169 173 170 174 /** 171 175 * Filters whether to update metadata of a specific type. … … 640 644 return false; 641 645 } 642 646 647 $meta_subtype = get_object_subtype( $meta_type, $object_id ); 648 643 649 // Sanitize the meta 644 650 $_meta_value = $meta_value; 645 $meta_value = sanitize_meta( $meta_key, $meta_value, $meta_type );651 $meta_value = sanitize_meta( $meta_key, $meta_value, $meta_type, $meta_subtype ); 646 652 $meta_value = maybe_serialize( $meta_value ); 647 653 648 654 // Format the data query arguments. … … 935 941 * Sanitize meta value. 936 942 * 937 943 * @since 3.1.3 944 * @since 5.0.0 The `$object_subtype` parameter was added. 938 945 * 939 946 * @param string $meta_key Meta key. 940 947 * @param mixed $meta_value Meta value to sanitize. … … 942 949 * 943 950 * @return mixed Sanitized $meta_value. 944 951 */ 945 function sanitize_meta( $meta_key, $meta_value, $object_type ) { 952 function sanitize_meta( $meta_key, $meta_value, $object_type, $object_subtype = '' ) { 953 if ( ! empty( $object_subtype ) ) { 954 /** 955 * Filters the sanitization of a specific meta key of a specific meta type and subtype. 956 * 957 * The dynamic portions of the hook name, `$object_type`, `$object_subtype` 958 * and `$meta_key`, refer to the metadata object type (comment, post, term or user), 959 * the object subtype and the meta key value, respectively. 960 * 961 * @since 5.0.0 962 * 963 * @param mixed $meta_value Meta value to sanitize. 964 * @param string $meta_key Meta key. 965 * @param string $object_type Object type. 966 * @param string $object_subtype Object subtype. 967 */ 968 $meta_value = apply_filters( "sanitize_{$object_type}_{$object_subtype}_meta_{$meta_key}", $meta_value, $meta_key, $object_type, $object_subtype ); 969 } 970 946 971 /** 947 972 * Filters the sanitization of a specific meta key of a specific meta type. 948 973 * … … 966 991 * @since 4.6.0 {@link https://core.trac.wordpress.org/ticket/35658 Modified 967 992 * to support an array of data to attach to registered meta keys}. Previous arguments for 968 993 * `$sanitize_callback` and `$auth_callback` have been folded into this array. 994 * @since 5.0.0 The `$object_subtype` argument was added to the arguments array. 969 995 * 970 996 * @param string $object_type Type of object this meta is registered to. 971 997 * @param string $meta_key Meta key to register. 972 998 * @param array $args { 973 999 * Data used to describe the meta key when registered. 974 1000 * 1001 * @type string $object_subtype A subtype; e.g. if the object type is "post", the post type. If left empty, 1002 * the meta key will be registered on the entire object type. Default empty. 975 1003 * @type string $type The type of data associated with this meta key. 976 1004 * Valid values are 'string', 'boolean', 'integer', and 'number'. 977 1005 * @type string $description A description of the data attached to this meta key. … … 994 1022 } 995 1023 996 1024 $defaults = array( 1025 'object_subtype' => '', 997 1026 'type' => 'string', 998 1027 'description' => '', 999 1028 'single' => false, … … 1034 1063 $args = apply_filters( 'register_meta_args', $args, $defaults, $object_type, $meta_key ); 1035 1064 $args = wp_parse_args( $args, $defaults ); 1036 1065 1066 $object_subtype = ! empty( $args['object_subtype'] ) ? $args['object_subtype'] : ''; 1067 1037 1068 // If `auth_callback` is not provided, fall back to `is_protected_meta()`. 1038 1069 if ( empty( $args['auth_callback'] ) ) { 1039 1070 if ( is_protected_meta( $meta_key, $object_type ) ) { … … 1045 1076 1046 1077 // Back-compat: old sanitize and auth callbacks are applied to all of an object type. 1047 1078 if ( is_callable( $args['sanitize_callback'] ) ) { 1048 add_filter( "sanitize_{$object_type}_meta_{$meta_key}", $args['sanitize_callback'], 10, 3 ); 1079 if ( ! empty( $object_subtype ) ) { 1080 add_filter( "sanitize_{$object_type}_{$object_subtype}_meta_{$meta_key}", $args['sanitize_callback'], 10, 4 ); 1081 } else { 1082 add_filter( "sanitize_{$object_type}_meta_{$meta_key}", $args['sanitize_callback'], 10, 3 ); 1083 } 1049 1084 } 1050 1085 1051 1086 if ( is_callable( $args['auth_callback'] ) ) { 1052 add_filter( "auth_{$object_type}_meta_{$meta_key}", $args['auth_callback'], 10, 6 ); 1087 if ( ! empty( $object_subtype ) ) { 1088 add_filter( "auth_{$object_type}_{$object_subtype}_meta_{$meta_key}", $args['auth_callback'], 10, 6 ); 1089 } else { 1090 add_filter( "auth_{$object_type}_meta_{$meta_key}", $args['auth_callback'], 10, 6 ); 1091 } 1053 1092 } 1054 1093 1055 1094 // Global registry only contains meta keys registered with the array of arguments added in 4.6.0. 1056 1095 if ( ! $has_old_auth_cb && ! $has_old_sanitize_cb ) { 1057 $wp_meta_keys[ $object_type ][ $ meta_key ] = $args;1096 $wp_meta_keys[ $object_type ][ $object_subtype ][ $meta_key ] = $args; 1058 1097 1059 1098 return true; 1060 1099 } … … 1066 1105 * Checks if a meta key is registered. 1067 1106 * 1068 1107 * @since 4.6.0 1108 * @since 5.0.0 The `$object_subtype` parameter was added. 1069 1109 * 1070 1110 * @param string $object_type The type of object. 1071 1111 * @param string $meta_key The meta key. 1112 * @param string $object_subtype Optional. The subtype of the object type. 1072 1113 * 1073 1114 * @return bool True if the meta key is registered to the object type. False if not. 1074 1115 */ 1075 function registered_meta_key_exists( $object_type, $meta_key ) {1116 function registered_meta_key_exists( $object_type, $meta_key, $object_subtype = '' ) { 1076 1117 global $wp_meta_keys; 1077 1118 1078 1119 if ( ! is_array( $wp_meta_keys ) ) { … … 1083 1124 return false; 1084 1125 } 1085 1126 1086 if ( isset( $wp_meta_keys[ $object_type ][ $meta_key ] ) ) { 1127 if ( ! isset( $wp_meta_keys[ $object_type ][ $object_subtype ] ) ) { 1128 return false; 1129 } 1130 1131 if ( isset( $wp_meta_keys[ $object_type ][ $object_subtype ][ $meta_key ] ) ) { 1087 1132 return true; 1088 1133 } 1089 1134 … … 1094 1139 * Unregisters a meta key from the list of registered keys. 1095 1140 * 1096 1141 * @since 4.6.0 1142 * @since 5.0.0 The `$object_subtype` parameter was added. 1097 1143 * 1098 * @param string $object_type The type of object. 1099 * @param string $meta_key The meta key. 1144 * @param string $object_type The type of object. 1145 * @param string $meta_key The meta key. 1146 * @param string $object_subtype Optional. The subtype of the object type. 1100 1147 * @return bool True if successful. False if the meta key was not registered. 1101 1148 */ 1102 function unregister_meta_key( $object_type, $meta_key ) {1149 function unregister_meta_key( $object_type, $meta_key, $object_subtype = '' ) { 1103 1150 global $wp_meta_keys; 1104 1151 1105 if ( ! registered_meta_key_exists( $object_type, $meta_key ) ) {1152 if ( ! registered_meta_key_exists( $object_type, $meta_key, $object_subtype ) ) { 1106 1153 return false; 1107 1154 } 1108 1155 1109 $args = $wp_meta_keys[ $object_type ][ $ meta_key ];1156 $args = $wp_meta_keys[ $object_type ][ $object_subtype ][ $meta_key ]; 1110 1157 1111 1158 if ( isset( $args['sanitize_callback'] ) && is_callable( $args['sanitize_callback'] ) ) { 1112 remove_filter( "sanitize_{$object_type}_meta_{$meta_key}", $args['sanitize_callback'] ); 1159 if ( ! empty( $object_subtype ) ) { 1160 remove_filter( "sanitize_{$object_type}_{$object_subtype}_meta_{$meta_key}", $args['sanitize_callback'] ); 1161 } else { 1162 remove_filter( "sanitize_{$object_type}_meta_{$meta_key}", $args['sanitize_callback'] ); 1163 } 1113 1164 } 1114 1165 1115 1166 if ( isset( $args['auth_callback'] ) && is_callable( $args['auth_callback'] ) ) { 1116 remove_filter( "auth_{$object_type}_meta_{$meta_key}", $args['auth_callback'] ); 1167 if ( ! empty( $object_subtype ) ) { 1168 remove_filter( "auth_{$object_type}_{$object_subtype}_meta_{$meta_key}", $args['auth_callback'] ); 1169 } else { 1170 remove_filter( "auth_{$object_type}_meta_{$meta_key}", $args['auth_callback'] ); 1171 } 1117 1172 } 1118 1173 1119 unset( $wp_meta_keys[ $object_type ][ $ meta_key ] );1174 unset( $wp_meta_keys[ $object_type ][ $object_subtype ][ $meta_key ] ); 1120 1175 1121 1176 // Do some clean up 1177 if ( empty( $wp_meta_keys[ $object_type ][ $object_subtype ] ) ) { 1178 unset( $wp_meta_keys[ $object_type ][ $object_subtype ] ); 1179 } 1122 1180 if ( empty( $wp_meta_keys[ $object_type ] ) ) { 1123 1181 unset( $wp_meta_keys[ $object_type ] ); 1124 1182 } … … 1130 1188 * Retrieves a list of registered meta keys for an object type. 1131 1189 * 1132 1190 * @since 4.6.0 1191 * @since 5.0.0 The `$object_subtype` parameter was added. 1133 1192 * 1134 * @param string $object_type The type of object. Post, comment, user, term. 1193 * @param string $object_type The type of object. Post, comment, user, term. 1194 * @param string $object_subtype Optional. The subtype of the object type. 1135 1195 * @return array List of registered meta keys. 1136 1196 */ 1137 function get_registered_meta_keys( $object_type ) {1197 function get_registered_meta_keys( $object_type, $object_subtype = '' ) { 1138 1198 global $wp_meta_keys; 1139 1199 1140 if ( ! is_array( $wp_meta_keys ) || ! isset( $wp_meta_keys[ $object_type ] ) ) {1200 if ( ! is_array( $wp_meta_keys ) || ! isset( $wp_meta_keys[ $object_type ] ) || ! isset( $wp_meta_keys[ $object_type ][ $object_subtype ] ) ) { 1141 1201 return array(); 1142 1202 } 1143 1203 1144 return $wp_meta_keys[ $object_type ] ;1204 return $wp_meta_keys[ $object_type ][ $object_subtype ]; 1145 1205 } 1146 1206 1147 1207 /** 1148 1208 * Retrieves registered metadata for a specified object. 1149 1209 * 1210 * The results include both meta that is registered specifically for the 1211 * object's subtype and meta that is registered for the entire object type. 1212 * 1150 1213 * @since 4.6.0 1151 1214 * 1152 1215 * @param string $object_type Type of object to request metadata for. (e.g. comment, post, term, user) … … 1157 1220 * and values for an object ID if not. 1158 1221 */ 1159 1222 function get_registered_metadata( $object_type, $object_id, $meta_key = '' ) { 1223 $object_subtype = get_object_subtype( $object_type, $object_id ); 1224 1160 1225 if ( ! empty( $meta_key ) ) { 1161 if ( ! registered_meta_key_exists( $object_type, $meta_key ) ) { 1226 if ( ! empty( $object_subtype ) ) { 1227 if ( ! registered_meta_key_exists( $object_type, $meta_key, $object_subtype ) ) { 1228 $object_subtype = ''; 1229 } 1230 } 1231 1232 if ( ! registered_meta_key_exists( $object_type, $meta_key, $object_subtype ) ) { 1162 1233 return false; 1163 1234 } 1164 $meta_keys = get_registered_meta_keys( $object_type ); 1235 1236 $meta_keys = get_registered_meta_keys( $object_type, $object_subtype ); 1165 1237 $meta_key_data = $meta_keys[ $meta_key ]; 1166 1238 1167 1239 $data = get_metadata( $object_type, $object_id, $meta_key, $meta_key_data['single'] ); … … 1171 1243 1172 1244 $data = get_metadata( $object_type, $object_id ); 1173 1245 1174 $meta_keys = get_registered_meta_keys( $object_type );1246 $meta_keys = get_registered_meta_keys( $object_type, '' ); 1175 1247 $registered_data = array(); 1176 1248 1177 1249 // Someday, array_filter() … … 1181 1253 } 1182 1254 } 1183 1255 1256 if ( ! empty( $object_subtype ) ) { 1257 $meta_keys = get_registered_meta_keys( $object_type, $object_subtype ); 1258 1259 foreach ( $meta_keys as $k => $v ) { 1260 if ( isset( $data[ $k ] ) ) { 1261 $registered_data[ $k ] = $data[ $k ]; 1262 } 1263 } 1264 } 1265 1184 1266 return $registered_data; 1185 1267 } 1186 1268 … … 1209 1291 1210 1292 return $args; 1211 1293 } 1294 1295 /** 1296 * Returns the object subtype for a given object ID of a specific type. 1297 * 1298 * @since 5.0.0 1299 * 1300 * @param string $object_type Type of object to request metadata for. (e.g. comment, post, term, user) 1301 * @param int $object_id ID of the object to retrieve its subtype. 1302 * @return string The object subtype or an empty string if unspecified subtype. 1303 */ 1304 function get_object_subtype( $object_type, $object_id ) { 1305 $object_id = (int) $object_type; 1306 $object_subtype = ''; 1307 1308 switch ( $object_type ) { 1309 case 'post': 1310 $post = get_post( $object_id ); 1311 if ( ! $post ) { 1312 break; 1313 } 1314 1315 $object_subtype = get_post_type( $post ); 1316 break; 1317 1318 case 'comment': 1319 $comment = get_comment( $object_id ); 1320 if ( ! $comment ) { 1321 break; 1322 } 1323 1324 $object_subtype = empty( $comment->comment_type ) ? 'comment' : $comment->comment_type; 1325 break; 1326 1327 case 'term': 1328 $term = get_term( $object_id ); 1329 if ( ! $term instanceof WP_Term ) { 1330 break; 1331 } 1332 1333 $object_subtype = $term->taxonomy; 1334 break; 1335 1336 case 'user': 1337 $user = get_user_by( 'id', $object_id ); 1338 if ( ! $user ) { 1339 break; 1340 } 1341 1342 $object_subtype = 'user'; 1343 break; 1344 default: 1345 1346 /** 1347 * Filters the object subtype identifier for a non standard object type. 1348 * 1349 * The dynamic portion of the hook, `$object_type`, refers to the object 1350 * type (post, comment, term, or user). 1351 * 1352 * @since 5.0.0 1353 * 1354 * @param string $object_subtype Empty string to override. 1355 * @param int $object_id ID of the object to get the subtype for. 1356 */ 1357 $object_subtype = apply_filters( "get_object_subtype_{$object_type}", $object_subtype, $object_id ); 1358 } 1359 1360 return $object_subtype; 1361 }