Deleting sites and users automatically in multisite

Note — as Kaiser rightly points out in his comment, Multisite shares users between sites. If you remove one, you remove her from all the sites in your network. If that’s not your intent, then look into remove_user_from_blog().


Instead of wp_delete_user(), use wpmu_delete_user(). Looking at the source code, wpmu_delete_user() first checks if the user in question is a user on any sites in the network, removes her if she is, cleans up any links and metadata associated with her account, and then finally deletes the user as you’d expect.

This WordPress support thread is what pointed me in this direction.

Re-assigning posts before deleting the user

From the source of wpmu_delete_user():

do_action( 'wpmu_delete_user', $id );

$blogs = get_blogs_of_user( $id );

if ( ! empty( $blogs ) ) {
        foreach ( $blogs as $blog ) {
                switch_to_blog( $blog->userblog_id );
                remove_user_from_blog( $id, $blog->userblog_id );

                $post_ids = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_author = %d", $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", $id ) );

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

                restore_current_blog();
        }
}

So the default action when deleting a user programmatically is to find and remove her posts from every site (blog) where she’s a user. However, there is an action hook that runs just before, conveniently named wpmu_delete_user. So you should be able to programmatically re-assign the to-be-deleted user’s posts before you delete her:

add_action( 'wpmu_delete_user', 'wpse130705_reassign_posts' );
function wpse130705_reassign_posts( $id ) {
    // $id should contain the user's ID
    $blogs = get_blogs_of_user( $id );
    $assign_to = 99; // some other user's ID; you'll have to work out what this will be
    if( ! empty( $blogs ) ) {
        foreach( $blogs as $blog ) {
            switch_to_blog( $blog->userblog_id );
            $post_ids = $wpdb->get_col( 
                $wpdb->prepare( 
                    "SELECT ID FROM $wpdb->posts WHERE post_author=%d", $id 
                )
            );
            if( $post_ids ) {
                foreach( $post_ids as $post_id ) {
                    $wpdb->update( 
                        $table = $wpdb->posts,
                        $data  = array( 'post_author' => $assign_to ),
                        $where = array( 'post_author' => $id ),
                        $format="%d",
                        $where_format="%d"
                    );
                }
            }
            restore_current_blog();
        }
    }
}

Leave a Comment