How To Ban A WordPress User

How To Ban A WordPress User

I was asked a few days ago to create a system would ban a WordPress user from an install. So I created a simple plugin and I wanted to share with you the basics of this plugin. In this tutorial we will be covering WordPress filters, actions, users columns management and some more great things.

Step 1: Create The Plugin

Once again, here it’s very complicated, all you have to do is to create a new folder with “wp-content/plugins” called “ban-users”. In this folder, create a new file called “ban-users.php”, open it an paste this code:

<?php
/*
Plugin Name: Ban Users
Plugin URI: http://www.remicorson.com
Description: Allows you to ban users
Author: Remi Corson
Version: 1.0
Author URI: http://www.remicorson.com
*/

Step 2: Add A Checkbox On Users’ Profile Page

The first thing we need to to do is to add a checkbox on each user profile edition page. When you’ll check this checkbox it will store a user meta option that will indicated that the user isn’t allowed anymore to login to your website.

Here is the code:

/**
 * Admin init
 *
 * @access      public
 * @since       1.0 
 * @return      void
*/
function rc_admin_init(){
    
	// Edit user profile
	add_action( 'edit_user_profile', 'rc_edit_user_profile' );
	add_action( 'edit_user_profile_update', 'rc_edit_user_profile_update' );
	
}
add_action('admin_init', 'rc_admin_init' );

This code is simply creating a call to a function that we have to create now. This function will add a checkbox to users profile page.

/**
 * Adds custom checkbox to user edition page
 *
 * @access      public
 * @since       1.0 
 * @return      void
*/
function rc_edit_user_profile() {
	if ( !current_user_can( 'edit_users' ) ) {
		return;
	}
	
	global $user_id;
	
	// User cannot disable itself
	$current_user = wp_get_current_user();
	$current_user_id = $current_user->ID;
	if ( $current_user_id == $user_id ) {
		return;
	}
	?>
	<table class="form-table">
	<tr>
		<th scope="row">Ban User</th>
		<td>
		<label for="rc_ban">
			<input name="rc_ban" type="checkbox" id="rc_ban" <?php if ( get_user_option( 'rc_banned', $user_id, false ) ) echo ' checked="checked"'; ?> />Ban this user</label>
		</td>
	</tr>
	</table>
	<?php
}

We now need to have the function that will save into the database the value of the checkbox:

/**
 * Save custom checkbox
 *
 * @access      public
 * @since       1.0 
 * @return      void
*/
function rc_edit_user_profile_update() {
			
	if ( !current_user_can( 'edit_users' ) ) {
		return;
	}
	
	global $user_id;
	
	// User cannot disable itself
	$current_user    = wp_get_current_user();
	$current_user_id = $current_user->ID;
	if ( $current_user_id == $user_id ) {
		return;
	}
	
	// Lock
	if( isset( $_POST['rc_ban'] ) && $_POST['rc_ban'] = 'on' ) {
		rc_ban_user( $user_id );
	} else { // Unlock
		rc_unban_user( $user_id );
	}
	
}

As you can see this new function uses two other functions: rc_ban_users() and rc_unban_users(). Their names are pretty explicit, the first one will store in the database the fact that a user is ban, the second will unlock users.

Step 3: Ban Users

It’s now time to create the rc_ban_users() function. In this function we need to check if a value is already stored, and if not we need to store the value. That’s the reason why i call a function that I’ll describe later: rc_is_user_banned():

/**
 * Ban user
 *
 * @access      public
 * @since       1.0 
 * @return      void
*/
function rc_ban_user( $user_id ) {
	
	$old_status = rc_is_user_banned( $user_id );
	
	// Update status
	if ( !$old_status ) {
		update_user_option( $user_id, 'rc_banned', true, false );
	}
}

Step 4: Un-ban Users

The following function is the opposite as the one we just created: we have to give the ability to “un-ban” users:

/**
 * Un-ban user
 *
 * @access      public
 * @since       1.0 
 * @return      void
*/
function rc_unban_user( $user_id ) {

	$old_status = rc_is_user_banned( $user_id );
	
	// Update status
	if ( $old_status ) {
		update_user_option( $user_id, 'rc_banned', false, false );
	}
}

Step 5: Is User Banned?

We saw in rc_ban_users() and rc_unban_users() that we use a function called rc_is_user_banned() to check if a user is banned or not. Let’s create it:

/**
 * Checks if a user is already banned
 *
 * @access      public
 * @since       1.0 
 * @return      void
*/
function rc_is_user_banned( $user_id ) {
	return get_user_option( 'rc_banned', $user_id, false );
}

Basically, this function simply returns the value of the option saved in rc_ban_users().

At this time we have a new checkbox on the user edition page that should like that:

ban_users_1

The last step is to hook a function to the login form to avoid banned users to login.

Step 5: Avoid Banned Users To Login

To do so we need to use a WordPress default filter called “wp_authenticate_user”. To this  filter we’ll hook a function called “rc_authenticate_user()”. This function will use the WP_Error class.

/**
 * Check if user is locked while login process
 *
 * @access      public
 * @since       1.0 
 * @return      void
*/
function rc_authenticate_user( $user ) {

	if ( is_wp_error( $user ) ) {
		return $user;
	}
	
	// Return error if user account is banned
	$banned = get_user_option( 'rc_banned', $user->ID, false );
	if ( $banned ) {
		return new WP_Error( 'rc_banned', __('<strong>ERROR</strong>: This user account is disabled.', 'rc') );
	}
	
	return $user;
}

Now, we just need to add the filter:

add_filter( 'wp_authenticate_user', 'rc_authenticate_user', 1 );

Conclusion

We created a plugin that adds a checkbox to the user profile edition page. We used a second function to store the value on the checkbox and we create a function to ban a WordPress user and another on to unlock a user. We also created a small function to check if a user is banned or not. And we finally hooked a function to the “wp_authenticate_user” filter using the WP_Error WordPress default class.

If you liked this tutorial, you’ll love the premium version of this plugin: Users Access Manager.

Download Full Code On Github

Remi
Remi is an expert WordPress developer that coded many great free and premium themes and plugins. His experience on WordPress allows him to produce great stuff and to propose advanced tutorials. (remicorson.com)
Remi
This article has 11 comments
  1. AJ Clarke | WPExplorer says:

    This is great ;) Much better then simply deleting their account.

    Admin
  2. Elliott says:

    Nice article, I’m just curious, is there a reason why the first two actions are called on admin_init? Would they not work outside the function rc_admin_init?

  3. Mathew Porter says:

    Great functionality addition, I can see how simply suspending an account and then warning users is alot better than deleting the account like AJ Clarke mentioned.

  4. raj says:

    great method there, a bit differently I am trying to modify checkbox to be able to checked by default in the user profile field.

    php echo (esc_attr( get_the_author_meta( ‘filed_ID’, $user->ID ) ) ? ‘checked=”checked” ‘ : ‘ ‘);

    this code makes the checkbox disabled by default, how can i have it checked by default? any idea?

    1. AJ Clarke | WPExplorer says:

      I’m prety sure the meta value still needs to be registered into the database so even if it was checked by default, you would still have to re-save all your user meta options to register it. So I really don’t see a point.

      What might be better is to just switch your if statements. So if it is checked the the user is not banned and if it is not checked then they are. I’m, not really sure what you are trying to do…

      Admin
  5. Dragos says:

    Remi this is really great script,

    Implemented on my site, just one thing after banning anf reloading user page check box is not checked. If I save it again user is unbanned. You wanted like that to be?

    thanks Dragos

  6. Gibins says:

    Great tutorial but just one problem. If the admin clicks the checkbutton and saves the profile, when the profile page is reloaded, the button does not remain checked. How can we fix this so that it remains checked so that a different admin can clearly see that the user is banned…?

  7. Ava Zinn says:

    I managed to get step 1 creating the file, but became lost on Step 2. Does that go in the plugin file?

Leave a Reply