1

To reduce spam registrations, users are assigned the pending role until they're vetted (at which point they're assigned the subscriber role). The pending role has no capabilities. When pending users log in, I want to log them out immediately and direct them to a page with an explanation. First, I tried the following:

function logout_pending_users() {
    $current_user = wp_get_current_user() ;
    if ( ! $current_user->has_cap( 'read' ) ) {
        $url = 'https://example.com/pending/' ;
        wp_redirect( $url ) ;
        wp_logout() ;
        exit ;
    }
} add_action('wp_login', 'logout_pending_users') ;

Result: both pending and subscriber users are logged out. I tried inverting the order of wp_redirect() and wp_logout():

        $url = 'https://example.com/pending/' ;
        wp_logout() ;
        wp_redirect( $url ) ;
        exit ;

Same result. Then I tried checking roles instead of caps (I know, you shouldn't...):

function logout_pending_users() {
    $current_user = wp_get_current_user() ;
    $role = $current_user->roles[0] ;
    if ( $role === 'pending' ) {
        $url = 'https://example.com/pending/' ;
        wp_redirect( $url ) ;
        wp_logout() ;
        exit ;
    }
} add_action('wp_login', 'logout_pending_users') ;

Again, same result. Next, I tried something based on an example on the WP Developer site:

function logout_pending_users() {
    $current_user = wp_get_current_user() ;
    if ( ! $current_user->has_cap( 'read' ) ) {
        wp_logout() ;
    }
} add_action('wp_login', 'logout_pending_users');

function redirect_pending_users() {
    $current_user = wp_get_current_user() ;
    if ( ! $current_user->has_cap( 'read' ) ) {
        $url = 'https://example.com/pending/' ;
        wp_redirect( $url ) ;
        exit;
} add_action( 'wp_logout()', 'redirect_pending_users');

Result: both pending and subscriber users are stuck at the login page, with URL: https://example.com/wp-login.php?redirect_to=https%3A%2F%2Fexample.com%2Fwp-admin%2Fprofile.php&reauth=1

During each attempt, I verified that the pending role has no read capacity (or any capacity), and that the subscriber role does. I also verified that $current_user->roles[0] does, indeed, contain the correct role.

What am I missing? Is there another way? Thank you for any help!

2

1 Answer 1

0

There are a couple of "timing" issues you're running into here.

When you're calling wp_get_current_user() this isn't really available at the moment of logging in, so to capture the logging-in user, you have to use a slightly different approach.

The same is with logout, as it uses the same method of getting the current user.

In the solution below you're capturing the logging-in user directly from the wp_login hook, and then instead of calling wp_logout(), you're calling the actual functions that do the logging-out for you. And, instead of adding multiple hooks, you're doing it all within the one hook: wp_login

There's also a sanity check to ensure the $user is actually an \WP_User object, or you'll get a fatal error on checking the capability.

function logout_pending_users( $username, $user ) {
    
    if ( $user instanceof \WP_User && !$user->has_cap( 'read' ) ) {

        wp_destroy_current_session();
        wp_clear_auth_cookie();
        wp_set_current_user( 0 );
        
        wp_redirect( 'https://example.com/pending/' );
        
        exit;
    }
}
add_action( 'wp_login', 'logout_pending_users', 100, 2 );
3
  • Lots of great information here — and it works. Thank you!
    – arielsfr
    May 8, 2021 at 17:09
  • Could you accept the answer, please?
    – Paul G.
    May 9, 2021 at 20:18
  • FIrst-timer. Tried to accept it yesterday but couldn't find an 'Accept' button anywhere! Finally figured it out. Thank you again!
    – arielsfr
    May 9, 2021 at 21:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.