X-Git-Url: https://scripts.mit.edu/gitweb/autoinstalls/wordpress.git/blobdiff_plain/8f374b7233bc2815ccc387e448d208c5434eb961..53a5df18dd17a11c18781e78349feb3e139096b4:/wp-includes/user.php diff --git a/wp-includes/user.php b/wp-includes/user.php index 6b342c85..a0cb8d81 100644 --- a/wp-includes/user.php +++ b/wp-includes/user.php @@ -73,6 +73,9 @@ function wp_authenticate_username_password($user, $username, $password) { if ( is_a($user, 'WP_User') ) { return $user; } if ( empty($username) || empty($password) ) { + if ( is_wp_error( $user ) ) + return $user; + $error = new WP_Error(); if ( empty($username) ) @@ -84,33 +87,19 @@ function wp_authenticate_username_password($user, $username, $password) { return $error; } - $userdata = get_user_by('login', $username); - - if ( !$userdata ) - return new WP_Error('invalid_username', sprintf(__('ERROR: Invalid username. Lost your password?'), wp_lostpassword_url())); - - if ( is_multisite() ) { - // Is user marked as spam? - if ( 1 == $userdata->spam) - return new WP_Error('invalid_username', __('ERROR: Your account has been marked as a spammer.')); + $user = get_user_by('login', $username); - // Is a user's blog marked as spam? - if ( !is_super_admin( $userdata->ID ) && isset($userdata->primary_blog) ) { - $details = get_blog_details( $userdata->primary_blog ); - if ( is_object( $details ) && $details->spam == 1 ) - return new WP_Error('blog_suspended', __('Site Suspended.')); - } - } + if ( !$user ) + return new WP_Error( 'invalid_username', sprintf( __( 'ERROR: Invalid username. Lost your password?' ), wp_lostpassword_url() ) ); - $userdata = apply_filters('wp_authenticate_user', $userdata, $password); - if ( is_wp_error($userdata) ) - return $userdata; + $user = apply_filters('wp_authenticate_user', $user, $password); + if ( is_wp_error($user) ) + return $user; - if ( !wp_check_password($password, $userdata->user_pass, $userdata->ID) ) + if ( !wp_check_password($password, $user->user_pass, $user->ID) ) return new WP_Error( 'incorrect_password', sprintf( __( 'ERROR: The password you entered for the username %1$s is incorrect. Lost your password?' ), $username, wp_lostpassword_url() ) ); - $user = new WP_User($userdata->ID); return $user; } @@ -141,6 +130,22 @@ function wp_authenticate_cookie($user, $username, $password) { return $user; } +/** + * For multisite blogs, check if the authenticated user has been marked as a + * spammer, or if the user's primary blog has been marked as spam. + * + * @since 3.7.0 + */ +function wp_authenticate_spam_check( $user ) { + if ( $user && is_a( $user, 'WP_User' ) && is_multisite() ) { + $spammed = apply_filters( 'check_is_user_spammed', is_user_spammy(), $user ); + + if ( $spammed ) + return new WP_Error( 'spammer_account', __( 'ERROR: Your account has been marked as a spammer.' ) ); + } + return $user; +} + /** * Number of posts user has written. * @@ -166,10 +171,11 @@ function count_user_posts($userid) { * @since 3.0.0 * * @param array $users Array of user IDs. - * @param string|array $post_type Optional. Post type to check. Defaults to post. + * @param string $post_type Optional. Post type to check. Defaults to post. + * @param bool $public_only Optional. Only return counts for public posts. Defaults to false. * @return array Amount of posts each user has written. */ -function count_many_users_posts( $users, $post_type = 'post' ) { +function count_many_users_posts( $users, $post_type = 'post', $public_only = false ) { global $wpdb; $count = array(); @@ -177,7 +183,7 @@ function count_many_users_posts( $users, $post_type = 'post' ) { return $count; $userlist = implode( ',', array_map( 'absint', $users ) ); - $where = get_posts_by_author_sql( $post_type ); + $where = get_posts_by_author_sql( $post_type, true, null, $public_only ); $result = $wpdb->get_results( "SELECT post_author, COUNT(*) FROM $wpdb->posts $where AND post_author IN ($userlist) GROUP BY post_author", ARRAY_N ); foreach ( $result as $row ) { @@ -192,24 +198,6 @@ function count_many_users_posts( $users, $post_type = 'post' ) { return $count; } -/** - * Check that the user login name and password is correct. - * - * @since 0.71 - * @todo xmlrpc only. Maybe move to xmlrpc.php. - * - * @param string $user_login User name. - * @param string $user_pass User password. - * @return bool False if does not authenticate, true if username and password authenticates. - */ -function user_pass_ok($user_login, $user_pass) { - $user = wp_authenticate($user_login, $user_pass); - if ( is_wp_error($user) ) - return false; - - return true; -} - // // User option functions // @@ -224,6 +212,8 @@ function user_pass_ok($user_login, $user_pass) { * @return int The current user's ID */ function get_current_user_id() { + if ( ! function_exists( 'wp_get_current_user' ) ) + return 0; $user = wp_get_current_user(); return ( isset( $user->ID ) ? (int) $user->ID : 0 ); } @@ -255,15 +245,14 @@ function get_user_option( $option, $user = 0, $deprecated = '' ) { _deprecated_argument( __FUNCTION__, '3.0' ); if ( empty( $user ) ) - $user = wp_get_current_user(); - else - $user = new WP_User( $user ); + $user = get_current_user_id(); - if ( ! $user->exists() ) + if ( ! $user = get_userdata( $user ) ) return false; - if ( $user->has_prop( $wpdb->prefix . $option ) ) // Blog specific - $result = $user->get( $wpdb->prefix . $option ); + $prefix = $wpdb->get_blog_prefix(); + if ( $user->has_prop( $prefix . $option ) ) // Blog specific + $result = $user->get( $prefix . $option ); elseif ( $user->has_prop( $option ) ) // User specific and cross-blog $result = $user->get( $option ); else @@ -294,12 +283,7 @@ function update_user_option( $user_id, $option_name, $newvalue, $global = false global $wpdb; if ( !$global ) - $option_name = $wpdb->prefix . $option_name; - - // For backward compatibility. See differences between update_user_meta() and deprecated update_usermeta(). - // http://core.trac.wordpress.org/ticket/13088 - if ( is_null( $newvalue ) || is_scalar( $newvalue ) && empty( $newvalue ) ) - return delete_user_meta( $user_id, $option_name ); + $option_name = $wpdb->get_blog_prefix() . $option_name; return update_user_meta( $user_id, $option_name, $newvalue ); } @@ -323,7 +307,7 @@ function delete_user_option( $user_id, $option_name, $global = false ) { global $wpdb; if ( !$global ) - $option_name = $wpdb->prefix . $option_name; + $option_name = $wpdb->get_blog_prefix() . $option_name; return delete_user_meta( $user_id, $option_name ); } @@ -334,6 +318,15 @@ function delete_user_option( $user_id, $option_name, $global = false ) { */ class WP_User_Query { + /** + * Query vars, after parsing + * + * @since 3.5.0 + * @access public + * @var array + */ + var $query_vars = array(); + /** * List of found user ids * @@ -402,14 +395,16 @@ class WP_User_Query { function prepare_query() { global $wpdb; - $qv = &$this->query_vars; + $qv =& $this->query_vars; if ( is_array( $qv['fields'] ) ) { $qv['fields'] = array_unique( $qv['fields'] ); $this->query_fields = array(); - foreach ( $qv['fields'] as $field ) - $this->query_fields[] = $wpdb->users . '.' . esc_sql( $field ); + foreach ( $qv['fields'] as $field ) { + $field = 'ID' === $field ? 'ID' : sanitize_key( $field ); + $this->query_fields[] = "$wpdb->users.$field"; + } $this->query_fields = implode( ',', $this->query_fields ); } elseif ( 'all' == $qv['fields'] ) { $this->query_fields = "$wpdb->users.*"; @@ -417,37 +412,44 @@ class WP_User_Query { $this->query_fields = "$wpdb->users.ID"; } - if ( $this->query_vars['count_total'] ) + if ( isset( $qv['count_total'] ) && $qv['count_total'] ) $this->query_fields = 'SQL_CALC_FOUND_ROWS ' . $this->query_fields; $this->query_from = "FROM $wpdb->users"; $this->query_where = "WHERE 1=1"; // sorting - if ( in_array( $qv['orderby'], array('nicename', 'email', 'url', 'registered') ) ) { - $orderby = 'user_' . $qv['orderby']; - } elseif ( in_array( $qv['orderby'], array('user_nicename', 'user_email', 'user_url', 'user_registered') ) ) { - $orderby = $qv['orderby']; - } elseif ( 'name' == $qv['orderby'] || 'display_name' == $qv['orderby'] ) { - $orderby = 'display_name'; - } elseif ( 'post_count' == $qv['orderby'] ) { - // todo: avoid the JOIN - $where = get_posts_by_author_sql('post'); - $this->query_from .= " LEFT OUTER JOIN ( - SELECT post_author, COUNT(*) as post_count - FROM $wpdb->posts - $where - GROUP BY post_author - ) p ON ({$wpdb->users}.ID = p.post_author) - "; - $orderby = 'post_count'; - } elseif ( 'ID' == $qv['orderby'] || 'id' == $qv['orderby'] ) { - $orderby = 'ID'; - } else { - $orderby = 'user_login'; + if ( isset( $qv['orderby'] ) ) { + if ( in_array( $qv['orderby'], array('nicename', 'email', 'url', 'registered') ) ) { + $orderby = 'user_' . $qv['orderby']; + } elseif ( in_array( $qv['orderby'], array('user_nicename', 'user_email', 'user_url', 'user_registered') ) ) { + $orderby = $qv['orderby']; + } elseif ( 'name' == $qv['orderby'] || 'display_name' == $qv['orderby'] ) { + $orderby = 'display_name'; + } elseif ( 'post_count' == $qv['orderby'] ) { + // todo: avoid the JOIN + $where = get_posts_by_author_sql('post'); + $this->query_from .= " LEFT OUTER JOIN ( + SELECT post_author, COUNT(*) as post_count + FROM $wpdb->posts + $where + GROUP BY post_author + ) p ON ({$wpdb->users}.ID = p.post_author) + "; + $orderby = 'post_count'; + } elseif ( 'ID' == $qv['orderby'] || 'id' == $qv['orderby'] ) { + $orderby = 'ID'; + } elseif ( 'meta_value' == $qv['orderby'] ) { + $orderby = "$wpdb->usermeta.meta_value"; + } else { + $orderby = 'user_login'; + } } - $qv['order'] = strtoupper( $qv['order'] ); + if ( empty( $orderby ) ) + $orderby = 'user_login'; + + $qv['order'] = isset( $qv['order'] ) ? strtoupper( $qv['order'] ) : ''; if ( 'ASC' == $qv['order'] ) $order = 'ASC'; else @@ -455,14 +457,17 @@ class WP_User_Query { $this->query_orderby = "ORDER BY $orderby $order"; // limit - if ( $qv['number'] ) { + if ( isset( $qv['number'] ) && $qv['number'] ) { if ( $qv['offset'] ) $this->query_limit = $wpdb->prepare("LIMIT %d, %d", $qv['offset'], $qv['number']); else $this->query_limit = $wpdb->prepare("LIMIT %d", $qv['number']); } - $search = trim( $qv['search'] ); + $search = ''; + if ( isset( $qv['search'] ) ) + $search = trim( $qv['search'] ); + if ( $search ) { $leading_wild = ( ltrim($search, '*') != $search ); $trailing_wild = ( rtrim($search, '*') != $search ); @@ -485,25 +490,31 @@ class WP_User_Query { $search_columns = array('user_email'); elseif ( is_numeric($search) ) $search_columns = array('user_login', 'ID'); - elseif ( preg_match('|^https?://|', $search) && ! wp_is_large_network( 'users' ) ) + elseif ( preg_match('|^https?://|', $search) && ! ( is_multisite() && wp_is_large_network( 'users' ) ) ) $search_columns = array('user_url'); else $search_columns = array('user_login', 'user_nicename'); } + $search_columns = apply_filters( 'user_search_columns', $search_columns, $search, $this ); + $this->query_where .= $this->get_search_sql( $search, $search_columns, $wild ); } - $blog_id = absint( $qv['blog_id'] ); + $blog_id = 0; + if ( isset( $qv['blog_id'] ) ) + $blog_id = absint( $qv['blog_id'] ); - if ( 'authors' == $qv['who'] && $blog_id ) { + if ( isset( $qv['who'] ) && 'authors' == $qv['who'] && $blog_id ) { $qv['meta_key'] = $wpdb->get_blog_prefix( $blog_id ) . 'user_level'; $qv['meta_value'] = 0; $qv['meta_compare'] = '!='; $qv['blog_id'] = $blog_id = 0; // Prevent extra meta query } - $role = trim( $qv['role'] ); + $role = ''; + if ( isset( $qv['role'] ) ) + $role = trim( $qv['role'] ); if ( $blog_id && ( $role || is_multisite() ) ) { $cap_meta_query = array(); @@ -529,10 +540,10 @@ class WP_User_Query { $this->query_fields = 'DISTINCT ' . $this->query_fields; } - if ( !empty( $qv['include'] ) ) { + if ( ! empty( $qv['include'] ) ) { $ids = implode( ',', wp_parse_id_list( $qv['include'] ) ); $this->query_where .= " AND $wpdb->users.ID IN ($ids)"; - } elseif ( !empty($qv['exclude']) ) { + } elseif ( ! empty( $qv['exclude'] ) ) { $ids = implode( ',', wp_parse_id_list( $qv['exclude'] ) ); $this->query_where .= " AND $wpdb->users.ID NOT IN ($ids)"; } @@ -549,29 +560,64 @@ class WP_User_Query { function query() { global $wpdb; - if ( is_array( $this->query_vars['fields'] ) || 'all' == $this->query_vars['fields'] ) { + $qv =& $this->query_vars; + + if ( is_array( $qv['fields'] ) || 'all' == $qv['fields'] ) { $this->results = $wpdb->get_results("SELECT $this->query_fields $this->query_from $this->query_where $this->query_orderby $this->query_limit"); } else { $this->results = $wpdb->get_col("SELECT $this->query_fields $this->query_from $this->query_where $this->query_orderby $this->query_limit"); } - if ( $this->query_vars['count_total'] ) + if ( isset( $qv['count_total'] ) && $qv['count_total'] ) $this->total_users = $wpdb->get_var( apply_filters( 'found_users_query', 'SELECT FOUND_ROWS()' ) ); if ( !$this->results ) return; - if ( 'all_with_meta' == $this->query_vars['fields'] ) { + if ( 'all_with_meta' == $qv['fields'] ) { cache_users( $this->results ); $r = array(); foreach ( $this->results as $userid ) - $r[ $userid ] = new WP_User( $userid, '', $this->query_vars['blog_id'] ); + $r[ $userid ] = new WP_User( $userid, '', $qv['blog_id'] ); $this->results = $r; + } elseif ( 'all' == $qv['fields'] ) { + foreach ( $this->results as $key => $user ) { + $this->results[ $key ] = new WP_User( $user ); + } } } + /** + * Retrieve query variable. + * + * @since 3.5.0 + * @access public + * + * @param string $query_var Query variable key. + * @return mixed + */ + function get( $query_var ) { + if ( isset( $this->query_vars[$query_var] ) ) + return $this->query_vars[$query_var]; + + return null; + } + + /** + * Set query variable. + * + * @since 3.5.0 + * @access public + * + * @param string $query_var Query variable key. + * @param mixed $value Query variable value. + */ + function set( $query_var, $value ) { + $this->query_vars[$query_var] = $value; + } + /* * Used internally to generate an SQL string for searching across multiple columns * @@ -676,6 +722,9 @@ function get_blogs_of_user( $user_id, $all = false ) { $blogs[ $blog_id ]->path = ''; $blogs[ $blog_id ]->site_id = 1; $blogs[ $blog_id ]->siteurl = get_option('siteurl'); + $blogs[ $blog_id ]->archived = 0; + $blogs[ $blog_id ]->spam = 0; + $blogs[ $blog_id ]->deleted = 0; return $blogs; } @@ -691,6 +740,9 @@ function get_blogs_of_user( $user_id, $all = false ) { 'path' => $blog->path, 'site_id' => $blog->site_id, 'siteurl' => $blog->siteurl, + 'archived' => 0, + 'spam' => 0, + 'deleted' => 0 ); } unset( $keys[ $wpdb->base_prefix . 'capabilities' ] ); @@ -717,6 +769,9 @@ function get_blogs_of_user( $user_id, $all = false ) { 'path' => $blog->path, 'site_id' => $blog->site_id, 'siteurl' => $blog->siteurl, + 'archived' => 0, + 'spam' => 0, + 'deleted' => 0 ); } } @@ -761,7 +816,7 @@ function is_user_member_of_blog( $user_id = 0, $blog_id = 0 ) { * @param string $meta_key Metadata name. * @param mixed $meta_value Metadata value. * @param bool $unique Optional, default is false. Whether the same key should not be added. - * @return bool False for failure. True for success. + * @return int|bool Meta ID on success, false on failure. */ function add_user_meta($user_id, $meta_key, $meta_value, $unique = false) { return add_metadata('user', $user_id, $meta_key, $meta_value, $unique); @@ -781,7 +836,7 @@ function add_user_meta($user_id, $meta_key, $meta_value, $unique = false) { * @param int $user_id user ID * @param string $meta_key Metadata name. * @param mixed $meta_value Optional. Metadata value. - * @return bool False for failure. True for success. + * @return bool True on success, false on failure. */ function delete_user_meta($user_id, $meta_key, $meta_value = '') { return delete_metadata('user', $user_id, $meta_key, $meta_value); @@ -820,7 +875,7 @@ function get_user_meta($user_id, $key = '', $single = false) { * @param string $meta_key Metadata key. * @param mixed $meta_value Metadata value. * @param mixed $prev_value Optional. Previous value to check before removing. - * @return bool False on failure, true if success. + * @return bool True on success, false on failure. */ function update_user_meta($user_id, $meta_key, $meta_value, $prev_value = '') { return update_metadata('user', $user_id, $meta_key, $meta_value, $prev_value); @@ -920,33 +975,31 @@ function count_users($strategy = 'time') { * @global int $user_ID The ID of the user * @global string $user_email The email address of the user * @global string $user_url The url in the user's profile - * @global string $user_pass_md5 MD5 of the user's password * @global string $user_identity The display name of the user * * @param int $for_user_id Optional. User ID to set up global data. */ function setup_userdata($for_user_id = '') { - global $user_login, $userdata, $user_level, $user_ID, $user_email, $user_url, $user_pass_md5, $user_identity; + global $user_login, $userdata, $user_level, $user_ID, $user_email, $user_url, $user_identity; if ( '' == $for_user_id ) - $user = wp_get_current_user(); - else - $user = new WP_User($for_user_id); - - $userdata = null; - $user_ID = (int) $user->ID; - $user_level = (int) isset($user->user_level) ? $user->user_level : 0; - - if ( ! $user->exists() ) { - $user_login = $user_email = $user_url = $user_pass_md5 = $user_identity = ''; + $for_user_id = get_current_user_id(); + $user = get_userdata( $for_user_id ); + + if ( ! $user ) { + $user_ID = 0; + $user_level = 0; + $userdata = null; + $user_login = $user_email = $user_url = $user_identity = ''; return; } + $user_ID = (int) $user->ID; + $user_level = (int) $user->user_level; $userdata = $user; $user_login = $user->user_login; $user_email = $user->user_email; $user_url = $user->user_url; - $user_pass_md5 = md5( $user->user_pass ); $user_identity = $user->display_name; } @@ -1001,7 +1054,7 @@ function wp_dropdown_users( $args = '' ) { extract( $r, EXTR_SKIP ); $query_args = wp_array_slice_assoc( $r, array( 'blog_id', 'include', 'exclude', 'orderby', 'order', 'who' ) ); - $query_args['fields'] = array( 'ID', $show ); + $query_args['fields'] = array( 'ID', 'user_login', $show ); $users = get_users( $query_args ); $output = ''; @@ -1221,7 +1274,7 @@ function validate_username( $username ) { * 'ID' - An integer that will be used for updating an existing user. * 'user_pass' - A string that contains the plain text password for the user. * 'user_login' - A string that contains the user's username for logging in. - * 'user_nicename' - A string that contains a nicer looking name for the user. + * 'user_nicename' - A string that contains a URL-friendly name for the user. * The default is the user's username. * 'user_url' - A string containing the user's URL for the user's web site. * 'user_email' - A string containing the user's email address. @@ -1245,13 +1298,18 @@ function validate_username( $username ) { * @uses do_action() Calls 'profile_update' hook when updating giving the user's ID * @uses do_action() Calls 'user_register' hook when creating a new user giving the user's ID * - * @param array $userdata An array of user data. + * @param mixed $userdata An array of user data or a user object of type stdClass or WP_User. * @return int|WP_Error The newly created user's ID or a WP_Error object if the user could not be created. */ -function wp_insert_user($userdata) { +function wp_insert_user( $userdata ) { global $wpdb; - extract($userdata, EXTR_SKIP); + if ( is_a( $userdata, 'stdClass' ) ) + $userdata = get_object_vars( $userdata ); + elseif ( is_a( $userdata, 'WP_User' ) ) + $userdata = $userdata->to_array(); + + extract( $userdata, EXTR_SKIP ); // Are we updating or creating? if ( !empty($ID) ) { @@ -1274,7 +1332,7 @@ function wp_insert_user($userdata) { return new WP_Error('empty_user_login', __('Cannot create a user with an empty login name.') ); if ( !$update && username_exists( $user_login ) ) - return new WP_Error('existing_user_login', __('This username is already registered.') ); + return new WP_Error( 'existing_user_login', __( 'Sorry, that username already exists!' ) ); if ( empty($user_nicename) ) $user_nicename = sanitize_title( $user_login ); @@ -1289,11 +1347,7 @@ function wp_insert_user($userdata) { $user_email = apply_filters('pre_user_email', $user_email); if ( !$update && ! defined( 'WP_IMPORTING' ) && email_exists($user_email) ) - return new WP_Error('existing_user_email', __('This email address is already registered.') ); - - if ( empty($display_name) ) - $display_name = $user_login; - $display_name = apply_filters('pre_user_display_name', $display_name); + return new WP_Error( 'existing_user_email', __( 'Sorry, that email address is already used!' ) ); if ( empty($nickname) ) $nickname = $user_login; @@ -1307,6 +1361,21 @@ function wp_insert_user($userdata) { $last_name = ''; $last_name = apply_filters('pre_user_last_name', $last_name); + if ( empty( $display_name ) ) { + if ( $update ) + $display_name = $user_login; + elseif ( $first_name && $last_name ) + /* translators: 1: first name, 2: last name */ + $display_name = sprintf( _x( '%1$s %2$s', 'Display name based on first name and last name' ), $first_name, $last_name ); + elseif ( $first_name ) + $display_name = $first_name; + elseif ( $last_name ) + $display_name = $last_name; + else + $display_name = $user_login; + } + $display_name = apply_filters( 'pre_user_display_name', $display_name ); + if ( empty($description) ) $description = ''; $description = apply_filters('pre_user_description', $description); @@ -1343,7 +1412,7 @@ function wp_insert_user($userdata) { } $data = compact( 'user_pass', 'user_email', 'user_url', 'user_nicename', 'display_name', 'user_registered' ); - $data = stripslashes_deep( $data ); + $data = wp_unslash( $data ); if ( $update ) { $wpdb->update( $wpdb->users, $data, compact( 'ID' ) ); @@ -1382,9 +1451,6 @@ function wp_insert_user($userdata) { * It is possible to update a user's password by specifying the 'user_pass' * value in the $userdata parameter array. * - * If $userdata does not contain an 'ID' key, then a new user will be created - * and the new user's ID will be returned. - * * If current user's password is being updated, then the cookies will be * cleared. * @@ -1392,16 +1458,23 @@ function wp_insert_user($userdata) { * @see wp_insert_user() For what fields can be set in $userdata * @uses wp_insert_user() Used to update existing user or add new one if user doesn't exist already * - * @param array $userdata An array of user data. - * @return int The updated user's ID. + * @param mixed $userdata An array of user data or a user object of type stdClass or WP_User. + * @return int|WP_Error The updated user's ID or a WP_Error object if the user could not be updated. */ function wp_update_user($userdata) { + if ( is_a( $userdata, 'stdClass' ) ) + $userdata = get_object_vars( $userdata ); + elseif ( is_a( $userdata, 'WP_User' ) ) + $userdata = $userdata->to_array(); + $ID = (int) $userdata['ID']; // First, get all of the original fields $user_obj = get_userdata( $ID ); + if ( ! $user_obj ) + return new WP_Error( 'invalid_user_id', __( 'Invalid user ID.' ) ); - $user = get_object_vars( $user_obj->data ); + $user = $user_obj->to_array(); // Add additional custom fields foreach ( _get_additional_user_keys( $user_obj ) as $key ) { @@ -1450,8 +1523,8 @@ function wp_update_user($userdata) { * @return int The new user's ID. */ function wp_create_user($username, $password, $email = '') { - $user_login = esc_sql( $username ); - $user_email = esc_sql( $email ); + $user_login = wp_slash( $username ); + $user_email = wp_slash( $email ); $user_pass = $password; $userdata = compact('user_login', 'user_email', 'user_pass'); @@ -1461,31 +1534,180 @@ function wp_create_user($username, $password, $email = '') { /** * Return a list of meta keys that wp_insert_user() is supposed to set. * - * @access private * @since 3.3.0 + * @access private * - * @param object $user WP_User instance + * @param object $user WP_User instance. * @return array */ function _get_additional_user_keys( $user ) { $keys = array( 'first_name', 'last_name', 'nickname', 'description', 'rich_editing', 'comment_shortcuts', 'admin_color', 'use_ssl', 'show_admin_bar_front' ); - return array_merge( $keys, array_keys( _wp_get_user_contactmethods( $user ) ) ); + return array_merge( $keys, array_keys( wp_get_user_contact_methods( $user ) ) ); } /** - * Set up the default contact methods + * Set up the user contact methods. * - * @access private - * @since + * Default contact methods were removed in 3.6. A filter dictates contact methods. + * + * @since 3.7.0 * - * @param object $user User data object (optional) - * @return array $user_contactmethods Array of contact methods and their labels. + * @param WP_User $user Optional. WP_User object. + * @return array Array of contact methods and their labels. + */ +function wp_get_user_contact_methods( $user = null ) { + $methods = array(); + if ( get_site_option( 'initial_db_version' ) < 23588 ) { + $methods = array( + 'aim' => __( 'AIM' ), + 'yim' => __( 'Yahoo IM' ), + 'jabber' => __( 'Jabber / Google Talk' ) + ); + } + + /** + * Filter the user contact methods. + * + * @since 2.9.0 + * + * @param array $methods Array of contact methods and their labels. + * @param WP_User $user Optional. WP_User object. + */ + return apply_filters( 'user_contactmethods', $methods, $user ); +} + +/** + * The old private function for setting up user contact methods. + * + * @since 2.9.0 + * @access private */ function _wp_get_user_contactmethods( $user = null ) { - $user_contactmethods = array( - 'aim' => __('AIM'), - 'yim' => __('Yahoo IM'), - 'jabber' => __('Jabber / Google Talk') - ); - return apply_filters( 'user_contactmethods', $user_contactmethods, $user ); + return wp_get_user_contact_methods( $user ); +} + +/** + * Retrieves a user row based on password reset key and login + * + * A key is considered 'expired' if it exactly matches the value of the + * user_activation_key field, rather than being matched after going through the + * hashing process. This field is now hashed; old values are no longer accepted + * but have a different WP_Error code so good user feedback can be provided. + * + * @uses $wpdb WordPress Database object + * + * @param string $key Hash to validate sending user's password. + * @param string $login The user login. + * @return WP_User|WP_Error WP_User object on success, WP_Error object for invalid or expired keys. + */ +function check_password_reset_key($key, $login) { + global $wpdb, $wp_hasher; + + $key = preg_replace('/[^a-z0-9]/i', '', $key); + + if ( empty( $key ) || !is_string( $key ) ) + return new WP_Error('invalid_key', __('Invalid key')); + + if ( empty($login) || !is_string($login) ) + return new WP_Error('invalid_key', __('Invalid key')); + + $row = $wpdb->get_row( $wpdb->prepare( "SELECT ID, user_activation_key FROM $wpdb->users WHERE user_login = %s", $login ) ); + if ( ! $row ) + return new WP_Error('invalid_key', __('Invalid key')); + + if ( empty( $wp_hasher ) ) { + require_once ABSPATH . 'wp-includes/class-phpass.php'; + $wp_hasher = new PasswordHash( 8, true ); + } + + if ( $wp_hasher->CheckPassword( $key, $row->user_activation_key ) ) + return get_userdata( $row->ID ); + + if ( $key === $row->user_activation_key ) { + $return = new WP_Error( 'expired_key', __( 'Invalid key' ) ); + $user_id = $row->ID; + + /** + * Filter the return value of check_password_reset_key() when an + * old-style key is used (plain-text key was stored in the database). + * + * @since 3.7.0 + * + * @param WP_Error $return A WP_Error object denoting an expired key. + * Return a WP_User object to validate the key. + * @param int $user_id The matched user ID. + */ + return apply_filters( 'password_reset_key_expired', $return, $user_id ); + } + + return new WP_Error( 'invalid_key', __( 'Invalid key' ) ); +} + +/** + * Handles resetting the user's password. + * + * @param object $user The user + * @param string $new_pass New password for the user in plaintext + */ +function reset_password( $user, $new_pass ) { + do_action( 'password_reset', $user, $new_pass ); + + wp_set_password( $new_pass, $user->ID ); + update_user_option( $user->ID, 'default_password_nag', false, true ); + + wp_password_change_notification( $user ); +} + +/** + * Handles registering a new user. + * + * @param string $user_login User's username for logging in + * @param string $user_email User's email address to send password and add + * @return int|WP_Error Either user's ID or error on failure. + */ +function register_new_user( $user_login, $user_email ) { + $errors = new WP_Error(); + + $sanitized_user_login = sanitize_user( $user_login ); + $user_email = apply_filters( 'user_registration_email', $user_email ); + + // Check the username + if ( $sanitized_user_login == '' ) { + $errors->add( 'empty_username', __( 'ERROR: Please enter a username.' ) ); + } elseif ( ! validate_username( $user_login ) ) { + $errors->add( 'invalid_username', __( 'ERROR: This username is invalid because it uses illegal characters. Please enter a valid username.' ) ); + $sanitized_user_login = ''; + } elseif ( username_exists( $sanitized_user_login ) ) { + $errors->add( 'username_exists', __( 'ERROR: This username is already registered. Please choose another one.' ) ); + } + + // Check the e-mail address + if ( $user_email == '' ) { + $errors->add( 'empty_email', __( 'ERROR: Please type your e-mail address.' ) ); + } elseif ( ! is_email( $user_email ) ) { + $errors->add( 'invalid_email', __( 'ERROR: The email address isn’t correct.' ) ); + $user_email = ''; + } elseif ( email_exists( $user_email ) ) { + $errors->add( 'email_exists', __( 'ERROR: This email is already registered, please choose another one.' ) ); + } + + do_action( 'register_post', $sanitized_user_login, $user_email, $errors ); + + $errors = apply_filters( 'registration_errors', $errors, $sanitized_user_login, $user_email ); + + if ( $errors->get_error_code() ) + return $errors; + + $user_pass = wp_generate_password( 12, false ); + $user_id = wp_create_user( $sanitized_user_login, $user_pass, $user_email ); + if ( ! $user_id || is_wp_error( $user_id ) ) { + $errors->add( 'registerfail', sprintf( __( 'ERROR: Couldn’t register you… please contact the webmaster !' ), get_option( 'admin_email' ) ) ); + return $errors; + } + + update_user_option( $user_id, 'default_password_nag', true, true ); //Set up the Password change nag. + + wp_new_user_notification( $user_id, $user_pass ); + + return $user_id; }