WordPress.org

Make WordPress Core

Ticket #7540: make-usermeta-work-like-post_meta.diff

File make-usermeta-work-like-post_meta.diff, 8.1 KB (added by misterbisson, 6 years ago)

Patch to make the user meta functions work the same as post meta. Revised against trunk and to incorporate suggestions by Denis-de-Bernardy (and now stripped of some bad characters that snuck in to my earlier patch)

  • user.php

     
    286286// User meta functions 
    287287// 
    288288 
     289// 
     290// User meta functions 
     291// 
     292 
     293 
     294 
    289295/** 
     296 * Add meta data field to a user. 
     297 * 
     298 * 
     299 * @since XXX 
     300 * @uses $wpdb 
     301 * @link http://codex.wordpress.org/Function_Reference/add_user_meta 
     302 * 
     303 * @param int $user_id User ID. 
     304 * @param string $key Metadata name. 
     305 * @param mixed $value Metadata value. 
     306 * @param bool $unique Optional, default is false. Whether the same key should not be added. 
     307 * @return bool False for failure. True for success. 
     308 */ 
     309function add_user_meta($user_id, $meta_key, $meta_value, $unique = false) { 
     310        global $wpdb; 
     311 
     312        // expected_slashed ($meta_key) 
     313        $meta_key = stripslashes($meta_key); 
     314 
     315        if ( $unique && $wpdb->get_var( $wpdb->prepare( "SELECT meta_key FROM $wpdb->usermeta WHERE meta_key = %s AND user_id = %d", $meta_key, $user_id ) ) ) 
     316                return false; 
     317 
     318        $meta_value = maybe_serialize( stripslashes_deep($meta_value) ); 
     319 
     320        $wpdb->insert( $wpdb->usermeta, compact( 'user_id', 'meta_key', 'meta_value' ) ); 
     321 
     322        wp_cache_delete($user_id, 'user_meta'); 
     323 
     324        return true; 
     325} 
     326 
     327/** 
     328 * Remove matching metadata from a user. 
     329 * 
     330 * You can match based on the key, or key and value. Removing based on key and 
     331 * value, will keep from removing duplicate metadata with the same key. It also 
     332 * allows removing all metadata matching key, if needed. 
     333 * 
     334 * @since xxx 
     335 * @uses $wpdb 
     336 * @link http://codex.wordpress.org/Function_Reference/delete_user_meta 
     337 * 
     338 * @param int $user_id User ID 
     339 * @param string $meta_key Metadata name. 
     340 * @param mixed $meta_value Optional. Metadata value. 
     341 * @return bool False for failure. True for success. 
     342 */ 
     343function delete_user_meta($user_id, $meta_key, $meta_value = '') { 
     344        global $wpdb; 
     345 
     346        // expected_slashed ($meta_key, $meta_value) 
     347        $meta_key = stripslashes( $meta_key ); 
     348        $meta_value = maybe_serialize( stripslashes_deep($meta_value) ); 
     349 
     350        if ( empty( $meta_value ) ) 
     351                $meta_id = $wpdb->get_var( $wpdb->prepare( "SELECT umeta_id FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s", $user_id, $meta_key ) ); 
     352        else 
     353                $meta_id = $wpdb->get_var( $wpdb->prepare( "SELECT umeta_id FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s AND meta_value = %s", $user_id, $meta_key, $meta_value ) ); 
     354 
     355        if ( !$meta_id ) 
     356                return false; 
     357 
     358        if ( empty( $meta_value ) ) 
     359                $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s", $user_id, $meta_key ) ); 
     360        else 
     361                $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s AND meta_value = %s", $user_id, $meta_key, $meta_value ) ); 
     362 
     363        wp_cache_delete($user_id, 'user_meta'); 
     364 
     365        return true; 
     366} 
     367 
     368/** 
     369 * Retrieve user meta field for a user. 
     370 * 
     371 * @since xxx 
     372 * @uses $wpdb 
     373 * @link http://codex.wordpress.org/Function_Reference/get_user_meta 
     374 * 
     375 * @param int $user_id User ID. 
     376 * @param string $key The meta key to retrieve. 
     377 * @param bool $single Whether to return a single value. 
     378 * @return mixed Will be an array if $single is false. Will be value of meta data field if $single is true. 
     379 */ 
     380function get_user_meta($user_id, $key, $single = false) { 
     381        $user_id = (int) $user_id; 
     382 
     383        $meta_cache = wp_cache_get($user_id, 'user_meta'); 
     384 
     385        if ( !$meta_cache ) { 
     386                update_usermeta_cache($user_id); 
     387                $meta_cache = wp_cache_get($user_id, 'user_meta'); 
     388        } 
     389 
     390        if ( isset($meta_cache[$key]) ) { 
     391                if ( $single ) { 
     392                        return maybe_unserialize( $meta_cache[$key][0] ); 
     393                } else { 
     394                        return array_map('maybe_unserialize', $meta_cache[$key]); 
     395                } 
     396        } 
     397 
     398        return ''; 
     399} 
     400 
     401/** 
     402 * Update user meta field based on User ID. 
     403 * 
     404 * Use the $prev_value parameter to differentiate between meta fields with the 
     405 * same key and User ID. 
     406 * 
     407 * If the meta field for the user does not exist, it will be added. 
     408 * 
     409 * @since xxx 
     410 * @uses $wpdb 
     411 * @link http://codex.wordpress.org/Function_Reference/update_user_meta 
     412 * 
     413 * @param int $user_id User ID. 
     414 * @param string $key Metadata key. 
     415 * @param mixed $value Metadata value. 
     416 * @param mixed $prev_value Optional. Previous value to check before removing. 
     417 * @return bool False on failure, true if success. 
     418 */ 
     419function update_user_meta($user_id, $meta_key, $meta_value, $prev_value = '') { 
     420        global $wpdb; 
     421 
     422        // expected_slashed ($meta_key) 
     423        $meta_key = stripslashes($meta_key); 
     424 
     425        if ( ! $wpdb->get_var( $wpdb->prepare( "SELECT meta_key FROM $wpdb->usermeta WHERE meta_key = %s AND user_id = %d", $meta_key, $user_id ) ) ) { 
     426                return add_user_meta($user_id, $meta_key, $meta_value); 
     427        } 
     428 
     429        $meta_value = maybe_serialize( stripslashes_deep($meta_value) ); 
     430 
     431        $data  = compact( 'meta_value' ); 
     432        $where = compact( 'meta_key', 'user_id' ); 
     433 
     434        if ( !empty( $prev_value ) ) { 
     435                $prev_value = maybe_serialize($prev_value); 
     436                $where['meta_value'] = $prev_value; 
     437        } 
     438 
     439        $wpdb->update( $wpdb->usermeta, $data, $where ); 
     440        wp_cache_delete($user_id, 'user_meta'); 
     441        return true; 
     442} 
     443 
     444/** 
     445 * Delete everything from user meta matching meta key. 
     446 * 
     447 * @since xxx 
     448 * @uses $wpdb 
     449 * 
     450 * @param string $user_meta_key Key to search for when deleting. 
     451 * @param string $operator The SQL operator. Can be any of LIKE, NOT LIKE, REGEXP, NOT REGEXP 
     452* @return bool Whether the user meta key was deleted from the database 
     453 */ 
     454function delete_user_meta_by_key($user_meta_key, $operator = false) { 
     455        global $wpdb; 
     456        switch ( $operator ) { 
     457                case 'LIKE': 
     458                case 'NOT LIKE': 
     459                case 'REGEXP': 
     460                case 'NOT REGEXP': 
     461                        break; 
     462                default: 
     463                        $operator = 'LIKE'; 
     464        } 
     465 
     466        $user_ids = $wpdb->get_col($wpdb->prepare("SELECT DISTINCT user_id FROM $wpdb->usermeta WHERE meta_key LIKE %s", $user_meta_key)); 
     467 
     468        if ( $user_ids ) { 
     469                $wpdb->query($wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE meta_key LIKE %s", $user_meta_key)); 
     470                        foreach ( $user_ids as $user_id ) 
     471                                wp_cache_delete($user_id, 'user_meta'); 
     472 
     473                return true; 
     474        } 
     475        return false; 
     476} 
     477 
     478/** 
    290479 * Remove user meta data. 
    291480 * 
    292481 * @since 2.0.0 
     
    455644} 
    456645 
    457646/** 
     647 * Updates metadata cache for list of User IDs. 
     648 * 
     649 * Performs SQL query to retrieve the metadata for the User IDs and updates the 
     650 * metadata cache for the users. Therefore, the functions, which call this 
     651 * function, do not need to perform SQL queries on their own. 
     652 * 
     653 * @package WordPress 
     654 * @subpackage Cache 
     655 * @since xxx 
     656 * 
     657 * @uses $wpdb 
     658 * 
     659 * @param array $user_ids List of User IDs. 
     660 * @return bool|array Returns false if there is nothing to update or an array of metadata. 
     661 */ 
     662function update_usermeta_cache($user_ids) { 
     663        global $wpdb; 
     664 
     665        if ( empty( $user_ids ) ) 
     666                return false; 
     667 
     668        if ( !is_array($user_ids) ) { 
     669                $user_ids = preg_replace('|[^0-9,]|', '', $user_ids); 
     670                $user_ids = explode(',', $user_ids); 
     671        } 
     672 
     673        $user_ids = array_map('intval', $user_ids); 
     674 
     675        $ids = array(); 
     676        foreach ( (array) $user_ids as $id ) { 
     677                if ( false === wp_cache_get($id, 'user_meta') ) 
     678                        $ids[] = $id; 
     679        } 
     680 
     681        if ( empty( $ids ) ) 
     682                return false; 
     683 
     684        // Get user-meta info 
     685        $id_list = join(',', $ids); 
     686        $cache = array(); 
     687        if ( $meta_list = $wpdb->get_results("SELECT user_id, meta_key, meta_value FROM $wpdb->usermeta WHERE user_id IN ($id_list)", ARRAY_A) ) { 
     688                foreach ( (array) $meta_list as $metarow) { 
     689                        $mpid = (int) $metarow['user_id']; 
     690                        $mkey = $metarow['meta_key']; 
     691                        $mval = $metarow['meta_value']; 
     692 
     693                        // Force subkeys to be array type: 
     694                        if ( !isset($cache[$mpid]) || !is_array($cache[$mpid]) ) 
     695                                $cache[$mpid] = array(); 
     696                        if ( !isset($cache[$mpid][$mkey]) || !is_array($cache[$mpid][$mkey]) ) 
     697                                $cache[$mpid][$mkey] = array(); 
     698 
     699                        // Add a value to the current pid/key: 
     700                        $cache[$mpid][$mkey][] = $mval; 
     701                } 
     702        } 
     703 
     704        foreach ( (array) $ids as $id ) { 
     705                if ( ! isset($cache[$id]) ) 
     706                        $cache[$id] = array(); 
     707        } 
     708 
     709        foreach ( (array) array_keys($cache) as $user) 
     710                wp_cache_set($user, $cache[$user], 'user_meta'); 
     711 
     712        return $cache; 
     713} 
     714 
     715/** 
    458716 * Create dropdown HTML content of users. 
    459717 * 
    460718 * The content can either be displayed, which it is by default or retrieved by 
     
    599857        wp_cache_add($user->user_email, $user->ID, 'useremail'); 
    600858        wp_cache_add($user->user_nicename, $user->ID, 'userslugs'); 
    601859} 
    602  
    603 ?>