-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Better guide users when deleting other users in single- and multisites #10502
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: trunk
Are you sure you want to change the base?
Changes from all commits
342f997
58b709f
fcb23c1
6328326
abc9cc9
1ac17bd
908a25c
c2b7fbd
b366373
1d4cd34
87143da
4e057d0
afe1012
9d5385d
0add334
4fbfce2
271ca0a
c3e3a89
a2798e8
ef2fc0f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -1589,3 +1589,14 @@ function image_attachment_fields_to_save( $post, $attachment ) { | |||||
|
|
||||||
| return $post; | ||||||
| } | ||||||
|
|
||||||
| /** | ||||||
| * Was used to add JavaScript to the delete users form. | ||||||
| * | ||||||
| * @since 3.5.0 | ||||||
| * @deprecated 6.9.0 | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| * @access private | ||||||
| */ | ||||||
| function delete_users_add_js() { | ||||||
| _deprecated_function( __FUNCTION__, '6.9.0' ); | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| } | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -860,30 +860,31 @@ function _thickbox_path_admin_subfolder() { | |
| * @return bool | ||
| */ | ||
| function confirm_delete_users( $users ) { | ||
| global $wpdb; | ||
|
|
||
| $current_user = wp_get_current_user(); | ||
| if ( ! is_array( $users ) || empty( $users ) ) { | ||
| return false; | ||
| } | ||
|
|
||
| ?> | ||
| <h1><?php esc_html_e( 'Users' ); ?></h1> | ||
| <h1><?php esc_html_e( 'Delete Users' ); ?></h1> | ||
|
|
||
| <?php if ( 1 === count( $users ) ) : ?> | ||
| <p><?php _e( 'You have chosen to delete the user from all networks and sites.' ); ?></p> | ||
| <?php else : ?> | ||
| <p><?php _e( 'You have chosen to delete the following users from all networks and sites.' ); ?></p> | ||
| <?php endif; ?> | ||
|
|
||
| <form action="users.php?action=dodelete" method="post"> | ||
| <form action="users.php?action=dodelete" method="post" class="delete-and-reassign-users-form"> | ||
| <input type="hidden" name="dodelete" /> | ||
| <?php | ||
| wp_nonce_field( 'ms-users-delete' ); | ||
| $site_admins = get_super_admins(); | ||
| $admin_out = '<option value="' . esc_attr( $current_user->ID ) . '">' . $current_user->user_login . '</option>'; | ||
| ?> | ||
| <table class="form-table" role="presentation"> | ||
| <?php | ||
| $allusers = (array) $_POST['allusers']; | ||
| foreach ( $allusers as $user_id ) { | ||
| foreach ( $users as $user_id ) { | ||
| if ( '' !== $user_id && '0' !== $user_id ) { | ||
| $delete_user = get_userdata( $user_id ); | ||
|
|
||
|
|
@@ -906,6 +907,7 @@ function confirm_delete_users( $users ) { | |
| ) | ||
| ); | ||
| } | ||
|
|
||
| ?> | ||
| <tr> | ||
| <th scope="row"><?php echo $delete_user->user_login; ?> | ||
|
|
@@ -930,46 +932,91 @@ function confirm_delete_users( $users ) { | |
| $blog_users = get_users( | ||
| array( | ||
| 'blog_id' => $details->userblog_id, | ||
| 'fields' => array( 'ID', 'user_login' ), | ||
| 'fields' => array( 'ID' ), | ||
| 'exclude' => $users, | ||
| ) | ||
| ); | ||
|
|
||
| $blog_users = wp_list_pluck( $blog_users, 'ID' ); | ||
|
|
||
| if ( is_array( $blog_users ) && ! empty( $blog_users ) ) { | ||
| $user_site = "<a href='" . esc_url( get_home_url( $details->userblog_id ) ) . "'>{$details->blogname}</a>"; | ||
| $user_dropdown = '<label for="reassign_user" class="screen-reader-text">' . | ||
| /* translators: Hidden accessibility text. */ | ||
| __( 'Select a user' ) . | ||
| '</label>'; | ||
| $user_dropdown .= "<select name='blog[$user_id][$key]' id='reassign_user'>"; | ||
| $user_list = ''; | ||
|
|
||
| foreach ( $blog_users as $user ) { | ||
| if ( ! in_array( (int) $user->ID, $allusers, true ) ) { | ||
| $user_list .= "<option value='{$user->ID}'>{$user->user_login}</option>"; | ||
| $user_site = "<a href='" . esc_url( get_home_url( $details->userblog_id ) ) . "'>{$details->blogname}</a>"; | ||
| switch_to_blog( $details->userblog_id ); | ||
| /* This filter is documented in wp-admin/users.php */ | ||
| $user_has_content = (bool) apply_filters( 'users_have_additional_content', false, array( $delete_user->ID ) ); | ||
|
|
||
| if ( ! $user_has_content ) { | ||
| if ( $wpdb->get_var( | ||
| $wpdb->prepare( | ||
| "SELECT ID FROM {$wpdb->posts} | ||
| WHERE post_author = %d | ||
| LIMIT 1", | ||
| $delete_user->ID | ||
| ) | ||
| ) ) { | ||
| $user_has_content = true; | ||
| } elseif ( $wpdb->get_var( | ||
| $wpdb->prepare( | ||
| "SELECT link_id FROM {$wpdb->links} | ||
| WHERE link_owner = %d | ||
| LIMIT 1", | ||
| $delete_user->ID | ||
| ) | ||
| ) ) { | ||
| $user_has_content = true; | ||
| } | ||
| } | ||
|
|
||
| if ( '' === $user_list ) { | ||
| $user_list = $admin_out; | ||
| } | ||
|
|
||
| $user_dropdown .= $user_list; | ||
| $user_dropdown .= "</select>\n"; | ||
| ?> | ||
| <ul style="list-style:none;"> | ||
| <li> | ||
| restore_current_blog(); | ||
|
|
||
| if ( ! $user_has_content ) { | ||
| ?> | ||
| <p> | ||
| <?php | ||
| /* translators: %s: Link to user's site. */ | ||
| printf( __( 'Site: %s' ), $user_site ); | ||
| ?> | ||
| </p> | ||
| <input type="hidden" id="delete_option_<?php echo esc_attr( $details->userblog_id . '_' . $delete_user->ID ); ?>" name="delete[<?php echo $details->userblog_id . '][' . $delete_user->ID; ?>]" value="delete" required /> | ||
| <p><?php _e( 'This user does not have any content.' ); ?></p> | ||
| <?php | ||
| } else { | ||
| ?> | ||
| <p> | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be a
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The fieldset is already present, but:
Change the It's preferable to place the username first, as that minimizes the discovery and makes the list easier to scan. |
||
| <?php | ||
| /* translators: %s: Link to user's site. */ | ||
| printf( __( 'Site: %s' ), $user_site ); | ||
| ?> | ||
| </p> | ||
| <ul> | ||
| <li> | ||
| <label> | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid using implicit |
||
| <input type="radio" id="delete_option_<?php echo esc_attr( $details->userblog_id . '_' . $delete_user->ID ); ?>" name="delete[<?php echo $details->userblog_id . '][' . $delete_user->ID; ?>]" value="delete" required /> | ||
| <?php _e( 'Delete all content.' ); ?> | ||
| </label> | ||
| </li> | ||
| <li> | ||
| <label> | ||
| <input type="radio" id="reassign_option_<?php echo esc_attr( $details->userblog_id . '_' . $delete_user->ID ); ?>" name="delete[<?php echo $details->userblog_id . '][' . $delete_user->ID; ?>]" value="reassign" required /> | ||
| <?php _e( 'Attribute all content to:' ); ?> | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is combining the radio for reassigning & the label for the dropdown into a single field. This is confusing, and leaves the dropdown unlabeled. Separate these into two explicitly separate fields with independent labels. Avoid using implicit |
||
| </label> | ||
|
|
||
| <?php | ||
| wp_dropdown_users( | ||
| array( | ||
| 'show_option_none' => __( 'Select a user' ), | ||
| 'name' => "blog[$user_id][$key]", | ||
| 'include' => $blog_users, | ||
| 'show' => 'display_name_with_login', | ||
| 'id' => "reassign_user_{$details->userblog_id}_{$delete_user->ID}", | ||
| ) | ||
| ); | ||
| ?> | ||
|
|
||
| </li> | ||
| </li> | ||
| <li><label><input type="radio" id="delete_option0" name="delete[<?php echo $details->userblog_id . '][' . $delete_user->ID; ?>]" value="delete" checked="checked" /> | ||
| <?php _e( 'Delete all content.' ); ?></label></li> | ||
| <li><label><input type="radio" id="delete_option1" name="delete[<?php echo $details->userblog_id . '][' . $delete_user->ID; ?>]" value="reassign" /> | ||
| <?php _e( 'Attribute all content to:' ); ?></label> | ||
| <?php echo $user_dropdown; ?></li> | ||
| </ul> | ||
| <?php | ||
| </ul> | ||
| <?php | ||
| } | ||
| } | ||
| } | ||
| echo '</fieldset></td></tr>'; | ||
|
|
@@ -986,7 +1033,7 @@ function confirm_delete_users( $users ) { | |
| </table> | ||
| <?php | ||
| /** This action is documented in wp-admin/users.php */ | ||
| do_action( 'delete_user_form', $current_user, $allusers ); | ||
| do_action( 'delete_user_form', $current_user, $users ); | ||
|
|
||
| if ( 1 === count( $users ) ) : | ||
| ?> | ||
|
|
@@ -996,7 +1043,7 @@ function confirm_delete_users( $users ) { | |
| <?php | ||
| endif; | ||
|
|
||
| submit_button( __( 'Confirm Deletion' ), 'primary' ); | ||
| submit_button( __( 'Confirm Deletion' ), 'primary', 'submit', false, array( 'id' => 'confirm-users-deletion' ) ); | ||
| ?> | ||
| </form> | ||
| <?php | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For accessibility, it would be preferable to throw an error if not all radio decisions have been resolved instead of disabling the submit button. Disabled buttons aren't discoverable by assistive technology, so it becomes difficult for a screen reader user to identify what's missing.
The error would need to notify the user with useful information, e.g. how many items still need to be completed, and ideally would also provide easy access to reach the incomplete fields. (Which can be a pain if you have three missing decisions but 100 users to sort through.)