2007-05-25 03:16:21 -04:00
< ? php
2008-10-01 21:03:26 -04:00
/**
* WordPress user administration API .
*
* @ package WordPress
* @ subpackage Administration
*/
/**
* Creates a new user from the " Users " form using $_POST information .
*
2013-12-24 13:57:12 -05:00
* @ since 2.0 . 0
2008-10-01 21:03:26 -04:00
*
2015-05-29 16:17:26 -04:00
* @ return int | WP_Error WP_Error or User ID .
2008-10-01 21:03:26 -04:00
*/
2007-05-25 03:16:21 -04:00
function add_user () {
2012-01-05 15:38:40 -05:00
return edit_user ();
2007-05-25 03:16:21 -04:00
}
2008-10-01 21:03:26 -04:00
/**
2009-01-06 17:00:05 -05:00
* Edit user settings based on contents of $_POST
2008-10-01 21:03:26 -04:00
*
2009-01-06 17:00:05 -05:00
* Used on user - edit . php and profile . php to manage and process user options , passwords etc .
2008-10-01 21:03:26 -04:00
*
2013-12-24 13:57:12 -05:00
* @ since 2.0 . 0
2008-10-01 21:03:26 -04:00
*
* @ param int $user_id Optional . User ID .
2020-06-20 08:02:12 -04:00
* @ return int | WP_Error User ID of the updated user .
2008-10-01 21:03:26 -04:00
*/
2007-05-25 03:16:21 -04:00
function edit_user ( $user_id = 0 ) {
2015-05-28 17:41:30 -04:00
$wp_roles = wp_roles ();
2017-11-30 18:11:00 -05:00
$user = new stdClass ;
2018-03-19 16:29:34 -04:00
$user_id = ( int ) $user_id ;
2010-11-15 01:38:10 -05:00
if ( $user_id ) {
2017-11-30 18:11:00 -05:00
$update = true ;
2018-03-19 16:29:34 -04:00
$user -> ID = $user_id ;
2017-11-30 18:11:00 -05:00
$userdata = get_userdata ( $user_id );
2013-03-01 12:14:09 -05:00
$user -> user_login = wp_slash ( $userdata -> user_login );
2007-05-25 03:16:21 -04:00
} else {
$update = false ;
}
2017-11-30 18:11:00 -05:00
if ( ! $update && isset ( $_POST [ 'user_login' ] ) ) {
2019-11-03 15:12:02 -05:00
$user -> user_login = sanitize_user ( wp_unslash ( $_POST [ 'user_login' ] ), true );
2017-11-30 18:11:00 -05:00
}
2007-05-25 03:16:21 -04:00
2019-07-01 08:52:01 -04:00
$pass1 = '' ;
$pass2 = '' ;
2017-11-30 18:11:00 -05:00
if ( isset ( $_POST [ 'pass1' ] ) ) {
2020-10-10 12:51:07 -04:00
$pass1 = trim ( $_POST [ 'pass1' ] );
2017-11-30 18:11:00 -05:00
}
if ( isset ( $_POST [ 'pass2' ] ) ) {
2020-10-10 12:51:07 -04:00
$pass2 = trim ( $_POST [ 'pass2' ] );
2017-11-30 18:11:00 -05:00
}
2007-05-25 03:16:21 -04:00
2018-03-19 16:29:34 -04:00
if ( isset ( $_POST [ 'role' ] ) && current_user_can ( 'promote_users' ) && ( ! $user_id || current_user_can ( 'promote_user' , $user_id ) ) ) {
$new_role = sanitize_text_field ( $_POST [ 'role' ] );
2009-01-06 17:00:05 -05:00
2018-03-19 16:29:34 -04:00
// If the new role isn't editable by the logged-in user die with error.
2009-01-06 17:00:05 -05:00
$editable_roles = get_editable_roles ();
2017-11-30 18:11:00 -05:00
if ( ! empty ( $new_role ) && empty ( $editable_roles [ $new_role ] ) ) {
2017-06-25 14:46:44 -04:00
wp_die ( __ ( 'Sorry, you are not allowed to give users that role.' ), 403 );
2017-11-30 18:11:00 -05:00
}
2018-03-19 16:29:34 -04:00
$potential_role = isset ( $wp_roles -> role_objects [ $new_role ] ) ? $wp_roles -> role_objects [ $new_role ] : false ;
/*
* Don 't let anyone with ' promote_users ' edit their own role to something without it .
* Multisite super admins can freely edit their roles , they possess all caps .
*/
if (
( is_multisite () && current_user_can ( 'manage_network_users' ) ) ||
2020-02-09 11:55:09 -05:00
get_current_user_id () !== $user_id ||
2018-03-19 16:29:34 -04:00
( $potential_role && $potential_role -> has_cap ( 'promote_users' ) )
) {
$user -> role = $new_role ;
}
2007-05-25 03:16:21 -04:00
}
2017-11-30 18:11:00 -05:00
if ( isset ( $_POST [ 'email' ] ) ) {
2014-10-19 16:30:19 -04:00
$user -> user_email = sanitize_text_field ( wp_unslash ( $_POST [ 'email' ] ) );
2017-11-30 18:11:00 -05:00
}
2013-03-01 11:28:40 -05:00
if ( isset ( $_POST [ 'url' ] ) ) {
2020-02-09 11:55:09 -05:00
if ( empty ( $_POST [ 'url' ] ) || 'http://' === $_POST [ 'url' ] ) {
2009-05-13 18:41:05 -04:00
$user -> user_url = '' ;
} else {
2013-03-01 11:28:40 -05:00
$user -> user_url = esc_url_raw ( $_POST [ 'url' ] );
2017-11-30 18:11:00 -05:00
$protocols = implode ( '|' , array_map ( 'preg_quote' , wp_allowed_protocols () ) );
$user -> user_url = preg_match ( '/^(' . $protocols . '):/is' , $user -> user_url ) ? $user -> user_url : 'http://' . $user -> user_url ;
2009-05-13 18:41:05 -04:00
}
2007-05-25 03:16:21 -04:00
}
2017-11-30 18:11:00 -05:00
if ( isset ( $_POST [ 'first_name' ] ) ) {
2013-03-01 11:28:40 -05:00
$user -> first_name = sanitize_text_field ( $_POST [ 'first_name' ] );
2017-11-30 18:11:00 -05:00
}
if ( isset ( $_POST [ 'last_name' ] ) ) {
2013-03-01 11:28:40 -05:00
$user -> last_name = sanitize_text_field ( $_POST [ 'last_name' ] );
2017-11-30 18:11:00 -05:00
}
if ( isset ( $_POST [ 'nickname' ] ) ) {
2013-03-01 11:28:40 -05:00
$user -> nickname = sanitize_text_field ( $_POST [ 'nickname' ] );
2017-11-30 18:11:00 -05:00
}
if ( isset ( $_POST [ 'display_name' ] ) ) {
2013-03-01 11:28:40 -05:00
$user -> display_name = sanitize_text_field ( $_POST [ 'display_name' ] );
2017-11-30 18:11:00 -05:00
}
2013-03-01 11:28:40 -05:00
2017-11-30 18:11:00 -05:00
if ( isset ( $_POST [ 'description' ] ) ) {
2013-03-01 11:28:40 -05:00
$user -> description = trim ( $_POST [ 'description' ] );
2017-11-30 18:11:00 -05:00
}
2009-09-14 09:57:48 -04:00
2013-09-24 14:14:09 -04:00
foreach ( wp_get_user_contact_methods ( $user ) as $method => $name ) {
2017-11-30 18:11:00 -05:00
if ( isset ( $_POST [ $method ] ) ) {
$user -> $method = sanitize_text_field ( $_POST [ $method ] );
}
2009-09-14 09:57:48 -04:00
}
2020-03-27 17:58:05 -04:00
if ( isset ( $_POST [ 'locale' ] ) ) {
$locale = sanitize_text_field ( $_POST [ 'locale' ] );
if ( 'site-default' === $locale ) {
$locale = '' ;
} elseif ( '' === $locale ) {
$locale = 'en_US' ;
} elseif ( ! in_array ( $locale , get_available_languages (), true ) ) {
$locale = '' ;
}
$user -> locale = $locale ;
}
2009-09-14 09:57:48 -04:00
if ( $update ) {
2017-11-30 18:11:00 -05:00
$user -> rich_editing = isset ( $_POST [ 'rich_editing' ] ) && 'false' === $_POST [ 'rich_editing' ] ? 'false' : 'true' ;
$user -> syntax_highlighting = isset ( $_POST [ 'syntax_highlighting' ] ) && 'false' === $_POST [ 'syntax_highlighting' ] ? 'false' : 'true' ;
$user -> admin_color = isset ( $_POST [ 'admin_color' ] ) ? sanitize_text_field ( $_POST [ 'admin_color' ] ) : 'fresh' ;
2013-03-01 11:28:40 -05:00
$user -> show_admin_bar_front = isset ( $_POST [ 'admin_bar_front' ] ) ? 'true' : 'false' ;
2009-08-06 17:59:52 -04:00
}
2007-05-25 03:16:21 -04:00
2020-05-16 14:42:12 -04:00
$user -> comment_shortcuts = isset ( $_POST [ 'comment_shortcuts' ] ) && 'true' === $_POST [ 'comment_shortcuts' ] ? 'true' : '' ;
2008-12-09 13:03:31 -05:00
2008-08-21 13:40:38 -04:00
$user -> use_ssl = 0 ;
2017-11-30 18:11:00 -05:00
if ( ! empty ( $_POST [ 'use_ssl' ] ) ) {
2008-08-21 13:40:38 -04:00
$user -> use_ssl = 1 ;
2017-11-30 18:11:00 -05:00
}
2008-08-21 13:40:38 -04:00
2007-05-25 03:16:21 -04:00
$errors = new WP_Error ();
/* checking that username has been typed */
2020-05-16 14:42:12 -04:00
if ( '' === $user -> user_login ) {
2020-06-21 10:00:09 -04:00
$errors -> add ( 'user_login' , __ ( '<strong>Error</strong>: Please enter a username.' ) );
2017-11-30 18:11:00 -05:00
}
2015-09-25 00:44:25 -04:00
2015-09-24 13:49:25 -04:00
/* checking that nickname has been typed */
2015-09-25 00:44:25 -04:00
if ( $update && empty ( $user -> nickname ) ) {
2020-06-21 10:00:09 -04:00
$errors -> add ( 'nickname' , __ ( '<strong>Error</strong>: Please enter a nickname.' ) );
2015-09-24 13:49:25 -04:00
}
2015-09-25 00:44:25 -04:00
2013-12-01 12:54:10 -05:00
/**
* Fires before the password and confirm password fields are checked for congruity .
*
* @ since 1.5 . 1
*
* @ param string $user_login The username .
2017-10-02 18:03:33 -04:00
* @ param string $pass1 The password ( passed by reference ) .
* @ param string $pass2 The confirmed password ( passed by reference ) .
2013-12-01 12:54:10 -05:00
*/
2013-03-07 01:00:16 -05:00
do_action_ref_array ( 'check_passwords' , array ( $user -> user_login , & $pass1 , & $pass2 ) );
2007-05-25 03:16:21 -04:00
2016-03-22 19:07:27 -04:00
// Check for blank password when adding a user.
if ( ! $update && empty ( $pass1 ) ) {
2020-06-21 10:00:09 -04:00
$errors -> add ( 'pass' , __ ( '<strong>Error</strong>: Please enter a password.' ), array ( 'form-field' => 'pass1' ) );
2016-03-22 19:07:27 -04:00
}
// Check for "\" in password.
2017-11-30 18:11:00 -05:00
if ( false !== strpos ( wp_unslash ( $pass1 ), '\\' ) ) {
2020-06-21 10:00:09 -04:00
$errors -> add ( 'pass' , __ ( '<strong>Error</strong>: Passwords may not contain the character "\\".' ), array ( 'form-field' => 'pass1' ) );
2016-03-22 19:07:27 -04:00
}
2007-05-25 03:16:21 -04:00
2016-03-22 19:07:27 -04:00
// Checking the password has been typed twice the same.
if ( ( $update || ! empty ( $pass1 ) ) && $pass1 != $pass2 ) {
2020-06-21 10:00:09 -04:00
$errors -> add ( 'pass' , __ ( '<strong>Error</strong>: Passwords don’t match. Please enter the same password in both password fields.' ), array ( 'form-field' => 'pass1' ) );
2016-03-22 19:07:27 -04:00
}
2007-05-25 03:16:21 -04:00
2017-11-30 18:11:00 -05:00
if ( ! empty ( $pass1 ) ) {
2007-05-25 03:16:21 -04:00
$user -> user_pass = $pass1 ;
2017-11-30 18:11:00 -05:00
}
2007-05-25 03:16:21 -04:00
2017-11-30 18:11:00 -05:00
if ( ! $update && isset ( $_POST [ 'user_login' ] ) && ! validate_username ( $_POST [ 'user_login' ] ) ) {
2020-06-21 10:00:09 -04:00
$errors -> add ( 'user_login' , __ ( '<strong>Error</strong>: This username is invalid because it uses illegal characters. Please enter a valid username.' ) );
2017-11-30 18:11:00 -05:00
}
2007-05-25 03:16:21 -04:00
2017-11-30 18:11:00 -05:00
if ( ! $update && username_exists ( $user -> user_login ) ) {
2020-06-21 10:00:09 -04:00
$errors -> add ( 'user_login' , __ ( '<strong>Error</strong>: This username is already registered. Please choose another one.' ) );
2017-11-30 18:11:00 -05:00
}
2007-05-25 03:16:21 -04:00
2015-11-21 22:51:28 -05:00
/** This filter is documented in wp-includes/user.php */
2015-11-12 11:34:27 -05:00
$illegal_logins = ( array ) apply_filters ( 'illegal_user_logins' , array () );
2015-11-12 11:30:28 -05:00
2019-11-29 17:04:02 -05:00
if ( in_array ( strtolower ( $user -> user_login ), array_map ( 'strtolower' , $illegal_logins ), true ) ) {
2020-06-21 10:00:09 -04:00
$errors -> add ( 'invalid_username' , __ ( '<strong>Error</strong>: Sorry, that username is not allowed.' ) );
2015-10-15 01:43:26 -04:00
}
2015-08-27 23:17:21 -04:00
/* checking email address */
2009-09-14 09:57:48 -04:00
if ( empty ( $user -> user_email ) ) {
2020-06-21 10:00:09 -04:00
$errors -> add ( 'empty_email' , __ ( '<strong>Error</strong>: Please enter an email address.' ), array ( 'form-field' => 'email' ) );
2017-11-30 18:11:00 -05:00
} elseif ( ! is_email ( $user -> user_email ) ) {
2020-06-21 10:00:09 -04:00
$errors -> add ( 'invalid_email' , __ ( '<strong>Error</strong>: The email address isn’t correct.' ), array ( 'form-field' => 'email' ) );
2019-07-01 08:52:01 -04:00
} else {
$owner_id = email_exists ( $user -> user_email );
if ( $owner_id && ( ! $update || ( $owner_id != $user -> ID ) ) ) {
2020-06-21 10:00:09 -04:00
$errors -> add ( 'email_exists' , __ ( '<strong>Error</strong>: This email is already registered. Please choose another one.' ), array ( 'form-field' => 'email' ) );
2019-07-01 08:52:01 -04:00
}
2009-04-17 14:43:40 -04:00
}
2007-05-25 03:16:21 -04:00
2013-12-01 12:54:10 -05:00
/**
* Fires before user profile update errors are returned .
*
* @ since 2.8 . 0
*
2017-10-02 18:03:33 -04:00
* @ param WP_Error $errors WP_Error object ( passed by reference ) .
2020-06-20 08:02:12 -04:00
* @ param bool $update Whether this is a user update .
2017-10-02 18:03:33 -04:00
* @ param stdClass $user User object ( passed by reference ) .
2013-12-01 12:54:10 -05:00
*/
2013-03-07 01:00:16 -05:00
do_action_ref_array ( 'user_profile_update_errors' , array ( & $errors , $update , & $user ) );
2009-05-24 19:47:49 -04:00
2018-02-26 21:31:31 -05:00
if ( $errors -> has_errors () ) {
2007-05-25 03:16:21 -04:00
return $errors ;
2017-11-30 18:11:00 -05:00
}
2007-05-25 03:16:21 -04:00
if ( $update ) {
2012-08-10 11:36:54 -04:00
$user_id = wp_update_user ( $user );
2007-05-25 03:16:21 -04:00
} else {
2012-08-10 11:36:54 -04:00
$user_id = wp_insert_user ( $user );
2015-11-25 17:38:29 -05:00
$notify = isset ( $_POST [ 'send_user_notification' ] ) ? 'both' : 'admin' ;
2015-09-16 18:19:24 -04:00
/**
2017-11-26 18:57:55 -05:00
* Fires after a new user has been created .
*
* @ since 4.4 . 0
*
* @ param int $user_id ID of the newly created user .
* @ param string $notify Type of notification that should happen . See wp_send_new_user_notifications ()
* for more information on possible values .
*/
2015-11-25 17:38:29 -05:00
do_action ( 'edit_user_created_user' , $user_id , $notify );
2007-05-25 03:16:21 -04:00
}
return $user_id ;
}
2009-01-06 17:00:05 -05:00
/**
2009-03-17 22:43:45 -04:00
* Fetch a filtered list of user roles that the current user is
* allowed to edit .
2009-01-06 17:00:05 -05:00
*
2018-10-02 12:23:25 -04:00
* Simple function whose main purpose is to allow filtering of the
2009-01-06 17:00:05 -05:00
* list of roles in the $wp_roles object so that plugins can remove
2011-09-03 10:18:10 -04:00
* inappropriate ones depending on the situation or user making edits .
2009-01-06 17:00:05 -05:00
* Specifically because without filtering anyone with the edit_users
* capability can edit others to be administrators , even if they are
* only editors or authors . This filter allows admins to delegate
2009-03-17 22:43:45 -04:00
* user management .
2009-01-06 17:00:05 -05:00
*
2013-12-24 13:57:12 -05:00
* @ since 2.8 . 0
2009-01-06 17:00:05 -05:00
*
2018-03-25 14:10:32 -04:00
* @ return array [] Array of arrays containing role information .
2009-01-06 17:00:05 -05:00
*/
function get_editable_roles () {
2015-05-28 17:41:30 -04:00
$all_roles = wp_roles () -> roles ;
2013-12-01 12:54:10 -05:00
/**
2016-05-22 14:01:30 -04:00
* Filters the list of editable roles .
2013-12-01 12:54:10 -05:00
*
* @ since 2.8 . 0
*
2018-03-25 14:10:32 -04:00
* @ param array [] $all_roles Array of arrays containing role information .
2013-12-01 12:54:10 -05:00
*/
$editable_roles = apply_filters ( 'editable_roles' , $all_roles );
2009-03-17 22:43:45 -04:00
2009-01-06 17:00:05 -05:00
return $editable_roles ;
}
2008-10-01 21:03:26 -04:00
/**
* Retrieve user data and filter it .
*
2010-12-01 14:24:38 -05:00
* @ since 2.0 . 5
2008-10-01 21:03:26 -04:00
*
* @ param int $user_id User ID .
2013-09-01 23:25:09 -04:00
* @ return WP_User | bool WP_User object on success , false on failure .
2008-10-01 21:03:26 -04:00
*/
2007-05-25 03:16:21 -04:00
function get_user_to_edit ( $user_id ) {
2012-08-02 21:06:05 -04:00
$user = get_userdata ( $user_id );
2009-08-06 17:59:52 -04:00
2017-11-30 18:11:00 -05:00
if ( $user ) {
2013-09-01 23:25:09 -04:00
$user -> filter = 'edit' ;
2017-11-30 18:11:00 -05:00
}
2007-05-25 03:16:21 -04:00
return $user ;
}
2008-10-01 21:03:26 -04:00
/**
* Retrieve the user ' s drafts .
*
2010-12-01 14:24:38 -05:00
* @ since 2.0 . 0
2008-10-01 21:03:26 -04:00
*
2015-10-14 19:44:25 -04:00
* @ global wpdb $wpdb WordPress database abstraction object .
2015-05-28 17:41:30 -04:00
*
2008-10-01 21:03:26 -04:00
* @ param int $user_id User ID .
* @ return array
*/
2007-05-25 03:16:21 -04:00
function get_users_drafts ( $user_id ) {
global $wpdb ;
2017-11-30 18:11:00 -05:00
$query = $wpdb -> prepare ( " SELECT ID, post_title FROM $wpdb->posts WHERE post_type = 'post' AND post_status = 'draft' AND post_author = %d ORDER BY post_modified DESC " , $user_id );
2013-12-01 12:54:10 -05:00
/**
2016-05-22 14:01:30 -04:00
* Filters the user ' s drafts query string .
2013-12-01 12:54:10 -05:00
*
* @ since 2.0 . 0
*
* @ param string $query The user ' s drafts query string .
*/
$query = apply_filters ( 'get_users_drafts' , $query );
2007-05-25 03:16:21 -04:00
return $wpdb -> get_results ( $query );
}
2008-10-01 21:03:26 -04:00
/**
* Remove user and optionally reassign posts and links to another user .
*
2015-04-05 10:44:27 -04:00
* If the $reassign parameter is not assigned to a User ID , then all posts will
2016-05-23 13:28:27 -04:00
* be deleted of that user . The action { @ see 'delete_user' } that is passed the User ID
2008-10-01 21:03:26 -04:00
* being deleted will be run after the posts are either reassigned or deleted .
* The user meta will also be deleted that are for that User ID .
*
2010-12-01 14:24:38 -05:00
* @ since 2.0 . 0
2008-10-01 21:03:26 -04:00
*
2015-10-14 19:44:25 -04:00
* @ global wpdb $wpdb WordPress database abstraction object .
2015-05-28 17:41:30 -04:00
*
2008-10-01 21:03:26 -04:00
* @ param int $id User ID .
* @ param int $reassign Optional . Reassign posts and links to new User ID .
* @ return bool True when finished .
*/
2014-03-07 22:16:14 -05:00
function wp_delete_user ( $id , $reassign = null ) {
2007-05-25 03:16:21 -04:00
global $wpdb ;
2015-09-10 22:25:23 -04:00
if ( ! is_numeric ( $id ) ) {
return false ;
}
2017-11-30 18:11:00 -05:00
$id = ( int ) $id ;
2012-04-18 17:07:31 -04:00
$user = new WP_User ( $id );
2009-04-16 22:13:00 -04:00
2017-11-30 18:11:00 -05:00
if ( ! $user -> exists () ) {
2013-02-01 23:41:02 -05:00
return false ;
2017-11-30 18:11:00 -05:00
}
2013-02-01 23:41:02 -05:00
2014-03-07 22:16:14 -05:00
// Normalize $reassign to null or a user ID. 'novalue' was an older default.
if ( 'novalue' === $reassign ) {
$reassign = null ;
} elseif ( null !== $reassign ) {
$reassign = ( int ) $reassign ;
}
2013-12-01 12:54:10 -05:00
/**
* Fires immediately before a user is deleted from the database .
*
* @ since 2.0 . 0
2020-07-05 06:57:01 -04:00
* @ since 5.5 . 0 Added the `$user` parameter .
2013-12-01 12:54:10 -05:00
*
2014-03-07 22:16:14 -05:00
* @ param int $id ID of the user to delete .
* @ param int | null $reassign ID of the user to reassign posts and links to .
* Default null , for no reassignment .
2020-07-05 06:57:01 -04:00
* @ param WP_User $user WP_User object of the user to delete .
2013-12-01 12:54:10 -05:00
*/
2020-07-05 06:57:01 -04:00
do_action ( 'delete_user' , $id , $reassign , $user );
2007-05-25 03:16:21 -04:00
2014-03-07 22:16:14 -05:00
if ( null === $reassign ) {
2012-05-08 13:01:50 -04:00
$post_types_to_delete = array ();
foreach ( get_post_types ( array (), 'objects' ) as $post_type ) {
if ( $post_type -> delete_with_user ) {
$post_types_to_delete [] = $post_type -> name ;
} elseif ( null === $post_type -> delete_with_user && post_type_supports ( $post_type -> name , 'author' ) ) {
$post_types_to_delete [] = $post_type -> name ;
}
}
2007-05-25 03:16:21 -04:00
2013-12-01 12:54:10 -05:00
/**
2016-05-22 14:01:30 -04:00
* Filters the list of post types to delete with a user .
2013-12-01 12:54:10 -05:00
*
* @ since 3.4 . 0
*
2018-03-25 14:10:32 -04:00
* @ param string [] $post_types_to_delete Array of post types to delete .
* @ param int $id User ID .
2013-12-01 12:54:10 -05:00
*/
2012-05-08 13:01:50 -04:00
$post_types_to_delete = apply_filters ( 'post_types_to_delete_with_user' , $post_types_to_delete , $id );
$post_types_to_delete = implode ( " ', ' " , $post_types_to_delete );
2017-11-30 18:11:00 -05:00
$post_ids = $wpdb -> get_col ( $wpdb -> prepare ( " SELECT ID FROM $wpdb->posts WHERE post_author = %d AND post_type IN (' $post_types_to_delete ') " , $id ) );
2010-01-19 14:23:11 -05:00
if ( $post_ids ) {
2017-11-30 18:11:00 -05:00
foreach ( $post_ids as $post_id ) {
2012-05-08 13:01:50 -04:00
wp_delete_post ( $post_id );
2017-11-30 18:11:00 -05:00
}
2007-05-25 03:16:21 -04:00
}
2020-01-28 19:45:18 -05:00
// Clean links.
2017-11-30 18:11:00 -05:00
$link_ids = $wpdb -> get_col ( $wpdb -> prepare ( " SELECT link_id FROM $wpdb->links WHERE link_owner = %d " , $id ) );
2009-04-16 22:13:00 -04:00
if ( $link_ids ) {
2017-11-30 18:11:00 -05:00
foreach ( $link_ids as $link_id ) {
wp_delete_link ( $link_id );
}
2009-04-16 22:13:00 -04:00
}
2007-05-25 03:16:21 -04:00
} else {
2012-09-10 15:56:08 -04:00
$post_ids = $wpdb -> get_col ( $wpdb -> prepare ( " SELECT ID FROM $wpdb->posts WHERE post_author = %d " , $id ) );
2017-11-30 18:11:00 -05:00
$wpdb -> update ( $wpdb -> posts , array ( 'post_author' => $reassign ), array ( 'post_author' => $id ) );
2012-09-10 15:56:08 -04:00
if ( ! empty ( $post_ids ) ) {
2017-11-30 18:11:00 -05:00
foreach ( $post_ids as $post_id ) {
2012-09-10 15:56:08 -04:00
clean_post_cache ( $post_id );
2017-11-30 18:11:00 -05:00
}
2012-09-10 15:56:08 -04:00
}
2017-11-30 18:11:00 -05:00
$link_ids = $wpdb -> get_col ( $wpdb -> prepare ( " SELECT link_id FROM $wpdb->links WHERE link_owner = %d " , $id ) );
$wpdb -> update ( $wpdb -> links , array ( 'link_owner' => $reassign ), array ( 'link_owner' => $id ) );
2012-09-10 15:56:08 -04:00
if ( ! empty ( $link_ids ) ) {
2017-11-30 18:11:00 -05:00
foreach ( $link_ids as $link_id ) {
2012-09-10 15:56:08 -04:00
clean_bookmark_cache ( $link_id );
2017-11-30 18:11:00 -05:00
}
2012-09-10 15:56:08 -04:00
}
2007-05-25 03:16:21 -04:00
}
2020-01-28 19:45:18 -05:00
// FINALLY, delete user.
2012-04-24 18:13:47 -04:00
if ( is_multisite () ) {
remove_user_from_blog ( $id , get_current_blog_id () );
2010-01-14 19:21:13 -05:00
} else {
2012-04-24 18:13:47 -04:00
$meta = $wpdb -> get_col ( $wpdb -> prepare ( " SELECT umeta_id FROM $wpdb->usermeta WHERE user_id = %d " , $id ) );
2017-11-30 18:11:00 -05:00
foreach ( $meta as $mid ) {
2012-04-24 18:13:47 -04:00
delete_metadata_by_mid ( 'user' , $mid );
2017-11-30 18:11:00 -05:00
}
2012-04-24 18:13:47 -04:00
$wpdb -> delete ( $wpdb -> users , array ( 'ID' => $id ) );
2010-01-14 19:21:13 -05:00
}
2007-05-25 03:16:21 -04:00
2012-04-18 17:24:53 -04:00
clean_user_cache ( $user );
2013-12-01 12:54:10 -05:00
/**
* Fires immediately after a user is deleted from the database .
*
* @ since 2.9 . 0
2020-07-05 06:57:01 -04:00
* @ since 5.5 . 0 Added the `$user` parameter .
2013-12-01 12:54:10 -05:00
*
2014-03-07 22:16:14 -05:00
* @ param int $id ID of the deleted user .
* @ param int | null $reassign ID of the user to reassign posts and links to .
* Default null , for no reassignment .
2020-07-05 06:57:01 -04:00
* @ param WP_User $user WP_User object of the deleted user .
2013-12-01 12:54:10 -05:00
*/
2020-07-05 06:57:01 -04:00
do_action ( 'deleted_user' , $id , $reassign , $user );
2007-05-25 03:16:21 -04:00
return true ;
}
2008-10-01 21:03:26 -04:00
/**
* Remove all capabilities from user .
*
2010-12-01 14:24:38 -05:00
* @ since 2.1 . 0
2008-10-01 21:03:26 -04:00
*
* @ param int $id User ID .
*/
2017-11-30 18:11:00 -05:00
function wp_revoke_user ( $id ) {
2007-05-25 03:16:21 -04:00
$id = ( int ) $id ;
2017-11-30 18:11:00 -05:00
$user = new WP_User ( $id );
2007-05-25 03:16:21 -04:00
$user -> remove_all_caps ();
}
2010-12-01 14:24:38 -05:00
/**
* @ since 2.8 . 0
2015-05-28 17:41:30 -04:00
*
* @ global int $user_ID
*
* @ param false $errors Deprecated .
*/
2017-11-30 18:11:00 -05:00
function default_password_nag_handler ( $errors = false ) {
2009-05-06 12:19:40 -04:00
global $user_ID ;
2014-07-17 05:14:16 -04:00
// Short-circuit it.
2017-11-30 18:11:00 -05:00
if ( ! get_user_option ( 'default_password_nag' ) ) {
2009-05-06 12:19:40 -04:00
return ;
2017-11-30 18:11:00 -05:00
}
2009-05-06 12:19:40 -04:00
2020-01-28 19:45:18 -05:00
// get_user_setting() = JS-saved UI setting. Else no-js-fallback code.
2020-05-16 14:42:12 -04:00
if ( 'hide' === get_user_setting ( 'default_password_nag' )
|| isset ( $_GET [ 'default_password_nag' ] ) && '0' == $_GET [ 'default_password_nag' ]
) {
2017-11-30 18:11:00 -05:00
delete_user_setting ( 'default_password_nag' );
update_user_option ( $user_ID , 'default_password_nag' , false , true );
2009-05-03 13:06:29 -04:00
}
}
2009-05-06 12:19:40 -04:00
2010-12-01 14:24:38 -05:00
/**
* @ since 2.8 . 0
2015-05-29 16:17:26 -04:00
*
2020-10-18 16:53:08 -04:00
* @ param int $user_ID
* @ param WP_User $old_data
2010-12-01 14:24:38 -05:00
*/
2017-11-30 18:11:00 -05:00
function default_password_nag_edit_user ( $user_ID , $old_data ) {
2014-07-17 05:14:16 -04:00
// Short-circuit it.
2017-11-30 18:11:00 -05:00
if ( ! get_user_option ( 'default_password_nag' , $user_ID ) ) {
2009-05-06 12:19:40 -04:00
return ;
2017-11-30 18:11:00 -05:00
}
2009-05-06 12:19:40 -04:00
2017-11-30 18:11:00 -05:00
$new_data = get_userdata ( $user_ID );
2009-05-06 12:19:40 -04:00
2014-07-17 05:14:16 -04:00
// Remove the nag if the password has been changed.
if ( $new_data -> user_pass != $old_data -> user_pass ) {
2017-11-30 18:11:00 -05:00
delete_user_setting ( 'default_password_nag' );
update_user_option ( $user_ID , 'default_password_nag' , false , true );
2009-05-06 12:19:40 -04:00
}
}
2010-12-01 14:24:38 -05:00
/**
* @ since 2.8 . 0
2015-05-28 17:41:30 -04:00
*
* @ global string $pagenow
2010-12-01 14:24:38 -05:00
*/
2009-05-03 13:06:29 -04:00
function default_password_nag () {
2010-09-13 12:49:04 -04:00
global $pagenow ;
2014-07-17 05:14:16 -04:00
// Short-circuit it.
2020-05-16 14:42:12 -04:00
if ( 'profile.php' === $pagenow || ! get_user_option ( 'default_password_nag' ) ) {
2009-05-03 13:06:29 -04:00
return ;
2017-11-30 18:11:00 -05:00
}
2009-05-03 13:06:29 -04:00
2010-04-20 13:15:07 -04:00
echo '<div class="error default-password-nag">' ;
echo '<p>' ;
2017-11-30 18:11:00 -05:00
echo '<strong>' . __ ( 'Notice:' ) . '</strong> ' ;
_e ( 'You’re using the auto-generated password for your account. Would you like to change it?' );
2010-04-27 17:57:18 -04:00
echo '</p><p>' ;
2017-11-30 18:11:00 -05:00
printf ( '<a href="%s">' . __ ( 'Yes, take me to my profile page' ) . '</a> | ' , get_edit_profile_url () . '#password' );
printf ( '<a href="%s" id="default-password-nag-no">' . __ ( 'No thanks, do not remind me again' ) . '</a>' , '?default_password_nag=0' );
2009-05-03 13:06:29 -04:00
echo '</p></div>' ;
}
2015-09-10 12:47:24 -04:00
/**
* @ since 3.5 . 0
* @ access private
*/
2017-11-30 18:11:00 -05:00
function delete_users_add_js () {
?>
2015-09-10 12:47:24 -04:00
< script >
jQuery ( document ) . ready ( function ( $ ) {
var submit = $ ( '#submit' ) . prop ( 'disabled' , true );
$ ( 'input[name="delete_option"]' ) . one ( 'change' , function () {
submit . prop ( 'disabled' , false );
});
$ ( '#reassign_user' ) . focus ( function () {
$ ( '#delete_option1' ) . prop ( 'checked' , true ) . trigger ( 'change' );
});
});
</ script >
2018-08-16 21:51:36 -04:00
< ? php
2015-09-10 17:33:33 -04:00
}
/**
* Optional SSL preference that can be turned on by hooking to the 'personal_options' action .
*
2016-05-23 13:28:27 -04:00
* See the { @ see 'personal_options' } action .
*
2015-09-10 17:33:33 -04:00
* @ since 2.7 . 0
*
2019-12-07 08:23:01 -05:00
* @ param WP_User $user User data object .
2015-09-10 17:33:33 -04:00
*/
2017-11-30 18:11:00 -05:00
function use_ssl_preference ( $user ) {
2018-08-16 21:51:36 -04:00
?>
2015-09-10 17:33:33 -04:00
< tr class = " user-use-ssl-wrap " >
2017-11-30 18:11:00 -05:00
< th scope = " row " >< ? php _e ( 'Use https' ); ?> </th>
< td >< label for = " use_ssl " >< input name = " use_ssl " type = " checkbox " id = " use_ssl " value = " 1 " < ? php checked ( '1' , $user -> use_ssl ); ?> /> <?php _e( 'Always use https when visiting the admin' ); ?></label></td>
2015-09-10 17:33:33 -04:00
</ tr >
2018-08-16 21:51:36 -04:00
< ? php
2015-09-10 17:33:33 -04:00
}
/**
I18N: Improve translator comments.
* Add missing translator comments.
* Fix placement of some translator comments. Translator comments should be on the line directly above the line containing the translation function call for optimal compatibility with various `.pot` file generation tools. The CS auto-fixing, which changed some inconsistent function calls to multi-line function calls, is part of the reason why this was no longer the case for a select group of translator comments.
Includes minor code layout fixes.
Polyglots, rejoice! All WordPress core files now have translator comments for all strings with placeholders!
Props jrf, subrataemfluence, GaryJ, webdados, Dency, swissspidy, alvarogois, marcomartins, mihaiiceyro, vladwtz, niq1982, flipkeijzer, michielatyoast, chandrapatel, thrijith, joshuanoyce, FesoVik, tessak22, bhaktirajdev, cleancoded, dhavalkasvala, garrett-eclipse, bibliofille, socalchristina, priyankkpatel, 5hel2l2y, adamsilverstein, JeffPaul, pierlo, SergeyBiryukov.
Fixes #44360.
Built from https://develop.svn.wordpress.org/trunk@45926
git-svn-id: http://core.svn.wordpress.org/trunk@45737 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-01 13:13:59 -04:00
* @ since MU ( 3.0 . 0 )
*
2015-09-10 17:33:33 -04:00
* @ param string $text
* @ return string
*/
function admin_created_user_email ( $text ) {
$roles = get_editable_roles ();
2017-11-30 18:11:00 -05:00
$role = $roles [ $_REQUEST [ 'role' ] ];
I18N: Improve translator comments.
* Add missing translator comments.
* Fix placement of some translator comments. Translator comments should be on the line directly above the line containing the translation function call for optimal compatibility with various `.pot` file generation tools. The CS auto-fixing, which changed some inconsistent function calls to multi-line function calls, is part of the reason why this was no longer the case for a select group of translator comments.
Includes minor code layout fixes.
Polyglots, rejoice! All WordPress core files now have translator comments for all strings with placeholders!
Props jrf, subrataemfluence, GaryJ, webdados, Dency, swissspidy, alvarogois, marcomartins, mihaiiceyro, vladwtz, niq1982, flipkeijzer, michielatyoast, chandrapatel, thrijith, joshuanoyce, FesoVik, tessak22, bhaktirajdev, cleancoded, dhavalkasvala, garrett-eclipse, bibliofille, socalchristina, priyankkpatel, 5hel2l2y, adamsilverstein, JeffPaul, pierlo, SergeyBiryukov.
Fixes #44360.
Built from https://develop.svn.wordpress.org/trunk@45926
git-svn-id: http://core.svn.wordpress.org/trunk@45737 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-09-01 13:13:59 -04:00
2017-11-30 18:11:00 -05:00
return sprintf (
2019-09-02 20:41:05 -04:00
/* translators: 1: Site title, 2: Site URL, 3: User role. */
2017-11-30 18:11:00 -05:00
__ (
' Hi ,
2015-09-10 17:33:33 -04:00
You\ ' ve been invited to join \ ' % 1 $s\ ' at
% 2 $s with the role of % 3 $s .
If you do not want to join this site please ignore
this email . This invitation will expire in a few days .
Please click the following link to activate your user account :
2017-11-30 18:11:00 -05:00
%% s '
2018-08-16 21:51:36 -04:00
),
wp_specialchars_decode ( get_bloginfo ( 'name' ), ENT_QUOTES ),
home_url (),
wp_specialchars_decode ( translate_user_role ( $role [ 'name' ] ) )
2017-11-30 18:11:00 -05:00
);
2015-09-25 00:44:25 -04:00
}
REST API: Introduce Application Passwords for API authentication.
In WordPress 4.4 the REST API was first introduced. A few releases later in WordPress 4.7, the Content API endpoints were added, paving the way for Gutenberg and countless in-site experiences. In the intervening years, numerous plugins have built on top of the REST API. Many developers shared a common frustration, the lack of external authentication to the REST API.
This commit introduces Application Passwords to allow users to connect to external applications to their WordPress website. Users can generate individual passwords for each application, allowing for easy revocation and activity monitoring. An authorization flow is introduced to make the connection flow simple for users and application developers.
Application Passwords uses Basic Authentication, and by default is only available over an SSL connection.
Props georgestephanis, kasparsd, timothyblynjacobs, afercia, akkspro, andraganescu, arippberger, aristath, austyfrosty, ayesh, batmoo, bradyvercher, brianhenryie, helen, ipstenu, jeffmatson, jeffpaul, joostdevalk, joshlevinson, kadamwhite, kjbenk, koke, michael-arestad, Otto42, pekz0r, salzano, spacedmonkey, valendesigns.
Fixes #42790.
Built from https://develop.svn.wordpress.org/trunk@49109
git-svn-id: http://core.svn.wordpress.org/trunk@48871 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2020-10-08 18:14:06 -04:00
/**
* Checks if the Authorize Application Password request is valid .
*
* @ since 5.6 . 0
*
* @ param array $request {
* The array of request data . All arguments are optional and may be empty .
*
* @ type string $app_name The suggested name of the application .
2020-10-22 11:06:09 -04:00
* @ type string $app_id A uuid provided by the application to uniquely identify it .
REST API: Introduce Application Passwords for API authentication.
In WordPress 4.4 the REST API was first introduced. A few releases later in WordPress 4.7, the Content API endpoints were added, paving the way for Gutenberg and countless in-site experiences. In the intervening years, numerous plugins have built on top of the REST API. Many developers shared a common frustration, the lack of external authentication to the REST API.
This commit introduces Application Passwords to allow users to connect to external applications to their WordPress website. Users can generate individual passwords for each application, allowing for easy revocation and activity monitoring. An authorization flow is introduced to make the connection flow simple for users and application developers.
Application Passwords uses Basic Authentication, and by default is only available over an SSL connection.
Props georgestephanis, kasparsd, timothyblynjacobs, afercia, akkspro, andraganescu, arippberger, aristath, austyfrosty, ayesh, batmoo, bradyvercher, brianhenryie, helen, ipstenu, jeffmatson, jeffpaul, joostdevalk, joshlevinson, kadamwhite, kjbenk, koke, michael-arestad, Otto42, pekz0r, salzano, spacedmonkey, valendesigns.
Fixes #42790.
Built from https://develop.svn.wordpress.org/trunk@49109
git-svn-id: http://core.svn.wordpress.org/trunk@48871 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2020-10-08 18:14:06 -04:00
* @ type string $success_url The url the user will be redirected to after approving the application .
* @ type string $reject_url The url the user will be redirected to after rejecting the application .
* }
* @ param WP_User $user The user authorizing the application .
* @ return true | WP_Error True if the request is valid , a WP_Error object contains errors if not .
*/
function wp_is_authorize_application_password_request_valid ( $request , $user ) {
$error = new WP_Error ();
if ( ! empty ( $request [ 'success_url' ] ) ) {
$scheme = wp_parse_url ( $request [ 'success_url' ], PHP_URL_SCHEME );
if ( 'http' === $scheme ) {
$error -> add (
'invalid_redirect_scheme' ,
__ ( 'The success url must be served over a secure connection.' )
);
}
}
if ( ! empty ( $request [ 'reject_url' ] ) ) {
$scheme = wp_parse_url ( $request [ 'reject_url' ], PHP_URL_SCHEME );
if ( 'http' === $scheme ) {
$error -> add (
'invalid_redirect_scheme' ,
__ ( 'The rejection url must be served over a secure connection.' )
);
}
}
2020-10-22 11:06:09 -04:00
if ( ! empty ( $request [ 'app_id' ] ) && ! wp_is_uuid ( $request [ 'app_id' ] ) ) {
$error -> add (
'invalid_app_id' ,
__ ( 'The app id must be a uuid.' )
);
}
REST API: Introduce Application Passwords for API authentication.
In WordPress 4.4 the REST API was first introduced. A few releases later in WordPress 4.7, the Content API endpoints were added, paving the way for Gutenberg and countless in-site experiences. In the intervening years, numerous plugins have built on top of the REST API. Many developers shared a common frustration, the lack of external authentication to the REST API.
This commit introduces Application Passwords to allow users to connect to external applications to their WordPress website. Users can generate individual passwords for each application, allowing for easy revocation and activity monitoring. An authorization flow is introduced to make the connection flow simple for users and application developers.
Application Passwords uses Basic Authentication, and by default is only available over an SSL connection.
Props georgestephanis, kasparsd, timothyblynjacobs, afercia, akkspro, andraganescu, arippberger, aristath, austyfrosty, ayesh, batmoo, bradyvercher, brianhenryie, helen, ipstenu, jeffmatson, jeffpaul, joostdevalk, joshlevinson, kadamwhite, kjbenk, koke, michael-arestad, Otto42, pekz0r, salzano, spacedmonkey, valendesigns.
Fixes #42790.
Built from https://develop.svn.wordpress.org/trunk@49109
git-svn-id: http://core.svn.wordpress.org/trunk@48871 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2020-10-08 18:14:06 -04:00
/**
* Fires before application password errors are returned .
*
* @ since 5.6 . 0
*
* @ param WP_Error $error The error object .
* @ param array $request The array of request data .
* @ param WP_User $user The user authorizing the application .
*/
do_action ( 'wp_authorize_application_password_request_errors' , $error , $request , $user );
if ( $error -> has_errors () ) {
return $error ;
}
return true ;
}