[wp-trac] [WordPress Trac] #32799: Deleting Multisite users does not delete their content

WordPress Trac noreply at wordpress.org
Fri Jun 26 21:03:58 UTC 2015

#32799: Deleting Multisite users does not delete their content
 Reporter:  johnrom       |      Owner:
     Type:  defect (bug)  |     Status:  new
 Priority:  normal        |  Milestone:  Awaiting Review
Component:  Users         |    Version:  4.2.1
 Severity:  normal        |   Keywords:
  Focuses:                |
 Deletion of a user from multisite through the interface does not work
 properly when attempting to delete all content, because
 `remove_user_from_blog` is called before `wpmu_delete_user`

 By the time `wpmu_delete_user` is called, it checks for
 `get_blogs_of_user`, which will be empty because the users were just
 removed from each blog. `remove_user_from_blog` will reassign posts, but
 not delete them. Therefore, `wpmu_delete_user` never deletes the user's
 posts because they have already been removed from the blog.

 If `wpmu_delete_user` is called programmatically, it does remove the
 posts, because it calls `remove_user_from_blog` after it gets the result
 of `get_blogs_of_user`.

 From what I can tell, removing `else remove_user_from_blog()` when not
 reassigning a post should be enough to fix the bug entirely, since it will
 be called later when wpmu_delete_user is called.

 The above lines are 223-224 of /wp-admin/network/users.php (4.2.1)

 My temporary fix is posted below for any who need a quick result. Please
 note that this is only tested on 4.2.1, and that it may affect
 programmatic calls to `remove_user_from_blog()`. It's impossible to check
 if a programmatic call to this function is attempting to reassign content
 since the $reassign value is not passed to this filter.

 function maybe_force_delete_user_posts( $user_id, $blog_id ) {

         // donno
         if ( empty( $user_id ) || empty( $blog_id ) )

         // if reassigning, do not delete posts
         if ( ! empty( $_POST['delete'] ) && 'reassign' ==
 $_POST['delete'][ $blog_id ][ $user_id ] )

         // we're probably on the delete page for this user if this is not
         // this is not a flawless check
         if ( empty( $_POST['blog'][ $user_id ] )

         global $wpdb;

         switch_to_blog( $blog_id );

         $post_ids = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM
 $wpdb->posts WHERE post_author = %d", $user_id ) );
         foreach ( (array) $post_ids as $post_id ) {
                 wp_delete_post( $post_id );

         // Clean links
         $link_ids = $wpdb->get_col( $wpdb->prepare( "SELECT link_id FROM
 $wpdb->links WHERE link_owner = %d", $user_id ) );

         if ( $link_ids ) {
                 foreach ( $link_ids as $link_id )
                         wp_delete_link( $link_id );

 add_action('remove_user_from_blog', 'maybe_force_delete_user_posts', 10, 2

Ticket URL: <https://core.trac.wordpress.org/ticket/32799>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform

More information about the wp-trac mailing list