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, 9 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 ?>