Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions src/js/_enqueues/admin/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -2354,3 +2354,59 @@ $( function( $ ) {
// Expose public methods.
return pub;
})();

/**
* Disable the submit button until all users radio buttons are checked.
*
* @since 7.0.0
*/
(function(){
const usersForm = document.querySelector( '.users-php .delete-and-reassign-users-form' );

// Check if the form exists and contains any radio buttons.
if ( ! usersForm || ! usersForm.querySelector( 'input[type="radio"]' ) ) {
return;
}

const submitBtn = usersForm.querySelector( 'input[type="submit"]' );

// Disable the submit button until all users radio buttons are checked.
submitBtn.disabled = true;

// Listen for changes on any radio input in the form.
usersForm.addEventListener('change', function() {
if ( ! usersForm.checkValidity() ) {
submitBtn.disabled = true;
return;
}

// Check all radio groups for validity.
let allValid = true;
const radioGroups = usersForm.querySelectorAll( 'fieldset ul' );
radioGroups.forEach( function( radioGroup ) {
const radios = radioGroup.querySelectorAll( 'input[type="radio"]' );
let checkedRadio = null;
radios.forEach( function( radio ) {
if ( radio.checked ) {
checkedRadio = radio;
}
});

if ( checkedRadio && checkedRadio.value === 'reassign' ) {
const select = radioGroup.querySelector( 'select' );
if ( select && select.value === '-1' ) {
allValid = false;
}
}
});

submitBtn.disabled = !allValid;
});

usersForm.querySelectorAll( 'select' ).forEach( function( selectElement ) {
selectElement.addEventListener( 'change', function( e ) {
const radio = e.target.closest( 'li' ).querySelector( 'input[type="radio"]' );
radio.checked = e.target.value !== '-1';
});
});
})();
11 changes: 11 additions & 0 deletions src/wp-admin/includes/deprecated.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
* @access private
*/
function delete_users_add_js() {
_deprecated_function( __FUNCTION__, '6.9.0' );
}
119 changes: 83 additions & 36 deletions src/wp-admin/includes/ms.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 );

Expand All @@ -906,6 +907,7 @@ function confirm_delete_users( $users ) {
)
);
}

?>
<tr>
<th scope="row"><?php echo $delete_user->user_login; ?>
Expand All @@ -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>
<?php
/* translators: %s: Link to user's site. */
printf( __( 'Site: %s' ), $user_site );
?>
</p>
<ul>
<li>
<label>
<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:' ); ?>
</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>';
Expand All @@ -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 ) ) :
?>
Expand All @@ -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
Expand Down
20 changes: 0 additions & 20 deletions src/wp-admin/includes/user.php
Original file line number Diff line number Diff line change
Expand Up @@ -561,26 +561,6 @@ function default_password_nag() {
);
}

/**
* @since 3.5.0
* @access private
*/
function delete_users_add_js() {
?>
<script>
jQuery( 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>
<?php
}

/**
* Optional SSL preference that can be turned on by hooking to the 'personal_options' action.
*
Expand Down
5 changes: 3 additions & 2 deletions src/wp-admin/network/users.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,9 @@

$doaction = $_POST['action'];
$userfunction = '';
$allusers = (array) $_POST['allusers'];

foreach ( (array) $_POST['allusers'] as $user_id ) {
foreach ( $allusers as $user_id ) {
if ( ! empty( $user_id ) ) {
switch ( $doaction ) {
case 'delete':
Expand All @@ -72,7 +73,7 @@
require_once ABSPATH . 'wp-admin/admin-header.php';

echo '<div class="wrap">';
confirm_delete_users( $_POST['allusers'] );
confirm_delete_users( $allusers );
echo '</div>';

require_once ABSPATH . 'wp-admin/admin-footer.php';
Expand Down
Loading
Loading