/wp-admin/includes/user.php

  1. <?php 
  2. /** 
  3. * WordPress user administration API. 
  4. * 
  5. * @package WordPress 
  6. * @subpackage Administration 
  7. */ 
  8.  
  9. /** 
  10. * Creates a new user from the "Users" form using $_POST information. 
  11. * 
  12. * @since 2.0.0 
  13. * 
  14. * @return int|WP_Error WP_Error or User ID. 
  15. */ 
  16. function add_user() { 
  17. return edit_user(); 
  18.  
  19. /** 
  20. * Edit user settings based on contents of $_POST 
  21. * 
  22. * Used on user-edit.php and profile.php to manage and process user options, passwords etc. 
  23. * 
  24. * @since 2.0.0 
  25. * 
  26. * @param int $user_id Optional. User ID. 
  27. * @return int|WP_Error user id of the updated user 
  28. */ 
  29. function edit_user( $user_id = 0 ) { 
  30. $wp_roles = wp_roles(); 
  31. $user = new stdClass; 
  32. if ( $user_id ) { 
  33. $update = true; 
  34. $user->ID = (int) $user_id; 
  35. $userdata = get_userdata( $user_id ); 
  36. $user->user_login = wp_slash( $userdata->user_login ); 
  37. } else { 
  38. $update = false; 
  39.  
  40. if ( !$update && isset( $_POST['user_login'] ) ) 
  41. $user->user_login = sanitize_user($_POST['user_login'], true); 
  42.  
  43. $pass1 = $pass2 = ''; 
  44. if ( isset( $_POST['pass1'] ) ) 
  45. $pass1 = $_POST['pass1']; 
  46. if ( isset( $_POST['pass2'] ) ) 
  47. $pass2 = $_POST['pass2']; 
  48.  
  49. if ( isset( $_POST['role'] ) && current_user_can( 'edit_users' ) ) { 
  50. $new_role = sanitize_text_field( $_POST['role'] ); 
  51. $potential_role = isset($wp_roles->role_objects[$new_role]) ? $wp_roles->role_objects[$new_role] : false; 
  52. // Don't let anyone with 'edit_users' (admins) edit their own role to something without it. 
  53. // Multisite super admins can freely edit their blog roles -- they possess all caps. 
  54. if ( ( is_multisite() && current_user_can( 'manage_sites' ) ) || $user_id != get_current_user_id() || ($potential_role && $potential_role->has_cap( 'edit_users' ) ) ) 
  55. $user->role = $new_role; 
  56.  
  57. // If the new role isn't editable by the logged-in user die with error 
  58. $editable_roles = get_editable_roles(); 
  59. if ( ! empty( $new_role ) && empty( $editable_roles[$new_role] ) ) 
  60. wp_die(__('You can’t give users that role.')); 
  61.  
  62. if ( isset( $_POST['email'] )) 
  63. $user->user_email = sanitize_text_field( wp_unslash( $_POST['email'] ) ); 
  64. if ( isset( $_POST['url'] ) ) { 
  65. if ( empty ( $_POST['url'] ) || $_POST['url'] == 'http://' ) { 
  66. $user->user_url = ''; 
  67. } else { 
  68. $user->user_url = esc_url_raw( $_POST['url'] ); 
  69. $protocols = implode( '|', array_map( 'preg_quote', wp_allowed_protocols() ) ); 
  70. $user->user_url = preg_match('/^(' . $protocols . '):/is', $user->user_url) ? $user->user_url : 'http://'.$user->user_url; 
  71. if ( isset( $_POST['first_name'] ) ) 
  72. $user->first_name = sanitize_text_field( $_POST['first_name'] ); 
  73. if ( isset( $_POST['last_name'] ) ) 
  74. $user->last_name = sanitize_text_field( $_POST['last_name'] ); 
  75. if ( isset( $_POST['nickname'] ) ) 
  76. $user->nickname = sanitize_text_field( $_POST['nickname'] ); 
  77. if ( isset( $_POST['display_name'] ) ) 
  78. $user->display_name = sanitize_text_field( $_POST['display_name'] ); 
  79.  
  80. if ( isset( $_POST['description'] ) ) 
  81. $user->description = trim( $_POST['description'] ); 
  82.  
  83. foreach ( wp_get_user_contact_methods( $user ) as $method => $name ) { 
  84. if ( isset( $_POST[$method] )) 
  85. $user->$method = sanitize_text_field( $_POST[$method] ); 
  86.  
  87. if ( $update ) { 
  88. $user->rich_editing = isset( $_POST['rich_editing'] ) && 'false' == $_POST['rich_editing'] ? 'false' : 'true'; 
  89. $user->admin_color = isset( $_POST['admin_color'] ) ? sanitize_text_field( $_POST['admin_color'] ) : 'fresh'; 
  90. $user->show_admin_bar_front = isset( $_POST['admin_bar_front'] ) ? 'true' : 'false'; 
  91. $user->locale = ''; 
  92.  
  93. if ( isset( $_POST['locale'] ) ) { 
  94. $locale = sanitize_text_field( $_POST['locale'] ); 
  95. if ( 'site-default' === $locale ) { 
  96. $locale = ''; 
  97. } elseif ( '' === $locale ) { 
  98. $locale = 'en_US'; 
  99. } elseif ( ! in_array( $locale, get_available_languages(), true ) ) { 
  100. $locale = ''; 
  101.  
  102. $user->locale = $locale; 
  103.  
  104. $user->comment_shortcuts = isset( $_POST['comment_shortcuts'] ) && 'true' == $_POST['comment_shortcuts'] ? 'true' : ''; 
  105.  
  106. $user->use_ssl = 0; 
  107. if ( !empty($_POST['use_ssl']) ) 
  108. $user->use_ssl = 1; 
  109.  
  110. $errors = new WP_Error(); 
  111.  
  112. /** checking that username has been typed */ 
  113. if ( $user->user_login == '' ) 
  114. $errors->add( 'user_login', __( '<strong>ERROR</strong>: Please enter a username.' ) ); 
  115.  
  116. /** checking that nickname has been typed */ 
  117. if ( $update && empty( $user->nickname ) ) { 
  118. $errors->add( 'nickname', __( '<strong>ERROR</strong>: Please enter a nickname.' ) ); 
  119.  
  120. /** 
  121. * Fires before the password and confirm password fields are checked for congruity. 
  122. * 
  123. * @since 1.5.1 
  124. * 
  125. * @param string $user_login The username. 
  126. * @param string &$pass1 The password, passed by reference. 
  127. * @param string &$pass2 The confirmed password, passed by reference. 
  128. */ 
  129. do_action_ref_array( 'check_passwords', array( $user->user_login, &$pass1, &$pass2 ) ); 
  130.  
  131. // Check for blank password when adding a user. 
  132. if ( ! $update && empty( $pass1 ) ) { 
  133. $errors->add( 'pass', __( '<strong>ERROR</strong>: Please enter a password.' ), array( 'form-field' => 'pass1' ) ); 
  134.  
  135. // Check for "\" in password. 
  136. if ( false !== strpos( wp_unslash( $pass1 ), "\\" ) ) { 
  137. $errors->add( 'pass', __( '<strong>ERROR</strong>: Passwords may not contain the character "\\".' ), array( 'form-field' => 'pass1' ) ); 
  138.  
  139. // Checking the password has been typed twice the same. 
  140. if ( ( $update || ! empty( $pass1 ) ) && $pass1 != $pass2 ) { 
  141. $errors->add( 'pass', __( '<strong>ERROR</strong>: Please enter the same password in both password fields.' ), array( 'form-field' => 'pass1' ) ); 
  142.  
  143. if ( !empty( $pass1 ) ) 
  144. $user->user_pass = $pass1; 
  145.  
  146. if ( !$update && isset( $_POST['user_login'] ) && !validate_username( $_POST['user_login'] ) ) 
  147. $errors->add( 'user_login', __( '<strong>ERROR</strong>: This username is invalid because it uses illegal characters. Please enter a valid username.' )); 
  148.  
  149. if ( !$update && username_exists( $user->user_login ) ) 
  150. $errors->add( 'user_login', __( '<strong>ERROR</strong>: This username is already registered. Please choose another one.' )); 
  151.  
  152. /** This filter is documented in wp-includes/user.php */ 
  153. $illegal_logins = (array) apply_filters( 'illegal_user_logins', array() ); 
  154.  
  155. if ( in_array( strtolower( $user->user_login ), array_map( 'strtolower', $illegal_logins ) ) ) { 
  156. $errors->add( 'invalid_username', __( '<strong>ERROR</strong>: Sorry, that username is not allowed.' ) ); 
  157.  
  158. /** checking email address */ 
  159. if ( empty( $user->user_email ) ) { 
  160. $errors->add( 'empty_email', __( '<strong>ERROR</strong>: Please enter an email address.' ), array( 'form-field' => 'email' ) ); 
  161. } elseif ( !is_email( $user->user_email ) ) { 
  162. $errors->add( 'invalid_email', __( '<strong>ERROR</strong>: The email address isn’t correct.' ), array( 'form-field' => 'email' ) ); 
  163. } elseif ( ( $owner_id = email_exists($user->user_email) ) && ( !$update || ( $owner_id != $user->ID ) ) ) { 
  164. $errors->add( 'email_exists', __('<strong>ERROR</strong>: This email is already registered, please choose another one.'), array( 'form-field' => 'email' ) ); 
  165.  
  166. /** 
  167. * Fires before user profile update errors are returned. 
  168. * 
  169. * @since 2.8.0 
  170. * 
  171. * @param WP_Error &$errors WP_Error object, passed by reference. 
  172. * @param bool $update Whether this is a user update. 
  173. * @param stdClass &$user User object, passed by reference. 
  174. */ 
  175. do_action_ref_array( 'user_profile_update_errors', array( &$errors, $update, &$user ) ); 
  176.  
  177. if ( $errors->get_error_codes() ) 
  178. return $errors; 
  179.  
  180. if ( $update ) { 
  181. $user_id = wp_update_user( $user ); 
  182. } else { 
  183. $user_id = wp_insert_user( $user ); 
  184. $notify = isset( $_POST['send_user_notification'] ) ? 'both' : 'admin'; 
  185.  
  186. /** 
  187. * Fires after a new user has been created. 
  188. * 
  189. * @since 4.4.0 
  190. * 
  191. * @param int $user_id ID of the newly created user. 
  192. * @param string $notify Type of notification that should happen. See wp_send_new_user_notifications() 
  193. * for more information on possible values. 
  194. */ 
  195. do_action( 'edit_user_created_user', $user_id, $notify ); 
  196. return $user_id; 
  197.  
  198. /** 
  199. * Fetch a filtered list of user roles that the current user is 
  200. * allowed to edit. 
  201. * 
  202. * Simple function who's main purpose is to allow filtering of the 
  203. * list of roles in the $wp_roles object so that plugins can remove 
  204. * inappropriate ones depending on the situation or user making edits. 
  205. * Specifically because without filtering anyone with the edit_users 
  206. * capability can edit others to be administrators, even if they are 
  207. * only editors or authors. This filter allows admins to delegate 
  208. * user management. 
  209. * 
  210. * @since 2.8.0 
  211. * 
  212. * @return array 
  213. */ 
  214. function get_editable_roles() { 
  215. $all_roles = wp_roles()->roles; 
  216.  
  217. /** 
  218. * Filters the list of editable roles. 
  219. * 
  220. * @since 2.8.0 
  221. * 
  222. * @param array $all_roles List of roles. 
  223. */ 
  224. $editable_roles = apply_filters( 'editable_roles', $all_roles ); 
  225.  
  226. return $editable_roles; 
  227.  
  228. /** 
  229. * Retrieve user data and filter it. 
  230. * 
  231. * @since 2.0.5 
  232. * 
  233. * @param int $user_id User ID. 
  234. * @return WP_User|bool WP_User object on success, false on failure. 
  235. */ 
  236. function get_user_to_edit( $user_id ) { 
  237. $user = get_userdata( $user_id ); 
  238.  
  239. if ( $user ) 
  240. $user->filter = 'edit'; 
  241.  
  242. return $user; 
  243.  
  244. /** 
  245. * Retrieve the user's drafts. 
  246. * 
  247. * @since 2.0.0 
  248. * 
  249. * @global wpdb $wpdb WordPress database abstraction object. 
  250. * 
  251. * @param int $user_id User ID. 
  252. * @return array 
  253. */ 
  254. function get_users_drafts( $user_id ) { 
  255. global $wpdb; 
  256. $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); 
  257.  
  258. /** 
  259. * Filters the user's drafts query string. 
  260. * 
  261. * @since 2.0.0 
  262. * 
  263. * @param string $query The user's drafts query string. 
  264. */ 
  265. $query = apply_filters( 'get_users_drafts', $query ); 
  266. return $wpdb->get_results( $query ); 
  267.  
  268. /** 
  269. * Remove user and optionally reassign posts and links to another user. 
  270. * 
  271. * If the $reassign parameter is not assigned to a User ID, then all posts will 
  272. * be deleted of that user. The action {@see 'delete_user'} that is passed the User ID 
  273. * being deleted will be run after the posts are either reassigned or deleted. 
  274. * The user meta will also be deleted that are for that User ID. 
  275. * 
  276. * @since 2.0.0 
  277. * 
  278. * @global wpdb $wpdb WordPress database abstraction object. 
  279. * 
  280. * @param int $id User ID. 
  281. * @param int $reassign Optional. Reassign posts and links to new User ID. 
  282. * @return bool True when finished. 
  283. */ 
  284. function wp_delete_user( $id, $reassign = null ) { 
  285. global $wpdb; 
  286.  
  287. if ( ! is_numeric( $id ) ) { 
  288. return false; 
  289.  
  290. $id = (int) $id; 
  291. $user = new WP_User( $id ); 
  292.  
  293. if ( !$user->exists() ) 
  294. return false; 
  295.  
  296. // Normalize $reassign to null or a user ID. 'novalue' was an older default. 
  297. if ( 'novalue' === $reassign ) { 
  298. $reassign = null; 
  299. } elseif ( null !== $reassign ) { 
  300. $reassign = (int) $reassign; 
  301.  
  302. /** 
  303. * Fires immediately before a user is deleted from the database. 
  304. * 
  305. * @since 2.0.0 
  306. * 
  307. * @param int $id ID of the user to delete. 
  308. * @param int|null $reassign ID of the user to reassign posts and links to. 
  309. * Default null, for no reassignment. 
  310. */ 
  311. do_action( 'delete_user', $id, $reassign ); 
  312.  
  313. if ( null === $reassign ) { 
  314. $post_types_to_delete = array(); 
  315. foreach ( get_post_types( array(), 'objects' ) as $post_type ) { 
  316. if ( $post_type->delete_with_user ) { 
  317. $post_types_to_delete[] = $post_type->name; 
  318. } elseif ( null === $post_type->delete_with_user && post_type_supports( $post_type->name, 'author' ) ) { 
  319. $post_types_to_delete[] = $post_type->name; 
  320.  
  321. /** 
  322. * Filters the list of post types to delete with a user. 
  323. * 
  324. * @since 3.4.0 
  325. * 
  326. * @param array $post_types_to_delete Post types to delete. 
  327. * @param int $id User ID. 
  328. */ 
  329. $post_types_to_delete = apply_filters( 'post_types_to_delete_with_user', $post_types_to_delete, $id ); 
  330. $post_types_to_delete = implode( "', '", $post_types_to_delete ); 
  331. $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 ) ); 
  332. if ( $post_ids ) { 
  333. foreach ( $post_ids as $post_id ) 
  334. wp_delete_post( $post_id ); 
  335.  
  336. // Clean links 
  337. $link_ids = $wpdb->get_col( $wpdb->prepare("SELECT link_id FROM $wpdb->links WHERE link_owner = %d", $id) ); 
  338.  
  339. if ( $link_ids ) { 
  340. foreach ( $link_ids as $link_id ) 
  341. wp_delete_link($link_id); 
  342. } else { 
  343. $post_ids = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_author = %d", $id ) ); 
  344. $wpdb->update( $wpdb->posts, array('post_author' => $reassign), array('post_author' => $id) ); 
  345. if ( ! empty( $post_ids ) ) { 
  346. foreach ( $post_ids as $post_id ) 
  347. clean_post_cache( $post_id ); 
  348. $link_ids = $wpdb->get_col( $wpdb->prepare("SELECT link_id FROM $wpdb->links WHERE link_owner = %d", $id) ); 
  349. $wpdb->update( $wpdb->links, array('link_owner' => $reassign), array('link_owner' => $id) ); 
  350. if ( ! empty( $link_ids ) ) { 
  351. foreach ( $link_ids as $link_id ) 
  352. clean_bookmark_cache( $link_id ); 
  353.  
  354. // FINALLY, delete user 
  355. if ( is_multisite() ) { 
  356. remove_user_from_blog( $id, get_current_blog_id() ); 
  357. } else { 
  358. $meta = $wpdb->get_col( $wpdb->prepare( "SELECT umeta_id FROM $wpdb->usermeta WHERE user_id = %d", $id ) ); 
  359. foreach ( $meta as $mid ) 
  360. delete_metadata_by_mid( 'user', $mid ); 
  361.  
  362. $wpdb->delete( $wpdb->users, array( 'ID' => $id ) ); 
  363.  
  364. clean_user_cache( $user ); 
  365.  
  366. /** 
  367. * Fires immediately after a user is deleted from the database. 
  368. * 
  369. * @since 2.9.0 
  370. * 
  371. * @param int $id ID of the deleted user. 
  372. * @param int|null $reassign ID of the user to reassign posts and links to. 
  373. * Default null, for no reassignment. 
  374. */ 
  375. do_action( 'deleted_user', $id, $reassign ); 
  376.  
  377. return true; 
  378.  
  379. /** 
  380. * Remove all capabilities from user. 
  381. * 
  382. * @since 2.1.0 
  383. * 
  384. * @param int $id User ID. 
  385. */ 
  386. function wp_revoke_user($id) { 
  387. $id = (int) $id; 
  388.  
  389. $user = new WP_User($id); 
  390. $user->remove_all_caps(); 
  391.  
  392. /** 
  393. * @since 2.8.0 
  394. * 
  395. * @global int $user_ID 
  396. * 
  397. * @param false $errors Deprecated. 
  398. */ 
  399. function default_password_nag_handler($errors = false) { 
  400. global $user_ID; 
  401. // Short-circuit it. 
  402. if ( ! get_user_option('default_password_nag') ) 
  403. return; 
  404.  
  405. // get_user_setting = JS saved UI setting. else no-js-fallback code. 
  406. if ( 'hide' == get_user_setting('default_password_nag') || isset($_GET['default_password_nag']) && '0' == $_GET['default_password_nag'] ) { 
  407. delete_user_setting('default_password_nag'); 
  408. update_user_option($user_ID, 'default_password_nag', false, true); 
  409.  
  410. /** 
  411. * @since 2.8.0 
  412. * 
  413. * @param int $user_ID 
  414. * @param object $old_data 
  415. */ 
  416. function default_password_nag_edit_user($user_ID, $old_data) { 
  417. // Short-circuit it. 
  418. if ( ! get_user_option('default_password_nag', $user_ID) ) 
  419. return; 
  420.  
  421. $new_data = get_userdata($user_ID); 
  422.  
  423. // Remove the nag if the password has been changed. 
  424. if ( $new_data->user_pass != $old_data->user_pass ) { 
  425. delete_user_setting('default_password_nag'); 
  426. update_user_option($user_ID, 'default_password_nag', false, true); 
  427.  
  428. /** 
  429. * @since 2.8.0 
  430. * 
  431. * @global string $pagenow 
  432. */ 
  433. function default_password_nag() { 
  434. global $pagenow; 
  435. // Short-circuit it. 
  436. if ( 'profile.php' == $pagenow || ! get_user_option('default_password_nag') ) 
  437. return; 
  438.  
  439. echo '<div class="error default-password-nag">'; 
  440. echo '<p>'; 
  441. echo '<strong>' . __('Notice:') . '</strong> '; 
  442. _e('You’re using the auto-generated password for your account. Would you like to change it?'); 
  443. echo '</p><p>'; 
  444. printf( '<a href="%s">' . __('Yes, take me to my profile page') . '</a> | ', get_edit_profile_url() . '#password' ); 
  445. printf( '<a href="%s" id="default-password-nag-no">' . __('No thanks, do not remind me again') . '</a>', '?default_password_nag=0' ); 
  446. echo '</p></div>'; 
  447.  
  448. /** 
  449. * @since 3.5.0 
  450. * @access private 
  451. */ 
  452. function delete_users_add_js() { ?> 
  453. <script> 
  454. jQuery(document).ready( function($) { 
  455. var submit = $('#submit').prop('disabled', true); 
  456. $('input[name="delete_option"]').one('change', function() { 
  457. submit.prop('disabled', false); 
  458. }); 
  459. $('#reassign_user').focus( function() { 
  460. $('#delete_option1').prop('checked', true).trigger('change'); 
  461. }); 
  462. }); 
  463. </script> 
  464. <?php 
  465.  
  466. /** 
  467. * Optional SSL preference that can be turned on by hooking to the 'personal_options' action. 
  468. * 
  469. * See the {@see 'personal_options'} action. 
  470. * 
  471. * @since 2.7.0 
  472. * 
  473. * @param object $user User data object 
  474. */ 
  475. function use_ssl_preference($user) { 
  476. ?> 
  477. <tr class="user-use-ssl-wrap"> 
  478. <th scope="row"><?php _e('Use https')?></th> 
  479. <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> 
  480. </tr> 
  481. <?php 
  482.  
  483. /** 
  484. * 
  485. * @param string $text 
  486. * @return string 
  487. */ 
  488. function admin_created_user_email( $text ) { 
  489. $roles = get_editable_roles(); 
  490. $role = $roles[ $_REQUEST['role'] ]; 
  491. /** translators: 1: Site name, 2: site URL, 3: role */ 
  492. return sprintf( __( 'Hi,  
  493. You\'ve been invited to join \'%1$s\' at 
  494. %2$s with the role of %3$s. 
  495. If you do not want to join this site please ignore 
  496. this email. This invitation will expire in a few days. 
  497.  
  498. Please click the following link to activate your user account: 
  499. %%s' ), get_bloginfo( 'name' ), home_url(), wp_specialchars_decode( translate_user_role( $role['name'] ) ) ); 
.