[ XREF Home ] [ Index ]

PHP Cross Reference of WordPress Trunk

Provided by Yoast

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


Generated: Wed Jun 1 08:30:02 2011 Cross-referenced by PHPXref 0.7
Provided by Yoast and awesome WordPress Hosting