[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-includes/ -> user.php (source)

   1  <?php
   2  /**
   3   * WordPress User API
   4   *
   5   * @package WordPress
   6   */
   7  
   8  /**
   9   * Authenticate user with remember capability.
  10   *
  11   * The credentials is an array that has 'user_login', 'user_password', and
  12   * 'remember' indices. If the credentials is not given, then the log in form
  13   * will be assumed and used if set.
  14   *
  15   * The various authentication cookies will be set by this function and will be
  16   * set for a longer period depending on if the 'remember' credential is set to
  17   * true.
  18   *
  19   * @since 2.5.0
  20   *
  21   * @param array $credentials Optional. User info in order to sign on.
  22   * @param bool $secure_cookie Optional. Whether to use secure cookie.
  23   * @return object Either WP_Error on failure, or WP_User on success.
  24   */
  25  function wp_signon( $credentials = '', $secure_cookie = '' ) {
  26      if ( empty($credentials) ) {
  27          if ( ! empty($_POST['log']) )
  28              $credentials['user_login'] = $_POST['log'];
  29          if ( ! empty($_POST['pwd']) )
  30              $credentials['user_password'] = $_POST['pwd'];
  31          if ( ! empty($_POST['rememberme']) )
  32              $credentials['remember'] = $_POST['rememberme'];
  33      }
  34  
  35      if ( !empty($credentials['remember']) )
  36          $credentials['remember'] = true;
  37      else
  38          $credentials['remember'] = false;
  39  
  40      // TODO do we deprecate the wp_authentication action?
  41      do_action_ref_array('wp_authenticate', array(&$credentials['user_login'], &$credentials['user_password']));
  42  
  43      if ( '' === $secure_cookie )
  44          $secure_cookie = is_ssl();
  45  
  46      $secure_cookie = apply_filters('secure_signon_cookie', $secure_cookie, $credentials);
  47  
  48      global $auth_secure_cookie; // XXX ugly hack to pass this to wp_authenticate_cookie
  49      $auth_secure_cookie = $secure_cookie;
  50  
  51      add_filter('authenticate', 'wp_authenticate_cookie', 30, 3);
  52  
  53      $user = wp_authenticate($credentials['user_login'], $credentials['user_password']);
  54  
  55      if ( is_wp_error($user) ) {
  56          if ( $user->get_error_codes() == array('empty_username', 'empty_password') ) {
  57              $user = new WP_Error('', '');
  58          }
  59  
  60          return $user;
  61      }
  62  
  63      wp_set_auth_cookie($user->ID, $credentials['remember'], $secure_cookie);
  64      do_action('wp_login', $user->user_login, $user);
  65      return $user;
  66  }
  67  
  68  /**
  69   * Authenticate the user using the username and password.
  70   */
  71  add_filter('authenticate', 'wp_authenticate_username_password', 20, 3);
  72  function wp_authenticate_username_password($user, $username, $password) {
  73      if ( is_a($user, 'WP_User') ) { return $user; }
  74  
  75      if ( empty($username) || empty($password) ) {
  76          $error = new WP_Error();
  77  
  78          if ( empty($username) )
  79              $error->add('empty_username', __('<strong>ERROR</strong>: The username field is empty.'));
  80  
  81          if ( empty($password) )
  82              $error->add('empty_password', __('<strong>ERROR</strong>: The password field is empty.'));
  83  
  84          return $error;
  85      }
  86  
  87      $userdata = get_user_by('login', $username);
  88  
  89      if ( !$userdata )
  90          return new WP_Error('invalid_username', sprintf(__('<strong>ERROR</strong>: Invalid username. <a href="%s" title="Password Lost and Found">Lost your password</a>?'), wp_lostpassword_url()));
  91  
  92      if ( is_multisite() ) {
  93          // Is user marked as spam?
  94          if ( 1 == $userdata->spam)
  95              return new WP_Error('invalid_username', __('<strong>ERROR</strong>: Your account has been marked as a spammer.'));
  96  
  97          // Is a user's blog marked as spam?
  98          if ( !is_super_admin( $userdata->ID ) && isset($userdata->primary_blog) ) {
  99              $details = get_blog_details( $userdata->primary_blog );
 100              if ( is_object( $details ) && $details->spam == 1 )
 101                  return new WP_Error('blog_suspended', __('Site Suspended.'));
 102          }
 103      }
 104  
 105      $userdata = apply_filters('wp_authenticate_user', $userdata, $password);
 106      if ( is_wp_error($userdata) )
 107          return $userdata;
 108  
 109      if ( !wp_check_password($password, $userdata->user_pass, $userdata->ID) )
 110          return new WP_Error( 'incorrect_password', sprintf( __( '<strong>ERROR</strong>: The password you entered for the username <strong>%1$s</strong> is incorrect. <a href="%2$s" title="Password Lost and Found">Lost your password</a>?' ),
 111          $username, wp_lostpassword_url() ) );
 112  
 113      $user =  new WP_User($userdata->ID);
 114      return $user;
 115  }
 116  
 117  /**
 118   * Authenticate the user using the WordPress auth cookie.
 119   */
 120  function wp_authenticate_cookie($user, $username, $password) {
 121      if ( is_a($user, 'WP_User') ) { return $user; }
 122  
 123      if ( empty($username) && empty($password) ) {
 124          $user_id = wp_validate_auth_cookie();
 125          if ( $user_id )
 126              return new WP_User($user_id);
 127  
 128          global $auth_secure_cookie;
 129  
 130          if ( $auth_secure_cookie )
 131              $auth_cookie = SECURE_AUTH_COOKIE;
 132          else
 133              $auth_cookie = AUTH_COOKIE;
 134  
 135          if ( !empty($_COOKIE[$auth_cookie]) )
 136              return new WP_Error('expired_session', __('Please log in again.'));
 137  
 138          // If the cookie is not set, be silent.
 139      }
 140  
 141      return $user;
 142  }
 143  
 144  /**
 145   * Number of posts user has written.
 146   *
 147   * @since 3.0.0
 148   * @uses $wpdb WordPress database object for queries.
 149   *
 150   * @param int $userid User ID.
 151   * @return int Amount of posts user has written.
 152   */
 153  function count_user_posts($userid) {
 154      global $wpdb;
 155  
 156      $where = get_posts_by_author_sql('post', true, $userid);
 157  
 158      $count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->posts $where" );
 159  
 160      return apply_filters('get_usernumposts', $count, $userid);
 161  }
 162  
 163  /**
 164   * Number of posts written by a list of users.
 165   *
 166   * @since 3.0.0
 167   *
 168   * @param array $users Array of user IDs.
 169   * @param string|array $post_type Optional. Post type to check. Defaults to post.
 170   * @return array Amount of posts each user has written.
 171   */
 172  function count_many_users_posts( $users, $post_type = 'post' ) {
 173      global $wpdb;
 174  
 175      $count = array();
 176      if ( empty( $users ) || ! is_array( $users ) )
 177          return $count;
 178  
 179      $userlist = implode( ',', array_map( 'absint', $users ) );
 180      $where = get_posts_by_author_sql( $post_type );
 181  
 182      $result = $wpdb->get_results( "SELECT post_author, COUNT(*) FROM $wpdb->posts $where AND post_author IN ($userlist) GROUP BY post_author", ARRAY_N );
 183      foreach ( $result as $row ) {
 184          $count[ $row[0] ] = $row[1];
 185      }
 186  
 187      foreach ( $users as $id ) {
 188          if ( ! isset( $count[ $id ] ) )
 189              $count[ $id ] = 0;
 190      }
 191  
 192      return $count;
 193  }
 194  
 195  /**
 196   * Check that the user login name and password is correct.
 197   *
 198   * @since 0.71
 199   * @todo xmlrpc only. Maybe move to xmlrpc.php.
 200   *
 201   * @param string $user_login User name.
 202   * @param string $user_pass User password.
 203   * @return bool False if does not authenticate, true if username and password authenticates.
 204   */
 205  function user_pass_ok($user_login, $user_pass) {
 206      $user = wp_authenticate($user_login, $user_pass);
 207      if ( is_wp_error($user) )
 208          return false;
 209  
 210      return true;
 211  }
 212  
 213  //
 214  // User option functions
 215  //
 216  
 217  /**
 218   * Get the current user's ID
 219   *
 220   * @since MU
 221   *
 222   * @uses wp_get_current_user
 223   *
 224   * @return int The current user's ID
 225   */
 226  function get_current_user_id() {
 227      $user = wp_get_current_user();
 228      return ( isset( $user->ID ) ? (int) $user->ID : 0 );
 229  }
 230  
 231  /**
 232   * Retrieve user option that can be either per Site or per Network.
 233   *
 234   * If the user ID is not given, then the current user will be used instead. If
 235   * the user ID is given, then the user data will be retrieved. The filter for
 236   * the result, will also pass the original option name and finally the user data
 237   * object as the third parameter.
 238   *
 239   * The option will first check for the per site name and then the per Network name.
 240   *
 241   * @since 2.0.0
 242   * @uses $wpdb WordPress database object for queries.
 243   * @uses apply_filters() Calls 'get_user_option_$option' hook with result,
 244   *        option parameter, and user data object.
 245   *
 246   * @param string $option User option name.
 247   * @param int $user Optional. User ID.
 248   * @param bool $deprecated Use get_option() to check for an option in the options table.
 249   * @return mixed
 250   */
 251  function get_user_option( $option, $user = 0, $deprecated = '' ) {
 252      global $wpdb;
 253  
 254      if ( !empty( $deprecated ) )
 255          _deprecated_argument( __FUNCTION__, '3.0' );
 256  
 257      if ( empty( $user ) )
 258          $user = wp_get_current_user();
 259      else
 260          $user = new WP_User( $user );
 261  
 262      if ( ! isset( $user->ID ) )
 263          return false;
 264  
 265      if ( $user->has_prop( $wpdb->prefix . $option ) ) // Blog specific
 266          $result = $user->get( $wpdb->prefix . $option );
 267      elseif ( $user->has_prop( $option ) ) // User specific and cross-blog
 268          $result = $user->get( $option );
 269      else
 270          $result = false;
 271  
 272      return apply_filters("get_user_option_{$option}", $result, $option, $user);
 273  }
 274  
 275  /**
 276   * Update user option with global blog capability.
 277   *
 278   * User options are just like user metadata except that they have support for
 279   * global blog options. If the 'global' parameter is false, which it is by default
 280   * it will prepend the WordPress table prefix to the option name.
 281   *
 282   * Deletes the user option if $newvalue is empty.
 283   *
 284   * @since 2.0.0
 285   * @uses $wpdb WordPress database object for queries
 286   *
 287   * @param int $user_id User ID
 288   * @param string $option_name User option name.
 289   * @param mixed $newvalue User option value.
 290   * @param bool $global Optional. Whether option name is global or blog specific. Default false (blog specific).
 291   * @return unknown
 292   */
 293  function update_user_option( $user_id, $option_name, $newvalue, $global = false ) {
 294      global $wpdb;
 295  
 296      if ( !$global )
 297          $option_name = $wpdb->prefix . $option_name;
 298  
 299      // For backward compatibility. See differences between update_user_meta() and deprecated update_usermeta().
 300      // http://core.trac.wordpress.org/ticket/13088
 301      if ( is_null( $newvalue ) || is_scalar( $newvalue ) && empty( $newvalue ) )
 302          return delete_user_meta( $user_id, $option_name );
 303  
 304      return update_user_meta( $user_id, $option_name, $newvalue );
 305  }
 306  
 307  /**
 308   * Delete user option with global blog capability.
 309   *
 310   * User options are just like user metadata except that they have support for
 311   * global blog options. If the 'global' parameter is false, which it is by default
 312   * it will prepend the WordPress table prefix to the option name.
 313   *
 314   * @since 3.0.0
 315   * @uses $wpdb WordPress database object for queries
 316   *
 317   * @param int $user_id User ID
 318   * @param string $option_name User option name.
 319   * @param bool $global Optional. Whether option name is global or blog specific. Default false (blog specific).
 320   * @return unknown
 321   */
 322  function delete_user_option( $user_id, $option_name, $global = false ) {
 323      global $wpdb;
 324  
 325      if ( !$global )
 326          $option_name = $wpdb->prefix . $option_name;
 327      return delete_user_meta( $user_id, $option_name );
 328  }
 329  
 330  /**
 331   * WordPress User Query class.
 332   *
 333   * @since 3.1.0
 334   */
 335  class WP_User_Query {
 336  
 337      /**
 338       * List of found user ids
 339       *
 340       * @since 3.1.0
 341       * @access private
 342       * @var array
 343       */
 344      var $results;
 345  
 346      /**
 347       * Total number of found users for the current query
 348       *
 349       * @since 3.1.0
 350       * @access private
 351       * @var int
 352       */
 353      var $total_users = 0;
 354  
 355      // SQL clauses
 356      var $query_fields;
 357      var $query_from;
 358      var $query_where;
 359      var $query_orderby;
 360      var $query_limit;
 361  
 362      /**
 363       * PHP5 constructor
 364       *
 365       * @since 3.1.0
 366       *
 367       * @param string|array $args The query variables
 368       * @return WP_User_Query
 369       */
 370  	function __construct( $query = null ) {
 371          if ( !empty( $query ) ) {
 372              $this->query_vars = wp_parse_args( $query, array(
 373                  'blog_id' => $GLOBALS['blog_id'],
 374                  'role' => '',
 375                  'meta_key' => '',
 376                  'meta_value' => '',
 377                  'meta_compare' => '',
 378                  'include' => array(),
 379                  'exclude' => array(),
 380                  'search' => '',
 381                  'orderby' => 'login',
 382                  'order' => 'ASC',
 383                  'offset' => '',
 384                  'number' => '',
 385                  'count_total' => true,
 386                  'fields' => 'all',
 387                  'who' => ''
 388              ) );
 389  
 390              $this->prepare_query();
 391              $this->query();
 392          }
 393      }
 394  
 395      /**
 396       * Prepare the query variables
 397       *
 398       * @since 3.1.0
 399       * @access private
 400       */
 401  	function prepare_query() {
 402          global $wpdb;
 403  
 404          $qv = &$this->query_vars;
 405  
 406          if ( is_array( $qv['fields'] ) ) {
 407              $qv['fields'] = array_unique( $qv['fields'] );
 408  
 409              $this->query_fields = array();
 410              foreach ( $qv['fields'] as $field )
 411                  $this->query_fields[] = $wpdb->users . '.' . esc_sql( $field );
 412              $this->query_fields = implode( ',', $this->query_fields );
 413          } elseif ( 'all' == $qv['fields'] ) {
 414              $this->query_fields = "$wpdb->users.*";
 415          } else {
 416              $this->query_fields = "$wpdb->users.ID";
 417          }
 418  
 419          if ( $this->query_vars['count_total'] )
 420              $this->query_fields = 'SQL_CALC_FOUND_ROWS ' . $this->query_fields;
 421  
 422          $this->query_from = "FROM $wpdb->users";
 423          $this->query_where = "WHERE 1=1";
 424  
 425          // sorting
 426          if ( in_array( $qv['orderby'], array('nicename', 'email', 'url', 'registered') ) ) {
 427              $orderby = 'user_' . $qv['orderby'];
 428          } elseif ( in_array( $qv['orderby'], array('user_nicename', 'user_email', 'user_url', 'user_registered') ) ) {
 429              $orderby = $qv['orderby'];
 430          } elseif ( 'name' == $qv['orderby'] || 'display_name' == $qv['orderby'] ) {
 431              $orderby = 'display_name';
 432          } elseif ( 'post_count' == $qv['orderby'] ) {
 433              // todo: avoid the JOIN
 434              $where = get_posts_by_author_sql('post');
 435              $this->query_from .= " LEFT OUTER JOIN (
 436                  SELECT post_author, COUNT(*) as post_count
 437                  FROM $wpdb->posts
 438                  $where
 439                  GROUP BY post_author
 440              ) p ON ({$wpdb->users}.ID = p.post_author)
 441              ";
 442              $orderby = 'post_count';
 443          } elseif ( 'ID' == $qv['orderby'] || 'id' == $qv['orderby'] ) {
 444              $orderby = 'ID';
 445          } else {
 446              $orderby = 'user_login';
 447          }
 448  
 449          $qv['order'] = strtoupper( $qv['order'] );
 450          if ( 'ASC' == $qv['order'] )
 451              $order = 'ASC';
 452          else
 453              $order = 'DESC';
 454          $this->query_orderby = "ORDER BY $orderby $order";
 455  
 456          // limit
 457          if ( $qv['number'] ) {
 458              if ( $qv['offset'] )
 459                  $this->query_limit = $wpdb->prepare("LIMIT %d, %d", $qv['offset'], $qv['number']);
 460              else
 461                  $this->query_limit = $wpdb->prepare("LIMIT %d", $qv['number']);
 462          }
 463  
 464          $search = trim( $qv['search'] );
 465          if ( $search ) {
 466              $leading_wild = ( ltrim($search, '*') != $search );
 467              $trailing_wild = ( rtrim($search, '*') != $search );
 468              if ( $leading_wild && $trailing_wild )
 469                  $wild = 'both';
 470              elseif ( $leading_wild )
 471                  $wild = 'leading';
 472              elseif ( $trailing_wild )
 473                  $wild = 'trailing';
 474              else
 475                  $wild = false;
 476              if ( $wild )
 477                  $search = trim($search, '*');
 478  
 479              if ( false !== strpos( $search, '@') )
 480                  $search_columns = array('user_email');
 481              elseif ( is_numeric($search) )
 482                  $search_columns = array('user_login', 'ID');
 483              elseif ( preg_match('|^https?://|', $search) )
 484                  $search_columns = array('user_url');
 485              else
 486                  $search_columns = array('user_login', 'user_nicename');
 487  
 488              $this->query_where .= $this->get_search_sql( $search, $search_columns, $wild );
 489          }
 490  
 491          $blog_id = absint( $qv['blog_id'] );
 492  
 493          if ( 'authors' == $qv['who'] && $blog_id ) {
 494              $qv['meta_key'] = $wpdb->get_blog_prefix( $blog_id ) . 'user_level';
 495              $qv['meta_value'] = 0;
 496              $qv['meta_compare'] = '!=';
 497              $qv['blog_id'] = $blog_id = 0; // Prevent extra meta query
 498          }
 499  
 500          $role = trim( $qv['role'] );
 501  
 502          if ( $blog_id && ( $role || is_multisite() ) ) {
 503              $cap_meta_query = array();
 504              $cap_meta_query['key'] = $wpdb->get_blog_prefix( $blog_id ) . 'capabilities';
 505  
 506              if ( $role ) {
 507                  $cap_meta_query['value'] = '"' . $role . '"';
 508                  $cap_meta_query['compare'] = 'like';
 509              }
 510  
 511              $qv['meta_query'][] = $cap_meta_query;
 512          }
 513  
 514          $meta_query = new WP_Meta_Query();
 515          $meta_query->parse_query_vars( $qv );
 516  
 517          if ( !empty( $meta_query->queries ) ) {
 518              $clauses = $meta_query->get_sql( 'user', $wpdb->users, 'ID', $this );
 519              $this->query_from .= $clauses['join'];
 520              $this->query_where .= $clauses['where'];
 521  
 522              if ( 'OR' == $meta_query->relation )
 523                  $this->query_fields = 'DISTINCT ' . $this->query_fields;
 524          }
 525  
 526          if ( !empty( $qv['include'] ) ) {
 527              $ids = implode( ',', wp_parse_id_list( $qv['include'] ) );
 528              $this->query_where .= " AND $wpdb->users.ID IN ($ids)";
 529          } elseif ( !empty($qv['exclude']) ) {
 530              $ids = implode( ',', wp_parse_id_list( $qv['exclude'] ) );
 531              $this->query_where .= " AND $wpdb->users.ID NOT IN ($ids)";
 532          }
 533  
 534          do_action_ref_array( 'pre_user_query', array( &$this ) );
 535      }
 536  
 537      /**
 538       * Execute the query, with the current variables
 539       *
 540       * @since 3.1.0
 541       * @access private
 542       */
 543  	function query() {
 544          global $wpdb;
 545  
 546          if ( is_array( $this->query_vars['fields'] ) || 'all' == $this->query_vars['fields'] ) {
 547              $this->results = $wpdb->get_results("SELECT $this->query_fields $this->query_from $this->query_where $this->query_orderby $this->query_limit");
 548          } else {
 549              $this->results = $wpdb->get_col("SELECT $this->query_fields $this->query_from $this->query_where $this->query_orderby $this->query_limit");
 550          }
 551  
 552          if ( $this->query_vars['count_total'] )
 553              $this->total_users = $wpdb->get_var( apply_filters( 'found_users_query', 'SELECT FOUND_ROWS()' ) );
 554  
 555          if ( !$this->results )
 556              return;
 557  
 558          if ( 'all_with_meta' == $this->query_vars['fields'] ) {
 559              cache_users( $this->results );
 560  
 561              $r = array();
 562              foreach ( $this->results as $userid )
 563                  $r[ $userid ] = new WP_User( $userid, '', $this->query_vars['blog_id'] );
 564  
 565              $this->results = $r;
 566          }
 567      }
 568  
 569      /*
 570       * Used internally to generate an SQL string for searching across multiple columns
 571       *
 572       * @access protected
 573       * @since 3.1.0
 574       *
 575       * @param string $string
 576       * @param array $cols
 577       * @param bool $wild Whether to allow wildcard searches. Default is false for Network Admin, true for
 578       *  single site. Single site allows leading and trailing wildcards, Network Admin only trailing.
 579       * @return string
 580       */
 581  	function get_search_sql( $string, $cols, $wild = false ) {
 582          $string = esc_sql( $string );
 583  
 584          $searches = array();
 585          $leading_wild = ( 'leading' == $wild || 'both' == $wild ) ? '%' : '';
 586          $trailing_wild = ( 'trailing' == $wild || 'both' == $wild ) ? '%' : '';
 587          foreach ( $cols as $col ) {
 588              if ( 'ID' == $col )
 589                  $searches[] = "$col = '$string'";
 590              else
 591                  $searches[] = "$col LIKE '$leading_wild" . like_escape($string) . "$trailing_wild'";
 592          }
 593  
 594          return ' AND (' . implode(' OR ', $searches) . ')';
 595      }
 596  
 597      /**
 598       * Return the list of users
 599       *
 600       * @since 3.1.0
 601       * @access public
 602       *
 603       * @return array
 604       */
 605  	function get_results() {
 606          return $this->results;
 607      }
 608  
 609      /**
 610       * Return the total number of users for the current query
 611       *
 612       * @since 3.1.0
 613       * @access public
 614       *
 615       * @return array
 616       */
 617  	function get_total() {
 618          return $this->total_users;
 619      }
 620  }
 621  
 622  /**
 623   * Retrieve list of users matching criteria.
 624   *
 625   * @since 3.1.0
 626   * @uses $wpdb
 627   * @uses WP_User_Query See for default arguments and information.
 628   *
 629   * @param array $args Optional.
 630   * @return array List of users.
 631   */
 632  function get_users( $args = array() ) {
 633  
 634      $args = wp_parse_args( $args );
 635      $args['count_total'] = false;
 636  
 637      $user_search = new WP_User_Query($args);
 638  
 639      return (array) $user_search->get_results();
 640  }
 641  
 642  /**
 643   * Get the blogs a user belongs to.
 644   *
 645   * @since 3.0.0
 646   *
 647   * @param int $user_id User ID
 648   * @param bool $all Whether to retrieve all blogs, or only blogs that are not marked as deleted, archived, or spam.
 649   * @return array A list of the user's blogs. False if the user was not found or an empty array if the user has no blogs.
 650   */
 651  function get_blogs_of_user( $user_id, $all = false ) {
 652      global $wpdb;
 653  
 654      $user_id = (int) $user_id;
 655  
 656      // Logged out users can't have blogs
 657      if ( empty( $user_id ) )
 658          return false;
 659  
 660      $keys = get_user_meta( $user_id );
 661      if ( empty( $keys ) )
 662          return false;
 663  
 664      if ( ! is_multisite() ) {
 665          $blog_id = get_current_blog_id();
 666          $blogs = array( $blog_id => new stdClass );
 667          $blogs[ $blog_id ]->userblog_id = $blog_id;
 668          $blogs[ $blog_id ]->blogname = get_option('blogname');
 669          $blogs[ $blog_id ]->domain = '';
 670          $blogs[ $blog_id ]->path = '';
 671          $blogs[ $blog_id ]->site_id = 1;
 672          $blogs[ $blog_id ]->siteurl = get_option('siteurl');
 673          return $blogs;
 674      }
 675  
 676      $blogs = array();
 677  
 678      if ( isset( $keys[ $wpdb->base_prefix . 'capabilities' ] ) && defined( 'MULTISITE' ) ) {
 679          $blog = get_blog_details( 1 );
 680          if ( $blog && isset( $blog->domain ) && ( $all || ( ! $blog->archived && ! $blog->spam && ! $blog->deleted ) ) ) {
 681              $blogs[ 1 ] = (object) array(
 682                  'userblog_id' => 1,
 683                  'blogname'    => $blog->blogname,
 684                  'domain'      => $blog->domain,
 685                  'path'        => $blog->path,
 686                  'site_id'     => $blog->site_id,
 687                  'siteurl'     => $blog->siteurl,
 688              );
 689          }
 690          unset( $keys[ $wpdb->base_prefix . 'capabilities' ] );
 691      }
 692  
 693      $keys = array_keys( $keys );
 694  
 695      foreach ( $keys as $key ) {
 696          if ( 'capabilities' !== substr( $key, -12 ) )
 697              continue;
 698          if ( $wpdb->base_prefix && 0 !== strpos( $key, $wpdb->base_prefix ) )
 699              continue;
 700          $blog_id = str_replace( array( $wpdb->base_prefix, '_capabilities' ), '', $key );
 701          if ( ! is_numeric( $blog_id ) )
 702              continue;
 703  
 704          $blog_id = (int) $blog_id;
 705          $blog = get_blog_details( $blog_id );
 706          if ( $blog && isset( $blog->domain ) && ( $all || ( ! $blog->archived && ! $blog->spam && ! $blog->deleted ) ) ) {
 707              $blogs[ $blog_id ] = (object) array(
 708                  'userblog_id' => $blog_id,
 709                  'blogname'    => $blog->blogname,
 710                  'domain'      => $blog->domain,
 711                  'path'        => $blog->path,
 712                  'site_id'     => $blog->site_id,
 713                  'siteurl'     => $blog->siteurl,
 714              );
 715          }
 716      }
 717  
 718      return apply_filters( 'get_blogs_of_user', $blogs, $user_id, $all );
 719  }
 720  
 721  /**
 722   * Find out whether a user is a member of a given blog.
 723   *
 724   * @since MU 1.1
 725   * @uses get_blogs_of_user()
 726   *
 727   * @param int $user_id Optional. The unique ID of the user. Defaults to the current user.
 728   * @param int $blog_id Optional. ID of the blog to check. Defaults to the current site.
 729   * @return bool
 730   */
 731  function is_user_member_of_blog( $user_id = 0, $blog_id = 0 ) {
 732      $user_id = (int) $user_id;
 733      $blog_id = (int) $blog_id;
 734  
 735      if ( empty( $user_id ) )
 736          $user_id = get_current_user_id();
 737  
 738      if ( empty( $blog_id ) )
 739          $blog_id = get_current_blog_id();
 740  
 741      $blogs = get_blogs_of_user( $user_id );
 742      if ( is_array( $blogs ) )
 743          return array_key_exists( $blog_id, $blogs );
 744      else
 745          return false;
 746  }
 747  
 748  /**
 749   * Add meta data field to a user.
 750   *
 751   * Post meta data is called "Custom Fields" on the Administration Screens.
 752   *
 753   * @since 3.0.0
 754   * @uses add_metadata()
 755   * @link http://codex.wordpress.org/Function_Reference/add_user_meta
 756   *
 757   * @param int $user_id Post ID.
 758   * @param string $meta_key Metadata name.
 759   * @param mixed $meta_value Metadata value.
 760   * @param bool $unique Optional, default is false. Whether the same key should not be added.
 761   * @return bool False for failure. True for success.
 762   */
 763  function add_user_meta($user_id, $meta_key, $meta_value, $unique = false) {
 764      return add_metadata('user', $user_id, $meta_key, $meta_value, $unique);
 765  }
 766  
 767  /**
 768   * Remove metadata matching criteria from a user.
 769   *
 770   * You can match based on the key, or key and value. Removing based on key and
 771   * value, will keep from removing duplicate metadata with the same key. It also
 772   * allows removing all metadata matching key, if needed.
 773   *
 774   * @since 3.0.0
 775   * @uses delete_metadata()
 776   * @link http://codex.wordpress.org/Function_Reference/delete_user_meta
 777   *
 778   * @param int $user_id user ID
 779   * @param string $meta_key Metadata name.
 780   * @param mixed $meta_value Optional. Metadata value.
 781   * @return bool False for failure. True for success.
 782   */
 783  function delete_user_meta($user_id, $meta_key, $meta_value = '') {
 784      return delete_metadata('user', $user_id, $meta_key, $meta_value);
 785  }
 786  
 787  /**
 788   * Retrieve user meta field for a user.
 789   *
 790   * @since 3.0.0
 791   * @uses get_metadata()
 792   * @link http://codex.wordpress.org/Function_Reference/get_user_meta
 793   *
 794   * @param int $user_id Post ID.
 795   * @param string $key The meta key to retrieve.
 796   * @param bool $single Whether to return a single value.
 797   * @return mixed Will be an array if $single is false. Will be value of meta data field if $single
 798   *  is true.
 799   */
 800  function get_user_meta($user_id, $key = '', $single = false) {
 801      return get_metadata('user', $user_id, $key, $single);
 802  }
 803  
 804  /**
 805   * Update user meta field based on user ID.
 806   *
 807   * Use the $prev_value parameter to differentiate between meta fields with the
 808   * same key and user ID.
 809   *
 810   * If the meta field for the user does not exist, it will be added.
 811   *
 812   * @since 3.0.0
 813   * @uses update_metadata
 814   * @link http://codex.wordpress.org/Function_Reference/update_user_meta
 815   *
 816   * @param int $user_id Post ID.
 817   * @param string $meta_key Metadata key.
 818   * @param mixed $meta_value Metadata value.
 819   * @param mixed $prev_value Optional. Previous value to check before removing.
 820   * @return bool False on failure, true if success.
 821   */
 822  function update_user_meta($user_id, $meta_key, $meta_value, $prev_value = '') {
 823      return update_metadata('user', $user_id, $meta_key, $meta_value, $prev_value);
 824  }
 825  
 826  /**
 827   * Count number of users who have each of the user roles.
 828   *
 829   * Assumes there are neither duplicated nor orphaned capabilities meta_values.
 830   * Assumes role names are unique phrases. Same assumption made by WP_User_Query::prepare_query()
 831   * Using $strategy = 'time' this is CPU-intensive and should handle around 10^7 users.
 832   * Using $strategy = 'memory' this is memory-intensive and should handle around 10^5 users, but see WP Bug #12257.
 833   *
 834   * @since 3.0.0
 835   * @param string $strategy 'time' or 'memory'
 836   * @return array Includes a grand total and an array of counts indexed by role strings.
 837   */
 838  function count_users($strategy = 'time') {
 839      global $wpdb, $wp_roles;
 840  
 841      // Initialize
 842      $id = get_current_blog_id();
 843      $blog_prefix = $wpdb->get_blog_prefix($id);
 844      $result = array();
 845  
 846      if ( 'time' == $strategy ) {
 847          global $wp_roles;
 848  
 849          if ( ! isset( $wp_roles ) )
 850              $wp_roles = new WP_Roles();
 851  
 852          $avail_roles = $wp_roles->get_names();
 853  
 854          // Build a CPU-intensive query that will return concise information.
 855          $select_count = array();
 856          foreach ( $avail_roles as $this_role => $name ) {
 857              $select_count[] = "COUNT(NULLIF(`meta_value` LIKE '%\"" . like_escape( $this_role ) . "\"%', false))";
 858          }
 859          $select_count = implode(', ', $select_count);
 860  
 861          // Add the meta_value index to the selection list, then run the query.
 862          $row = $wpdb->get_row( "SELECT $select_count, COUNT(*) FROM $wpdb->usermeta WHERE meta_key = '{$blog_prefix}capabilities'", ARRAY_N );
 863  
 864          // Run the previous loop again to associate results with role names.
 865          $col = 0;
 866          $role_counts = array();
 867          foreach ( $avail_roles as $this_role => $name ) {
 868              $count = (int) $row[$col++];
 869              if ($count > 0) {
 870                  $role_counts[$this_role] = $count;
 871              }
 872          }
 873  
 874          // Get the meta_value index from the end of the result set.
 875          $total_users = (int) $row[$col];
 876  
 877          $result['total_users'] = $total_users;
 878          $result['avail_roles'] =& $role_counts;
 879      } else {
 880          $avail_roles = array();
 881  
 882          $users_of_blog = $wpdb->get_col( "SELECT meta_value FROM $wpdb->usermeta WHERE meta_key = '{$blog_prefix}capabilities'" );
 883  
 884          foreach ( $users_of_blog as $caps_meta ) {
 885              $b_roles = unserialize($caps_meta);
 886              if ( is_array($b_roles) ) {
 887                  foreach ( $b_roles as $b_role => $val ) {
 888                      if ( isset($avail_roles[$b_role]) ) {
 889                          $avail_roles[$b_role]++;
 890                      } else {
 891                          $avail_roles[$b_role] = 1;
 892                      }
 893                  }
 894              }
 895          }
 896  
 897          $result['total_users'] = count( $users_of_blog );
 898          $result['avail_roles'] =& $avail_roles;
 899      }
 900  
 901      return $result;
 902  }
 903  
 904  //
 905  // Private helper functions
 906  //
 907  
 908  /**
 909   * Set up global user vars.
 910   *
 911   * Used by wp_set_current_user() for back compat. Might be deprecated in the future.
 912   *
 913   * @since 2.0.4
 914   * @global string $userdata User description.
 915   * @global string $user_login The user username for logging in
 916   * @global int $user_level The level of the user
 917   * @global int $user_ID The ID of the user
 918   * @global string $user_email The email address of the user
 919   * @global string $user_url The url in the user's profile
 920   * @global string $user_pass_md5 MD5 of the user's password
 921   * @global string $user_identity The display name of the user
 922   *
 923   * @param int $for_user_id Optional. User ID to set up global data.
 924   */
 925  function setup_userdata($for_user_id = '') {
 926      global $user_login, $userdata, $user_level, $user_ID, $user_email, $user_url, $user_pass_md5, $user_identity;
 927  
 928      if ( '' == $for_user_id )
 929          $user = wp_get_current_user();
 930      else
 931          $user = new WP_User($for_user_id);
 932  
 933      $userdata   = $user;
 934      $user_ID    = (int) $user->ID;
 935      $user_level = (int) isset($user->user_level) ? $user->user_level : 0;
 936  
 937      if ( 0 == $user->ID ) {
 938          $user_login = $user_email = $user_url = $user_pass_md5 = $user_identity = '';
 939          return;
 940      }
 941  
 942      $user_login    = $user->user_login;
 943      $user_email    = $user->user_email;
 944      $user_url    = $user->user_url;
 945      $user_pass_md5    = md5($user->user_pass);
 946      $user_identity    = $user->display_name;
 947  }
 948  
 949  /**
 950   * Create dropdown HTML content of users.
 951   *
 952   * The content can either be displayed, which it is by default or retrieved by
 953   * setting the 'echo' argument. The 'include' and 'exclude' arguments do not
 954   * need to be used; all users will be displayed in that case. Only one can be
 955   * used, either 'include' or 'exclude', but not both.
 956   *
 957   * The available arguments are as follows:
 958   * <ol>
 959   * <li>show_option_all - Text to show all and whether HTML option exists.</li>
 960   * <li>show_option_none - Text for show none and whether HTML option exists.</li>
 961   * <li>hide_if_only_one_author - Don't create the dropdown if there is only one user.</li>
 962   * <li>orderby - SQL order by clause for what order the users appear. Default is 'display_name'.</li>
 963   * <li>order - Default is 'ASC'. Can also be 'DESC'.</li>
 964   * <li>include - User IDs to include.</li>
 965   * <li>exclude - User IDs to exclude.</li>
 966   * <li>multi - Default is 'false'. Whether to skip the ID attribute on the 'select' element. A 'true' value is overridden when id argument is set.</li>
 967   * <li>show - Default is 'display_name'. User table column to display. If the selected item is empty then the user_login will be displayed in parentheses</li>
 968   * <li>echo - Default is '1'. Whether to display or retrieve content.</li>
 969   * <li>selected - Which User ID is selected.</li>
 970   * <li>include_selected - Always include the selected user ID in the dropdown. Default is false.</li>
 971   * <li>name - Default is 'user'. Name attribute of select element.</li>
 972   * <li>id - Default is the value of the 'name' parameter. ID attribute of select element.</li>
 973   * <li>class - Class attribute of select element.</li>
 974   * <li>blog_id - ID of blog (Multisite only). Defaults to ID of current blog.</li>
 975   * <li>who - Which users to query. Currently only 'authors' is supported. Default is all users.</li>
 976   * </ol>
 977   *
 978   * @since 2.3.0
 979   * @uses $wpdb WordPress database object for queries
 980   *
 981   * @param string|array $args Optional. Override defaults.
 982   * @return string|null Null on display. String of HTML content on retrieve.
 983   */
 984  function wp_dropdown_users( $args = '' ) {
 985      $defaults = array(
 986          'show_option_all' => '', 'show_option_none' => '', 'hide_if_only_one_author' => '',
 987          'orderby' => 'display_name', 'order' => 'ASC',
 988          'include' => '', 'exclude' => '', 'multi' => 0,
 989          'show' => 'display_name', 'echo' => 1,
 990          'selected' => 0, 'name' => 'user', 'class' => '', 'id' => '',
 991          'blog_id' => $GLOBALS['blog_id'], 'who' => '', 'include_selected' => false
 992      );
 993  
 994      $defaults['selected'] = is_author() ? get_query_var( 'author' ) : 0;
 995  
 996      $r = wp_parse_args( $args, $defaults );
 997      extract( $r, EXTR_SKIP );
 998  
 999      $query_args = wp_array_slice_assoc( $r, array( 'blog_id', 'include', 'exclude', 'orderby', 'order', 'who' ) );
1000      $query_args['fields'] = array( 'ID', $show );
1001      $users = get_users( $query_args );
1002  
1003      $output = '';
1004      if ( !empty($users) && ( empty($hide_if_only_one_author) || count($users) > 1 ) ) {
1005          $name = esc_attr( $name );
1006          if ( $multi && ! $id )
1007              $id = '';
1008          else
1009              $id = $id ? " id='" . esc_attr( $id ) . "'" : " id='$name'";
1010  
1011          $output = "<select name='{$name}'{$id} class='$class'>\n";
1012  
1013          if ( $show_option_all )
1014              $output .= "\t<option value='0'>$show_option_all</option>\n";
1015  
1016          if ( $show_option_none ) {
1017              $_selected = selected( -1, $selected, false );
1018              $output .= "\t<option value='-1'$_selected>$show_option_none</option>\n";
1019          }
1020  
1021          $found_selected = false;
1022          foreach ( (array) $users as $user ) {
1023              $user->ID = (int) $user->ID;
1024              $_selected = selected( $user->ID, $selected, false );
1025              if ( $_selected )
1026                  $found_selected = true;
1027              $display = !empty($user->$show) ? $user->$show : '('. $user->user_login . ')';
1028              $output .= "\t<option value='$user->ID'$_selected>" . esc_html($display) . "</option>\n";
1029          }
1030  
1031          if ( $include_selected && ! $found_selected && ( $selected > 0 ) ) {
1032              $user = get_userdata( $selected );
1033              $_selected = selected( $user->ID, $selected, false );
1034              $display = !empty($user->$show) ? $user->$show : '('. $user->user_login . ')';
1035              $output .= "\t<option value='$user->ID'$_selected>" . esc_html($display) . "</option>\n";
1036          }
1037  
1038          $output .= "</select>";
1039      }
1040  
1041      $output = apply_filters('wp_dropdown_users', $output);
1042  
1043      if ( $echo )
1044          echo $output;
1045  
1046      return $output;
1047  }
1048  
1049  /**
1050   * Sanitize user field based on context.
1051   *
1052   * Possible context values are:  'raw', 'edit', 'db', 'display', 'attribute' and 'js'. The
1053   * 'display' context is used by default. 'attribute' and 'js' contexts are treated like 'display'
1054   * when calling filters.
1055   *
1056   * @since 2.3.0
1057   * @uses apply_filters() Calls 'edit_$field' and '{$field_no_prefix}_edit_pre' passing $value and
1058   *  $user_id if $context == 'edit' and field name prefix == 'user_'.
1059   *
1060   * @uses apply_filters() Calls 'edit_user_$field' passing $value and $user_id if $context == 'db'.
1061   * @uses apply_filters() Calls 'pre_$field' passing $value if $context == 'db' and field name prefix == 'user_'.
1062   * @uses apply_filters() Calls '{$field}_pre' passing $value if $context == 'db' and field name prefix != 'user_'.
1063   *
1064   * @uses apply_filters() Calls '$field' passing $value, $user_id and $context if $context == anything
1065   *  other than 'raw', 'edit' and 'db' and field name prefix == 'user_'.
1066   * @uses apply_filters() Calls 'user_$field' passing $value if $context == anything other than 'raw',
1067   *  'edit' and 'db' and field name prefix != 'user_'.
1068   *
1069   * @param string $field The user Object field name.
1070   * @param mixed $value The user Object value.
1071   * @param int $user_id user ID.
1072   * @param string $context How to sanitize user fields. Looks for 'raw', 'edit', 'db', 'display',
1073   *               'attribute' and 'js'.
1074   * @return mixed Sanitized value.
1075   */
1076  function sanitize_user_field($field, $value, $user_id, $context) {
1077      $int_fields = array('ID');
1078      if ( in_array($field, $int_fields) )
1079          $value = (int) $value;
1080  
1081      if ( 'raw' == $context )
1082          return $value;
1083  
1084      if ( !is_string($value) && !is_numeric($value) )
1085          return $value;
1086  
1087      $prefixed = false;
1088      if ( false !== strpos($field, 'user_') ) {
1089          $prefixed = true;
1090          $field_no_prefix = str_replace('user_', '', $field);
1091      }
1092  
1093      if ( 'edit' == $context ) {
1094          if ( $prefixed ) {
1095              $value = apply_filters("edit_{$field}", $value, $user_id);
1096          } else {
1097              $value = apply_filters("edit_user_{$field}", $value, $user_id);
1098          }
1099  
1100          if ( 'description' == $field )
1101              $value = esc_html( $value ); // textarea_escaped?
1102          else
1103              $value = esc_attr($value);
1104      } else if ( 'db' == $context ) {
1105          if ( $prefixed ) {
1106              $value = apply_filters("pre_{$field}", $value);
1107          } else {
1108              $value = apply_filters("pre_user_{$field}", $value);
1109          }
1110      } else {
1111          // Use display filters by default.
1112          if ( $prefixed )
1113              $value = apply_filters($field, $value, $user_id, $context);
1114          else
1115              $value = apply_filters("user_{$field}", $value, $user_id, $context);
1116      }
1117  
1118      if ( 'user_url' == $field )
1119          $value = esc_url($value);
1120  
1121      if ( 'attribute' == $context )
1122          $value = esc_attr($value);
1123      else if ( 'js' == $context )
1124          $value = esc_js($value);
1125  
1126      return $value;
1127  }
1128  
1129  /**
1130   * Update all user caches
1131   *
1132   * @since 3.0.0
1133   *
1134   * @param object $user User object to be cached
1135   */
1136  function update_user_caches($user) {
1137      wp_cache_add($user->ID, $user, 'users');
1138      wp_cache_add($user->user_login, $user->ID, 'userlogins');
1139      wp_cache_add($user->user_email, $user->ID, 'useremail');
1140      wp_cache_add($user->user_nicename, $user->ID, 'userslugs');
1141  }
1142  
1143  /**
1144   * Clean all user caches
1145   *
1146   * @since 3.0.0
1147   *
1148   * @param int $id User ID
1149   */
1150  function clean_user_cache($id) {
1151      $user = WP_User::get_data_by( 'id', $id );
1152  
1153      wp_cache_delete($id, 'users');
1154      wp_cache_delete($user->user_login, 'userlogins');
1155      wp_cache_delete($user->user_email, 'useremail');
1156      wp_cache_delete($user->user_nicename, 'userslugs');
1157  }
1158  
1159  /**
1160   * Checks whether the given username exists.
1161   *
1162   * @since 2.0.0
1163   *
1164   * @param string $username Username.
1165   * @return null|int The user's ID on success, and null on failure.
1166   */
1167  function username_exists( $username ) {
1168      if ( $user = get_user_by('login', $username ) ) {
1169          return $user->ID;
1170      } else {
1171          return null;
1172      }
1173  }
1174  
1175  /**
1176   * Checks whether the given email exists.
1177   *
1178   * @since 2.1.0
1179   * @uses $wpdb
1180   *
1181   * @param string $email Email.
1182   * @return bool|int The user's ID on success, and false on failure.
1183   */
1184  function email_exists( $email ) {
1185      if ( $user = get_user_by('email', $email) )
1186          return $user->ID;
1187  
1188      return false;
1189  }
1190  
1191  /**
1192   * Checks whether an username is valid.
1193   *
1194   * @since 2.0.1
1195   * @uses apply_filters() Calls 'validate_username' hook on $valid check and $username as parameters
1196   *
1197   * @param string $username Username.
1198   * @return bool Whether username given is valid
1199   */
1200  function validate_username( $username ) {
1201      $sanitized = sanitize_user( $username, true );
1202      $valid = ( $sanitized == $username );
1203      return apply_filters( 'validate_username', $valid, $username );
1204  }
1205  
1206  /**
1207   * Insert an user into the database.
1208   *
1209   * Can update a current user or insert a new user based on whether the user's ID
1210   * is present.
1211   *
1212   * Can be used to update the user's info (see below), set the user's role, and
1213   * set the user's preference on whether they want the rich editor on.
1214   *
1215   * Most of the $userdata array fields have filters associated with the values.
1216   * The exceptions are 'rich_editing', 'role', 'jabber', 'aim', 'yim',
1217   * 'user_registered', and 'ID'. The filters have the prefix 'pre_user_' followed
1218   * by the field name. An example using 'description' would have the filter
1219   * called, 'pre_user_description' that can be hooked into.
1220   *
1221   * The $userdata array can contain the following fields:
1222   * 'ID' - An integer that will be used for updating an existing user.
1223   * 'user_pass' - A string that contains the plain text password for the user.
1224   * 'user_login' - A string that contains the user's username for logging in.
1225   * 'user_nicename' - A string that contains a nicer looking name for the user.
1226   *        The default is the user's username.
1227   * 'user_url' - A string containing the user's URL for the user's web site.
1228   * 'user_email' - A string containing the user's email address.
1229   * 'display_name' - A string that will be shown on the site. Defaults to user's
1230   *        username. It is likely that you will want to change this, for appearance.
1231   * 'nickname' - The user's nickname, defaults to the user's username.
1232   * 'first_name' - The user's first name.
1233   * 'last_name' - The user's last name.
1234   * 'description' - A string containing content about the user.
1235   * 'rich_editing' - A string for whether to enable the rich editor. False
1236   *        if not empty.
1237   * 'user_registered' - The date the user registered. Format is 'Y-m-d H:i:s'.
1238   * 'role' - A string used to set the user's role.
1239   * 'jabber' - User's Jabber account.
1240   * 'aim' - User's AOL IM account.
1241   * 'yim' - User's Yahoo IM account.
1242   *
1243   * @since 2.0.0
1244   * @uses $wpdb WordPress database layer.
1245   * @uses apply_filters() Calls filters for most of the $userdata fields with the prefix 'pre_user'. See note above.
1246   * @uses do_action() Calls 'profile_update' hook when updating giving the user's ID
1247   * @uses do_action() Calls 'user_register' hook when creating a new user giving the user's ID
1248   *
1249   * @param array $userdata An array of user data.
1250   * @return int|WP_Error The newly created user's ID or a WP_Error object if the user could not be created.
1251   */
1252  function wp_insert_user($userdata) {
1253      global $wpdb;
1254  
1255      extract($userdata, EXTR_SKIP);
1256  
1257      // Are we updating or creating?
1258      if ( !empty($ID) ) {
1259          $ID = (int) $ID;
1260          $update = true;
1261          $old_user_data = WP_User::get_data_by( 'id', $ID );
1262      } else {
1263          $update = false;
1264          // Hash the password
1265          $user_pass = wp_hash_password($user_pass);
1266      }
1267  
1268      $user_login = sanitize_user($user_login, true);
1269      $user_login = apply_filters('pre_user_login', $user_login);
1270  
1271      //Remove any non-printable chars from the login string to see if we have ended up with an empty username
1272      $user_login = trim($user_login);
1273  
1274      if ( empty($user_login) )
1275          return new WP_Error('empty_user_login', __('Cannot create a user with an empty login name.') );
1276  
1277      if ( !$update && username_exists( $user_login ) )
1278          return new WP_Error('existing_user_login', __('This username is already registered.') );
1279  
1280      if ( empty($user_nicename) )
1281          $user_nicename = sanitize_title( $user_login );
1282      $user_nicename = apply_filters('pre_user_nicename', $user_nicename);
1283  
1284      if ( empty($user_url) )
1285          $user_url = '';
1286      $user_url = apply_filters('pre_user_url', $user_url);
1287  
1288      if ( empty($user_email) )
1289          $user_email = '';
1290      $user_email = apply_filters('pre_user_email', $user_email);
1291  
1292      if ( !$update && ! defined( 'WP_IMPORTING' ) && email_exists($user_email) )
1293          return new WP_Error('existing_user_email', __('This email address is already registered.') );
1294  
1295      if ( empty($display_name) )
1296          $display_name = $user_login;
1297      $display_name = apply_filters('pre_user_display_name', $display_name);
1298  
1299      if ( empty($nickname) )
1300          $nickname = $user_login;
1301      $nickname = apply_filters('pre_user_nickname', $nickname);
1302  
1303      if ( empty($first_name) )
1304          $first_name = '';
1305      $first_name = apply_filters('pre_user_first_name', $first_name);
1306  
1307      if ( empty($last_name) )
1308          $last_name = '';
1309      $last_name = apply_filters('pre_user_last_name', $last_name);
1310  
1311      if ( empty($description) )
1312          $description = '';
1313      $description = apply_filters('pre_user_description', $description);
1314  
1315      if ( empty($rich_editing) )
1316          $rich_editing = 'true';
1317  
1318      if ( empty($comment_shortcuts) )
1319          $comment_shortcuts = 'false';
1320  
1321      if ( empty($admin_color) )
1322          $admin_color = 'fresh';
1323      $admin_color = preg_replace('|[^a-z0-9 _.\-@]|i', '', $admin_color);
1324  
1325      if ( empty($use_ssl) )
1326          $use_ssl = 0;
1327  
1328      if ( empty($user_registered) )
1329          $user_registered = gmdate('Y-m-d H:i:s');
1330  
1331      if ( empty($show_admin_bar_front) )
1332          $show_admin_bar_front = 'true';
1333  
1334      $user_nicename_check = $wpdb->get_var( $wpdb->prepare("SELECT ID FROM $wpdb->users WHERE user_nicename = %s AND user_login != %s LIMIT 1" , $user_nicename, $user_login));
1335  
1336      if ( $user_nicename_check ) {
1337          $suffix = 2;
1338          while ($user_nicename_check) {
1339              $alt_user_nicename = $user_nicename . "-$suffix";
1340              $user_nicename_check = $wpdb->get_var( $wpdb->prepare("SELECT ID FROM $wpdb->users WHERE user_nicename = %s AND user_login != %s LIMIT 1" , $alt_user_nicename, $user_login));
1341              $suffix++;
1342          }
1343          $user_nicename = $alt_user_nicename;
1344      }
1345  
1346      $data = compact( 'user_pass', 'user_email', 'user_url', 'user_nicename', 'display_name', 'user_registered' );
1347      $data = stripslashes_deep( $data );
1348  
1349      if ( $update ) {
1350          $wpdb->update( $wpdb->users, $data, compact( 'ID' ) );
1351          $user_id = (int) $ID;
1352      } else {
1353          $wpdb->insert( $wpdb->users, $data + compact( 'user_login' ) );
1354          $user_id = (int) $wpdb->insert_id;
1355      }
1356  
1357      $user = new WP_User( $user_id );
1358  
1359      foreach ( _get_additional_user_keys( $user ) as $key ) {
1360          if ( isset( $$key ) )
1361              update_user_meta( $user_id, $key, $$key );
1362      }
1363  
1364      if ( isset($role) )
1365          $user->set_role($role);
1366      elseif ( !$update )
1367          $user->set_role(get_option('default_role'));
1368  
1369      wp_cache_delete($user_id, 'users');
1370      wp_cache_delete($user_login, 'userlogins');
1371  
1372      if ( $update )
1373          do_action('profile_update', $user_id, $old_user_data);
1374      else
1375          do_action('user_register', $user_id);
1376  
1377      return $user_id;
1378  }
1379  
1380  /**
1381   * Update an user in the database.
1382   *
1383   * It is possible to update a user's password by specifying the 'user_pass'
1384   * value in the $userdata parameter array.
1385   *
1386   * If $userdata does not contain an 'ID' key, then a new user will be created
1387   * and the new user's ID will be returned.
1388   *
1389   * If current user's password is being updated, then the cookies will be
1390   * cleared.
1391   *
1392   * @since 2.0.0
1393   * @see wp_insert_user() For what fields can be set in $userdata
1394   * @uses wp_insert_user() Used to update existing user or add new one if user doesn't exist already
1395   *
1396   * @param array $userdata An array of user data.
1397   * @return int The updated user's ID.
1398   */
1399  function wp_update_user($userdata) {
1400      $ID = (int) $userdata['ID'];
1401  
1402      // First, get all of the original fields
1403      $user_obj = get_userdata( $ID );
1404  
1405      $user = get_object_vars( $user_obj->data );
1406  
1407      // Add additional custom fields
1408      foreach ( _get_additional_user_keys( $user_obj ) as $key ) {
1409          $user[ $key ] = get_user_meta( $ID, $key, true );
1410      }
1411  
1412      // Escape data pulled from DB.
1413      $user = add_magic_quotes( $user );
1414  
1415      // If password is changing, hash it now.
1416      if ( ! empty($userdata['user_pass']) ) {
1417          $plaintext_pass = $userdata['user_pass'];
1418          $userdata['user_pass'] = wp_hash_password($userdata['user_pass']);
1419      }
1420  
1421      wp_cache_delete($user[ 'user_email' ], 'useremail');
1422  
1423      // Merge old and new fields with new fields overwriting old ones.
1424      $userdata = array_merge($user, $userdata);
1425      $user_id = wp_insert_user($userdata);
1426  
1427      // Update the cookies if the password changed.
1428      $current_user = wp_get_current_user();
1429      if ( $current_user->ID == $ID ) {
1430          if ( isset($plaintext_pass) ) {
1431              wp_clear_auth_cookie();
1432              wp_set_auth_cookie($ID);
1433          }
1434      }
1435  
1436      return $user_id;
1437  }
1438  
1439  /**
1440   * A simpler way of inserting an user into the database.
1441   *
1442   * Creates a new user with just the username, password, and email. For more
1443   * complex user creation use wp_insert_user() to specify more information.
1444   *
1445   * @since 2.0.0
1446   * @see wp_insert_user() More complete way to create a new user
1447   *
1448   * @param string $username The user's username.
1449   * @param string $password The user's password.
1450   * @param string $email The user's email (optional).
1451   * @return int The new user's ID.
1452   */
1453  function wp_create_user($username, $password, $email = '') {
1454      $user_login = esc_sql( $username );
1455      $user_email = esc_sql( $email    );
1456      $user_pass = $password;
1457  
1458      $userdata = compact('user_login', 'user_email', 'user_pass');
1459      return wp_insert_user($userdata);
1460  }
1461  
1462  /**
1463   * Return a list of meta keys that wp_insert_user() is supposed to set.
1464   *
1465   * @access private
1466   * @since 3.3.0
1467   *
1468   * @param object $user WP_User instance
1469   * @return array
1470   */
1471  function _get_additional_user_keys( $user ) {
1472      $keys = array( 'first_name', 'last_name', 'nickname', 'description', 'rich_editing', 'comment_shortcuts', 'admin_color', 'use_ssl', 'show_admin_bar_front' );
1473      return array_merge( $keys, array_keys( _wp_get_user_contactmethods( $user ) ) );
1474  }
1475  
1476  /**
1477   * Set up the default contact methods
1478   *
1479   * @access private
1480   * @since
1481   *
1482   * @param object $user User data object (optional)
1483   * @return array $user_contactmethods Array of contact methods and their labels.
1484   */
1485  function _wp_get_user_contactmethods( $user = null ) {
1486      $user_contactmethods = array(
1487          'aim' => __('AIM'),
1488          'yim' => __('Yahoo IM'),
1489          'jabber' => __('Jabber / Google Talk')
1490      );
1491      return apply_filters( 'user_contactmethods', $user_contactmethods, $user );
1492  }


Generated: Tue Feb 7 03:55:55 2012 Hosted by follow the white rabbit.