[ Index ]

PHP Cross Reference of BackPress

title

Body

[close]

/includes/ -> class.wp-users.php (source)

   1  <?php
   2  
   3  class WP_Users {
   4      var $db;
   5  
   6  	function WP_Users( &$db ) {
   7          self::__construct( $db );
   8  //        register_shutdown_function( array(&$this, '__destruct') );
   9      }
  10  
  11  	function __construct( &$db ) {
  12          $this->db =& $db;
  13      }
  14  
  15  //    function __destruct() {
  16  //    }
  17  
  18  	function _put_user( $args = null ) {
  19          $defaults = array(
  20              'ID' => false,
  21              'user_login' => '',
  22              'user_nicename' => '',
  23              'user_email' => '',
  24              'user_url' => '',
  25              'user_pass' => false,
  26              'user_registered' => time(),
  27              'display_name' => '',
  28              'user_status' => 0,
  29              'strict_user_login' => true
  30          );
  31  
  32          $fields = array_keys( wp_parse_args( $args ) );
  33          $args = wp_parse_args( $args, $defaults );
  34          unset($defaults['strict_user_login']);
  35  
  36          if ( isset($args['ID']) && $args['ID'] ) {
  37              unset($defaults['ID']);
  38              $fields = array_intersect( $fields, array_keys( $defaults ) );
  39          } else {
  40              $fields = array_keys( $defaults );
  41          }
  42  
  43          extract( $args, EXTR_SKIP );
  44  
  45          $ID = (int) $ID;
  46  
  47          if ( !$ID || in_array( 'user_login', $fields ) ) {
  48              $user_login = $this->sanitize_user( $user_login, $strict_user_login );
  49  
  50              if ( !$user_login )
  51                  return new WP_Error( 'user_login', __('Invalid login name') );
  52              if ( !$ID && $this->get_user( $user_login, array( 'by' => 'login' ) ) )
  53                  return new WP_Error( 'user_login', __('Name already exists') );
  54          }
  55  
  56          if ( !$ID || in_array( 'user_nicename', $fields ) ) {
  57              if ( !$user_nicename = $this->sanitize_nicename( $user_nicename ? $user_nicename : $user_login ) )
  58                  return new WP_Error( 'user_nicename', __('Invalid nicename') );
  59              if ( !$ID && $this->get_user( $user_nicename, array( 'by' => 'nicename' ) ) )
  60                  return new WP_Error( 'user_nicename', __('Nicename already exists') );
  61          }
  62  
  63          if ( !$ID || in_array( 'user_email', $fields ) ) {
  64              if ( !$this->is_email( $user_email ) )
  65                  return new WP_Error( 'user_email', __('Invalid email address') );
  66  
  67              if ( $already_email = $this->get_user( $user_email, array( 'by' => 'email' ) ) ) {
  68                  // if new user, or if multiple users with that email, or if only one user with that email, but it's not the user being updated
  69                  if ( !$ID || is_wp_error( $already_email ) || $already_email->ID != $ID )
  70                      return new WP_Error( 'user_email', __('Email already exists') );
  71              }
  72          }
  73  
  74          if ( !$ID || in_array( 'user_url', $fields ) ) {
  75              $user_url = esc_url( $user_url );
  76          }
  77  
  78          if ( !$ID || in_array( 'user_pass', $fields ) ) {
  79              if ( !$user_pass )
  80                  $user_pass = WP_Pass::generate_password();
  81              $plain_pass = $user_pass;
  82              $user_pass  = WP_Pass::hash_password( $user_pass );
  83          }
  84  
  85          if ( !$ID || in_array( 'user_registered', $fields ) ) {
  86              if ( !is_numeric($user_registered) )
  87                  $user_registered = backpress_gmt_strtotime( $user_registered );
  88  
  89              if ( !$user_registered || $user_registered < 0 )
  90                  return new WP_Error( 'user_registered', __('Invalid registration time') );
  91  
  92              if ( !$user_registered = @gmdate('Y-m-d H:i:s', $user_registered) )
  93                  return new WP_Error( 'user_registered', __('Invalid registration timestamp') );
  94          }
  95  
  96          if ( !$ID || in_array( 'user_display', $fields ) ) {
  97              if ( !$display_name )
  98                  $display_name = $user_login;
  99          }
 100  
 101          $db_return = NULL;
 102          if ( $ID ) {
 103              $db_return = $this->db->update( $this->db->users, compact( $fields ), compact('ID') );
 104          } else {
 105              $db_return = $this->db->insert( $this->db->users, compact( $fields ) );
 106              $ID = $this->db->insert_id;
 107          }
 108  
 109          if ( !$db_return )
 110              return new WP_Error( 'WP_Users::_put_user', __('Query failed') );
 111  
 112          // Cache the result
 113          if ( $ID ) {
 114              wp_cache_delete( $ID, 'users' );
 115              $this->get_user( $ID, array( 'from_cache' => false ) );
 116          }
 117  
 118          $args = compact( array_keys($args) );
 119          $args['plain_pass'] = $plain_pass;
 120  
 121          do_action( __CLASS__ . '::' . __FUNCTION__, $args );
 122  
 123          return $args;
 124      }
 125  
 126  	function new_user( $args = null ) {
 127          $args = wp_parse_args( $args );
 128          $args['ID'] = false;
 129  
 130          $r = $this->_put_user( $args );
 131  
 132          if ( is_wp_error($r) )
 133              return $r;
 134  
 135          do_action( __CLASS__ . '::' . __FUNCTION__, $r, $args );
 136  
 137          return $r;
 138      }
 139  
 140  	function update_user( $ID, $args = null ) {
 141          $args = wp_parse_args( $args );
 142  
 143          $args['output'] = OBJECT;
 144          $user = $this->get_user( $ID, $args );
 145          if ( !$user || is_wp_error( $user ) )
 146              return $user;
 147  
 148          $args['ID'] = $user->ID;
 149  
 150          $r = $this->_put_user( $args );
 151  
 152          if ( is_wp_error($r) )
 153              return $r;
 154  
 155          do_action( __CLASS__ . '::' . __FUNCTION__, $r, $args );
 156  
 157          return $r;
 158      }
 159  
 160      /**
 161       * set_password() - Updates the user's password with a new encrypted one
 162       *
 163       * For integration with other applications, this function can be
 164       * overwritten to instead use the other package password checking
 165       * algorithm.
 166       *
 167       * @since 2.5
 168       * @uses WP_Pass::hash_password() Used to encrypt the user's password before passing to the database
 169       *
 170       * @param string $password The plaintext new user password
 171       * @param int $user_id User ID
 172       */
 173  	function set_password( $password, $user_id ) {
 174          $user = $this->get_user( $user_id );
 175          if ( !$user || is_wp_error( $user ) )
 176              return $user;
 177  
 178          $user_id = $user->ID;
 179          $hash = WP_Pass::hash_password($password);
 180          $this->update_user( $user->ID, array( 'user_pass' => $password ) );
 181      }
 182  
 183      // $user_id can be user ID#, user_login, user_email (by specifying by = email)
 184  	function get_user( $user_id = 0, $args = null ) {
 185          $defaults = array( 'output' => OBJECT, 'by' => false, 'from_cache' => true, 'append_meta' => true );
 186          $args = wp_parse_args( $args, $defaults );
 187          extract( $args, EXTR_SKIP );
 188  
 189          if ( !$user_id ) {
 190              return false;
 191          }
 192  
 193          // Let's just deal with arrays
 194          $user_ids = (array) $user_id;
 195  
 196          if ( !count( $user_ids ) ) {
 197              return false;
 198          }
 199  
 200          // Validate passed ids
 201          $safe_user_ids = array();
 202          foreach ( $user_ids as $_user_id ) {
 203              switch ( $by ) {
 204                  case 'login':
 205                      $safe_user_ids[] = $this->sanitize_user( $_user_id, true );
 206                      break;
 207                  case 'email':
 208                      if ( $this->is_email( $_user_id ) ) {
 209                          $safe_user_ids[] = $_user_id;
 210                      }
 211                      break;
 212                  case 'nicename':
 213                      $safe_user_ids[] = $this->sanitize_nicename( $_user_id );
 214                      break;
 215                  default:
 216                      if ( is_numeric( $_user_id ) ) {
 217                          $safe_user_ids[] = (int) $_user_id;
 218                      } else { // If one $_user_id is non-numerical, treat all $user_ids as user_logins
 219                          $safe_user_ids[] = $this->sanitize_user( $_user_id, true );
 220                          $by = 'login';
 221                      }
 222                      break;
 223              }
 224          }
 225  
 226          // No soup for you!
 227          if ( !count( $safe_user_ids ) ) {
 228              return false;
 229          }
 230  
 231          // Name the cache storing non-existant ids and the SQL field to query by
 232          switch ( $by ) {
 233              case 'login':
 234                  $non_existant_cache = 'userlogins';
 235                  $sql_field = 'user_login';
 236                  break;
 237              case 'email':
 238                  $non_existant_cache = 'useremail';
 239                  $sql_field = 'user_email';
 240                  break;
 241              case 'nicename':
 242                  $non_existant_cache = 'usernicename';
 243                  $sql_field = 'user_nicename';
 244                  break;
 245              default:
 246                  $non_existant_cache = 'users';
 247                  $sql_field = 'ID';
 248                  break;
 249          }
 250          
 251          // Check if the numeric user IDs exist from caches
 252          $cached_users = array();
 253          if ( $from_cache ) {
 254              $existant_user_ids = array();
 255              $maybe_existant_user_ids = array();
 256              
 257              switch ( $by ) {
 258                  case 'login':
 259                  case 'email':
 260                  case 'nicename':
 261                      foreach ( $safe_user_ids as $_safe_user_id ) {
 262                          $ID = wp_cache_get( $_safe_user_id, $non_existant_cache );
 263                          if ( false === $ID ) {
 264                              $maybe_existant_user_ids[] = $_safe_user_id;
 265                          } elseif ( 0 !== $ID ) {
 266                              $existant_user_ids[] = $ID;
 267                          }
 268                      }
 269                      if ( count( $existant_user_ids ) ) {
 270                          // We need to run again using numeric ids
 271                          $args['by'] = false;
 272                          $cached_users = $this->get_user( $existant_user_ids, $args );
 273                      }
 274                      break;
 275                  default:
 276                      foreach ( $safe_user_ids as $_safe_user_id ) {
 277                          $user = wp_cache_get( $_safe_user_id, 'users' );
 278                          if ( false === $user ) {
 279                              $maybe_existant_user_ids[] = $_safe_user_id;
 280                          } elseif ( 0 !== $user ) {
 281                              $cached_users[] = $user;
 282                          }
 283                      }
 284                      break;
 285              }
 286  
 287              // No maybes? Then it's definite.
 288              if ( !count( $maybe_existant_user_ids ) ) {
 289                  if ( !count( $cached_users ) ) {
 290                      // Nothing there sorry
 291                      return false;
 292                  }
 293  
 294                  // Deal with the case where one record was requested but multiple records are returned
 295                  if ( !is_array( $user_id ) && $user_id ) {
 296                      if ( 1 < count( $cached_users ) ) {
 297                          if ( 'user_email' == $sql_field ) {
 298                              $err = __( 'Multiple email matches.  Log in with your username.' );
 299                          } else {
 300                              $err = sprintf( __( 'Multiple %s matches' ), $sql_field );
 301                          }
 302                          return new WP_Error( $sql_field, $err, $args + array( 'user_id' => $user_id, 'unique' => false ) );
 303                      }
 304  
 305                      // If one item was requested, it expects a single user object back
 306                      $cached_users = array_shift( $cached_users );
 307                  }
 308  
 309                  backpress_convert_object( $cached_users, $output );
 310                  return $cached_users;
 311              }
 312  
 313              // If we get this far, there are some maybes so try and grab them
 314          } else {
 315              $maybe_existant_user_ids = $safe_user_ids;
 316          }
 317  
 318          // Escape the ids for the SQL query
 319          $maybe_existant_user_ids = $this->db->escape_deep( $maybe_existant_user_ids );
 320  
 321          // Sort the ids so the MySQL will more consistently cache the query
 322          sort( $maybe_existant_user_ids );
 323  
 324          // Get the users from the database
 325          $sql = "SELECT * FROM `{$this->db->users}` WHERE `$sql_field` in ('" . join( "','", $maybe_existant_user_ids ) . "');";
 326          $db_users = $this->db->get_results( $sql );
 327  
 328          // Merge in the cached users if available
 329          if ( count( $cached_users ) ) {
 330              // Create a convenient array of database fetched user ids
 331              $db_user_ids = array();
 332              foreach ( $db_users as $_db_user ) {
 333                  $db_user_ids[] = $_db_user->ID;
 334              }
 335              $users = array_merge( $cached_users, $db_users );
 336          } else {
 337              $users = $db_users;
 338          }
 339  
 340          // Deal with the case where one record was requested but multiple records are returned
 341          if ( !is_array( $user_id ) && $user_id ) {
 342              if ( 1 < count( $users ) ) {
 343                  if ( 'user_email' == $sql_field ) {
 344                      $err = __( 'Multiple email matches.  Log in with your username.' );
 345                  } else {
 346                      $err = sprintf( __( 'Multiple %s matches' ), $sql_field );
 347                  }
 348                  return new WP_Error( $sql_field, $err, $args + array( 'user_id' => $user_id, 'unique' => false ) );
 349              }
 350          }
 351  
 352          // Create a convenient array of final user ids
 353          $final_user_ids = array();
 354          foreach ( $users as $_user ) {
 355              $final_user_ids[] = $_user->$sql_field;
 356          }
 357  
 358          foreach ( $safe_user_ids as $_safe_user_id ) {
 359              if ( !in_array( $_safe_user_id, $final_user_ids ) ) {
 360                  wp_cache_add( $_safe_user_id, 0, $non_existant_cache );
 361              }
 362          }
 363  
 364          if ( !count( $users ) ) {
 365              return false;
 366          }
 367  
 368          // Add display names
 369          $final_users = array();
 370          foreach ( $users as $_user ) {
 371              // Make sure there is a display_name set
 372              if ( !$_user->display_name ) {
 373                  $_user->display_name = $_user->user_login;
 374              }
 375  
 376              $final_users[] = $_user;
 377          }
 378  
 379          // append_meta() does the user object, useremail, userlogins caching
 380          if ( $append_meta ) {
 381              if ( count( $cached_users ) ) {
 382                  $db_final_users =array();
 383                  $cached_final_users = array();
 384                  foreach ( $final_users as $final_user ) {
 385                      if ( in_array( $final_user->ID, $db_user_ids ) ) {
 386                          $db_final_users[] = $final_user;
 387                      } else {
 388                          $cached_final_users[] = $final_user;
 389                      }
 390                  }
 391                  $db_final_users = $this->append_meta( $db_final_users );
 392                  $final_users = array_merge( $cached_final_users, $db_final_users );
 393              } else {
 394                  $final_users = $this->append_meta( $final_users );
 395              }
 396          }
 397  
 398          // If one item was requested, it expects a single user object back
 399          if ( !is_array( $user_id ) && $user_id ) {
 400              $final_users = array_shift( $final_users );
 401          }
 402  
 403          backpress_convert_object( $final_users, $output );
 404          return $final_users;
 405      }
 406  
 407  	function delete_user( $user_id ) {
 408          $user = $this->get_user( $user_id );
 409  
 410          if ( !$user || is_wp_error( $user ) )
 411              return $user;
 412  
 413          do_action( 'pre_' . __CLASS__ . '::' . __FUNCTION__, $user->ID );
 414  
 415          $r = $this->db->query( $this->db->prepare( "DELETE FROM {$this->db->users} WHERE ID = %d", $user->ID ) );
 416          $this->db->query( $this->db->prepare( "DELETE FROM {$this->db->usermeta} WHERE user_id = %d", $user->ID ) );
 417  
 418          wp_cache_delete( $user->ID, 'users' );
 419          wp_cache_delete( $user->user_nicename, 'usernicename' );
 420          wp_cache_delete( $user->user_email, 'useremail' );
 421          wp_cache_delete( $user->user_login, 'userlogins' );
 422  
 423          do_action( __CLASS__ . '::' . __FUNCTION__, $user->ID );
 424  
 425          return $r;
 426      }
 427  
 428      // Used for user meta, but can be used for other meta data (such as bbPress' topic meta)
 429      // Should this be in the class or should it be it's own special function?
 430  	function append_meta( $object, $args = null ) {
 431          $defaults = array( 'meta_table' => 'usermeta', 'meta_field' => 'user_id', 'id_field' => 'ID', 'cache_group' => 'users' );
 432          $args = wp_parse_args( $args, $defaults );
 433          extract( $args, EXTR_SKIP );
 434  
 435          if ( is_array($object) ) {
 436              $trans = array();
 437              foreach ( array_keys($object) as $i )
 438                  $trans[$object[$i]->$id_field] =& $object[$i];
 439              $ids = join(',', array_keys($trans));
 440              if ( $ids && $metas = $this->db->get_results("SELECT $meta_field, meta_key, meta_value FROM {$this->db->$meta_table} WHERE $meta_field IN ($ids) /* WP_Users::append_meta */") ) {
 441                  usort( $metas, array(&$this, '_append_meta_sort') );
 442                  foreach ( $metas as $meta ) {
 443                      if ( empty( $meta->meta_key ) )
 444                          continue;
 445                      $trans[$meta->$meta_field]->{$meta->meta_key} = maybe_unserialize( $meta->meta_value );
 446                      if ( strpos($meta->meta_key, $this->db->prefix) === 0 )
 447                          $trans[$meta->$meta_field]->{substr($meta->meta_key, strlen($this->db->prefix))} = maybe_unserialize( $meta->meta_value );
 448                  }
 449              }
 450              foreach ( array_keys($trans) as $i ) {
 451                  wp_cache_set( $i, $trans[$i], $cache_group );
 452                  if ( 'users' == $cache_group ) {
 453                      wp_cache_set( $trans[$i]->user_login, $i, 'userlogins' );
 454                      wp_cache_set( $trans[$i]->user_email, $i, 'useremail' );
 455                      wp_cache_set( $trans[$i]->user_nicename, $i, 'usernicename' );
 456                  }
 457              }
 458              return $object;
 459          } elseif ( $object ) {
 460              if ( $metas = $this->db->get_results("SELECT meta_key, meta_value FROM {$this->db->$meta_table} WHERE $meta_field = '{$object->$id_field}' /* WP_Users::append_meta */") ) {
 461                  usort( $metas, array(&$this, '_append_meta_sort') );
 462                  foreach ( $metas as $meta ) {
 463                      if ( empty( $meta->meta_key ) )
 464                          continue;
 465                      $object->{$meta->meta_key} = maybe_unserialize( $meta->meta_value );
 466                      if ( strpos($meta->meta_key, $this->db->prefix) === 0 )
 467                          $object->{substr($meta->meta_key, strlen($this->db->prefix))} = maybe_unserialize( $meta->meta_value );
 468                  }
 469              }
 470              wp_cache_set( $object->$id_field, $object, $cache_group );
 471              if ( 'users' == $cache_group ) {
 472                  wp_cache_set($object->user_login, $object->ID, 'userlogins');
 473                  wp_cache_set($object->user_email, $object->ID, 'useremail');
 474                  wp_cache_set($object->user_nicename, $object->ID, 'usernicename');
 475              }
 476              return $object;
 477          }
 478      }
 479      
 480      /** 
 481       * _append_meta_sort() - sorts meta keys by length to ensure $appended_object->{$bbdb->prefix}key overwrites $appended_object->key as desired
 482       *
 483       * @internal
 484       */
 485  	function _append_meta_sort( $a, $b ) {
 486          return strlen( $a->meta_key ) - strlen( $b->meta_key );
 487      }
 488  
 489  	function update_meta( $args = null ) {
 490          $defaults = array( 'id' => 0, 'meta_key' => null, 'meta_value' => null, 'meta_table' => 'usermeta', 'meta_field' => 'user_id', 'cache_group' => 'users' );
 491          $args = wp_parse_args( $args, $defaults );
 492          extract( $args, EXTR_SKIP );
 493  
 494          $user = $this->get_user( $id );
 495          if ( !$user || is_wp_error($user) )
 496              return $user;
 497  
 498          $id = (int) $user->ID;
 499  
 500          if ( is_null($meta_key) || is_null($meta_value) )
 501              return false;
 502  
 503          $meta_key = preg_replace('|[^a-z0-9_]|i', '', $meta_key);
 504          if ( 'usermeta' == $meta_table && 'capabilities' == $meta_key )
 505              $meta_key = $this->db->prefix . 'capabilities';
 506  
 507          $meta_tuple = compact('id', 'meta_key', 'meta_value', 'meta_table');
 508          $meta_tuple = apply_filters( __CLASS__ . '::' . __FUNCTION__, $meta_tuple );
 509          extract($meta_tuple, EXTR_OVERWRITE);
 510  
 511          $_meta_value = maybe_serialize( $meta_value );
 512  
 513          $cur = $this->db->get_row( $this->db->prepare( "SELECT * FROM {$this->db->$meta_table} WHERE $meta_field = %d AND meta_key = %s", $id, $meta_key ) );
 514  
 515          if ( !$cur ) {
 516              $this->db->insert( $this->db->$meta_table, array( $meta_field => $id, 'meta_key' => $meta_key, 'meta_value' => $_meta_value ) );
 517          } elseif ( $cur->meta_value != $meta_value ) {
 518              $this->db->update( $this->db->$meta_table, array( 'meta_value' => $_meta_value ), array( $meta_field => $id, 'meta_key' => $meta_key ) );
 519          }
 520  
 521  
 522          wp_cache_delete( $id, $cache_group );
 523  
 524          return true;
 525      }
 526  
 527  	function delete_meta( $args = null ) {
 528          $defaults = array( 'id' => 0, 'meta_key' => null, 'meta_value' => null, 'meta_table' => 'usermeta', 'meta_field' => 'user_id', 'meta_id_field' => 'umeta_id', 'cache_group' => 'users' );
 529          $args = wp_parse_args( $args, $defaults );
 530          extract( $args, EXTR_SKIP );
 531  
 532          $user = $this->get_user( $id );
 533          if ( !$user || is_wp_error($user) )
 534              return $user;
 535  
 536          $id = (int) $id;
 537  
 538          if ( is_null($meta_key) )
 539              return false;
 540  
 541          $meta_key = preg_replace('|[^a-z0-9_]|i', '', $meta_key);
 542  
 543          $meta_tuple = compact('id', 'meta_key', 'meta_value', 'meta_table');
 544          $meta_tuple = apply_filters( __CLASS__ . '::' . __FUNCTION__, $meta_tuple );
 545          extract($meta_tuple, EXTR_OVERWRITE);
 546  
 547          $_meta_value = is_null($meta_value) ? null : maybe_serialize( $meta_value );
 548  
 549          if ( is_null($_meta_value) )
 550              $meta_id = $this->db->get_var( $this->db->prepare( "SELECT $meta_id_field FROM {$this->db->$meta_table} WHERE $meta_field = %d AND meta_key = %s", $id, $meta_key ) );
 551          else
 552              $meta_id = $this->db->get_var( $this->db->prepare( "SELECT $meta_id_field FROM {$this->db->$meta_table} WHERE $meta_field = %d AND meta_key = %s AND meta_value = %s", $id, $meta_key, $_meta_value ) );
 553  
 554          if ( !$meta_id )
 555              return false;
 556  
 557          if ( is_null($_meta_value) )
 558              $this->db->query( $this->db->prepare( "DELETE FROM {$this->db->$meta_table} WHERE $meta_field = %d AND meta_key = %s", $id, $meta_key ) );
 559          else
 560              $this->db->query( $this->db->prepare( "DELETE FROM {$this->db->$meta_table} WHERE $meta_id_field = %d", $meta_id ) );
 561  
 562          wp_cache_delete( $id, $cache_group );
 563  
 564          return true;
 565      }
 566  
 567  	function sanitize_user( $user_login, $strict = false ) {
 568          return sanitize_user( $user_login, $strict );
 569      }
 570  
 571  	function sanitize_nicename( $slug ) {
 572          return sanitize_title( $slug );
 573      }
 574  
 575  	function is_email( $email ) {
 576          return is_email( $email );
 577      }
 578  
 579  }


Generated: Wed Dec 19 01:01:51 2018 Cross-referenced by PHPXref 0.7.1