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:

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;
	}

	// Check if enabled
	$checked = checked( get_user_option( 'rc_banned', $user_id, false ) );

	// Display checkbox
	echo '<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" '. $checked .' />Ban this user</label>
		</td>
	</tr>
	</table>';
}

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

Post Author:

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)

Disclosure: This page contains external affiliate links that may result in us receiving a comission if you choose to purchase said product. The opinions on this page are our own. We do not receive payment for positive reviews.
Got something to say? Join the discussion.
  1. AJ Clarke | WPExplorer says:
    AJ Clarke | WPExplorer

    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?

    • AJ Clarke | WPExplorer says:
      AJ Clarke | WPExplorer

      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?

  8. Geoffrey says:

    Hi there,
    Good work Remi.
    Little typo here :

    if( isset( $_POST['rc_ban'] ) &amp;&amp; $_POST['rc_ban'] = 'on' )

    A single equal makes the control true. You have to use double (simple control) or triple equal (strict control).
    Thank you.
    Geoffrey

  9. Ryan Dye says:

    Hi,

    I’ve tried to use this but when I login a banned account it shows the error on the wp-login page but it doesn’t stop them all they have to do is navigate to a new page…

    Also, if they’re logged in then the same problem happens they don’t get logged out.

    Any ideas

Leave a Reply