WordPress.org

Ready to get started?Download WordPress

Forums

[resolved] wp_delete_user bug in multisite? (16 posts)

  1. Eddie Krebs
    Member
    Posted 2 years ago #

    I am using wp_delete_user and it's returning true, but the user still exists in the database.

    I looked at the code in user.php function wp_delete_user( $id, $reassign ), and it looks to me like the line of code to delete the user is completely missing, if you are running multisite. Am I missing something here?

    Here is the code from user.php:

    // FINALLY, delete user
    	if ( !is_multisite() ) {
    		$wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE user_id = %d", $id) );
    		$wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->users WHERE ID = %d", $id) );
    	} else {
    		$level_key = $wpdb->get_blog_prefix() . 'capabilities'; // wpmu site admins don't have user_levels
    		$wpdb->query("DELETE FROM $wpdb->usermeta WHERE user_id = $id AND meta_key = '{$level_key}'");
    	}
  2. I am using wp_delete_user

    In your own code or just trying to delete a user from the network admin?

  3. Eddie Krebs
    Member
    Posted 2 years ago #

    Hi Ipstenu, thanks for the response.

    I am using a custom user creation screen, with a checkbox to auto-create a blog for the created user. This auto-creation creates some custom site meta data and associates the user with the site.

    The code logic creates the user, then attempts to create the site. If the site creation fails for some reason, it deletes the user and returns the error to the admin. Only, the code doesn't delete the user as expected.

    Here is the relevant code. $aws_site returns null (site creation fails), and the code inside the if statement gets executed. The $user_id is valid and wp_delete_user returns 1. However, the user is still in the database, and the "deleted" field remains 0 in the wp_users table.

    $site_id = $aws_site->create( $_POST[ 'subdomain' ], $user_id );
    
    if ( is_null( $site_id ) ) {
        $msg = $aws_site->error_message;
        wp_delete_user( $user_id ); // roll back user creation
    }
  4. Eddie Krebs
    Member
    Posted 2 years ago #

    Just to follow up, the code I pasted from user.php is confusing me because I literally do not see the line of code to delete the user. Maybe that code is hidden in some called procedure that I missed?

    The else statement below runs if is_multisite is true. I see the query to delete the user meta, but no code to delete the user from the wp_users table. If that code is actually missing it would produce my issue.

    } else {
        $level_key = $wpdb->get_blog_prefix() . 'capabilities';
        $wpdb->query("DELETE FROM $wpdb->usermeta WHERE user_id = $id AND meta_key = '{$level_key}'");
    }

    I highly doubt I found a bug in WordPress. I just can't find where the "delete from $wpdb->users" code is.

  5. I am using a custom user creation screen, with a checkbox to auto-create a blog for the created user.

    I got hung up on that ...

    You DO know that's a feature built into WP right? Are you doing this just to make a custom styled screen for new users or something else?

    I suspect it's not deleting because that's a restricted function to super-admins.

  6. Eddie Krebs
    Member
    Posted 2 years ago #

    I do understand that. We're not using WordPress as a multi-blog platform, but as an engine to allow customers to create multiple websites with different functionality for their employees. It's very specialized. If I hooked into the user editor, I would be removing just about everything already there and adding my own functionality in the hooks. It sure seems more efficient if I write half the code and get all the functionality I need.

    WordPress has functions like wp_delete_user and wp_insert_user for just this purpose.

    I get what you're saying, and I've evaluated the pros and cons of this approach. I believe the custom screen is the best for our application.

    To answer your follow up suspicion, I am logged in as the super admin. There are two users in the test environment: the super admin and the user to be deleted. There are two sites (blogs), the initial blog and one I created (blog_id 4 in this case). I am logged into Blog ID 4 as super admin. The user is a Subscriber of blog_id 4.

  7. Yeah, I think you're going at it the wrong way (easier to add into the existing stuff than re-write it all). That's what we do with BuddyPress and all the plugins that let you set default settings or custom tweaks when accounts are added (like the LDAP integration).

    But.

    Are you creating these IDs as the super admin or are un-registered people coming to domain.com/signuppage and registering?

    If YOU are adding them, then yes, the commands should work. If THEY are adding themSELVES, then it doesn't run as super admin, y'see.

  8. Eddie Krebs
    Member
    Posted 2 years ago #

    I'll take your advice and look into using hooks again instead of a custom user editor. I'm not convinced yet this is the proper method for us because of the scope of our application, but I'll look at BuddyPress closely and see if we just missed the boat somehow.

    None of this changes the fact that the wp_delete_user method seems to fail. When logged in as a super admin, running this method returns true but does not actually delete the user. The key question is this: does this method work for anyone else in a multisite setup, or is it broken?

  9. I've never called wp_delete_user anywhere outside of the built in delete user command on the users.php page, so at a guess, it MUST work (since I can delete users the 'right' way).

    You may want to ping the WP Hackers email list to ask the right way to delete a user, though. I suspect it'd have something to do with the nonces, but I'm stabbing in the dark and likely to be eaten by a grue.

  10. ShinichiN
    Member
    Posted 2 years ago #

    // FINALLY, delete user
    	if ( !is_multisite() ) {
    		$wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->usermeta WHERE user_id = %d", $id) );
    		$wpdb->query( $wpdb->prepare("DELETE FROM $wpdb->users WHERE ID = %d", $id) );
    	} else {
    		$level_key = $wpdb->get_blog_prefix() . 'capabilities'; // wpmu site admins don't have user_levels
    		$wpdb->query("DELETE FROM $wpdb->usermeta WHERE user_id = $id AND meta_key = '{$level_key}'");
    	}
    
    	// allow for commit transaction
    	do_action('deleted_user', $id);

    Isn't it possible to delete user by hooking additional codes to the "deleted_user" hook?

    like:

    if ( is_multisite() ) {
    	delete it!
    }
  11. Eddie Krebs
    Member
    Posted 2 years ago #

    Hi ShinichiN. Yes, you almost certainly could hook into the deleted_user action and run the delete code yourself. That's a good workaround for someone in my situation, thanks.

    I think the best solution is to propose this as a bug and see what the core developers say. I just wanted to pass it through the forums first and see if I missed something obvious.

  12. Tim Moore
    Moderator
    Posted 2 years ago #

    This isn't actually a bug, AFAIK.

    If you are in single site mode, this function allows you to directly delete a user from the database since you don't have to worry about the user being attached to any other network site.

    If you are in Network mode, however, a non-Network Admin may want to "delete" the user from their site on the network, which is what this function does. It removes the user from the site without harming the user's status on other sites in the Network.

    You'll find that for Multi Site, in /wp-admin/network/users.php there is a different function that handles deleting users in such a way that all of the blogs a user is associated with don't get broken when the user is actually deleted from the database.

  13. Eddie Krebs
    Member
    Posted 2 years ago #

    Tim, this makes perfect sense and is exactly the information I was digging for. Thanks a ton!

  14. gomez.rudy
    Member
    Posted 2 years ago #

    Great post, lost of help.

    Can someone please list the function that completely delete a use from a multisite network?

  15. Eddie Krebs
    Member
    Posted 2 years ago #

    gomez, try wpmu_delete_user. Pretty obvious once you know about it.

    http://codex.wordpress.org/Function_Reference/wpmu_delete_user

  16. gomez.rudy
    Member
    Posted 2 years ago #

    Worked great. Plugin done.

    Sorry if I missed something so obvious, only been working with WordPress for a couple of months.

    Thanks again Eddie.

Topic Closed

This topic has been closed to new replies.

About this Topic