user.php 20 KB

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