0

I have a particular issue. I have only 2 roles on my site, admin and a secondary role used for various administrative tasks in the backend.

This secondary role needs to normally redirect to a frontend page when they login, UNLESS the redirect_to URL parameter is set while they're logging in.

I have tried using login_redirect, but to no avail. Here is what I currently have:

function redirect_users_by_role() {

if ( ! defined( 'DOING_AJAX' ) ) {

    $current_user   = wp_get_current_user();
    $role_name      = $current_user->roles[0];
    $admin_url = home_url().'/wp-admin/';

    if ( 'subscriber' === $role_name ) {
        wp_safe_redirect( home_url('/access-denied') );
    }

    if (empty($role_name)) {
        wp_safe_redirect( home_url('/access-denied') );
    } 

    if ( 'staff' === $role_name && isset($_REQUEST['redirect_to']) && !empty($_REQUEST['redirect_to']) ) {
        wp_safe_redirect( $_REQUEST['redirect_to'] );
    }

    elseif ( 'staff' === $role_name && $_REQUEST['redirect_to'] == $admin_url ) {
        wp_safe_redirect( home_url('/resources')); exit;
    }

} // DOING_AJAX

} // redirect_users_by_role

add_action( 'admin_init', 'redirect_users_by_role' );

If a user with a role of staff logs in and redirect_to is empty when the login_redirect POSTs to itself, then they should go to home_url().'/resources', otherwise, if they're logging in with the role of staff but redirect_to IS set, then they should be redirected to that. I have been completely unable to figure this out. Any help is greatly appreciated.

UPDATE

Here is what I ultimately ended up doing to get this to work. Since this is a very specific instance in my user flow, I doubt it will be helpful to anyone, but I wanted to make sure I added the working solution, anyway.

function admin_login_redirect( $url, $request, $user ){
    //is there a user
    if( $user && is_object( $user ) && is_a( $user, 'WP_User' ) ) {
        //is user admin
        if( $user->has_cap( 'administrator' ) ) {
            //go do admin stuff
            $url = admin_url();
            //but wait there's more
        }
    }
    return $url;
}
add_filter('login_redirect', 'admin_login_redirect', 10, 3 );

function staff_login_redirect( $url, $request, $user ){
    if( $user && is_object( $user ) && is_a( $user, 'WP_User' ) ) {
        if( $user->has_cap('staff') && strpos($_REQUEST['redirect_to'], 'gf_entries') == false )  {
            //please god work
            $url = home_url() . '/resources';
            //but waittt there's more
        } else {
            //damnit all
            if( $user->has_cap('staff') && isset($_REQUEST['redirect_to']) && strpos($_REQUEST['redirect_to'], 'gf_entries') !== false) {

            $url = $_REQUEST['redirect_to'];

            }
        }
    }
    return $url;
}
add_filter('login_redirect', 'staff_login_redirect', 10, 3 );

function transient_login_redirect( $url, $request, $user ) {
    if ( $user && is_object( $user ) && is_a( $user, 'WP_User' ) ) {
        if (!$user->has_cap('administrator') && !$user->has_cap('staff') ) {
        //go away
        $url= home_url('/access-denied');
        }
    }
    return $url;
}
add_filter('login_redirect', 'transient_login_redirect', 10, 3);

The final solution was to check for several things, on top of splitting up the logic into different functions and hook into the login_redirect hook.

For admins, I just send them wherever.

For staff, I check if they're going to the one place in the backend where they should be on any given day, gravity forms page 'gf_entries', using strpos(). If they're not headed to that area of wp-admin via the $_REQUEST['redirect_to'] parameter, then we send them over to /resources (my internal page for staff resources).

Thanks for your help everyone!

5
  • Are none of the redirects working? Commented Dec 6, 2016 at 21:25
  • @czerspalace The final elseif redirect doesn't work. It just takes the 'staff' user to /wp-admin/ instead of home_url()./resources. The others appear to be functioning.
    – Jordan W.
    Commented Dec 6, 2016 at 22:51
  • So if a user goes to /wp-admin/, you want them to be redirected to /resources? Are you sure that the elseif is being reached? Are you sure that the $_REQUEST['redirect_to'] == /wp-admin/? If the $_REQUEST['redirect_to'] is not set then the last elsif wont be reached Commented Dec 6, 2016 at 23:29
  • You might want to try elseif ( 'staff' === $role_name && ($_REQUEST['redirect_to'] == $admin_url || empty( $_REQUEST['redirect_to'] ))) Commented Dec 6, 2016 at 23:33
  • @czerspalace Yes, 'staff' users should only be permitted into /wp-admin/ when they have a specific need to, e.g. redirect_to is set to an area inside /wp-admin/, specifically to a Gravity Forms /wp-admin/ page. I believe you're correct, that last elseif isn't being reached. I think my issue is the default behavior of redirect_to inside wp-login.php. I'm gonna try your code real fast.
    – Jordan W.
    Commented Dec 7, 2016 at 12:51

3 Answers 3

2

The login_redirect hook does seem to be the right hook.

Can you try this :

(Adapted from the Codex )

function redirect_users_by_role( $redirect_to, $request, $user ) {

    if ( isset( $user->roles ) && is_array( $user->roles ) ) {

        if ( in_array( 'staff', $user->roles ) ) {

            if ($admin_url === $request){

                return home_url('/resources');

            } else{

                return $redirect_to;

            }

        }
    } else {

        return home_url('/access-denied');

    }
}


add_filter( 'login_redirect', 'redirect_users_by_role', 10, 3 );
1

You might want to use a test like

if(current_user_can('edit_posts'))

rather than testing for a specific role name, so that you're basing it on capabilities that might be possessed or not by multiple roles. Depends on why you're trying to steer users away from the dashboard.

1
  • Good thinking. I'm going to adapt @pixline's suggestion and try to use capability tests instead.
    – Jordan W.
    Commented Dec 7, 2016 at 13:06
0

Here is what I ultimately ended up doing to get this to work. Since this is a very specific instance in my user flow, I doubt it will be helpful to anyone, but I wanted to make sure I added the working solution, anyway.

function admin_login_redirect( $url, $request, $user ){
    //is there a user
    if( $user && is_object( $user ) && is_a( $user, 'WP_User' ) ) {
        //is user admin
        if( $user->has_cap( 'administrator' ) ) {
            //go do admin stuff
            $url = admin_url();
            //but wait there's more
        }
    }
    return $url;
}
add_filter('login_redirect', 'admin_login_redirect', 10, 3 );

function staff_login_redirect( $url, $request, $user ){
    if( $user && is_object( $user ) && is_a( $user, 'WP_User' ) ) {
        if( $user->has_cap('staff') && strpos($_REQUEST['redirect_to'], 'gf_entries') == false )  {
            //please god work
            $url = home_url() . '/resources';
            //but waittt there's more
        } else {
            //damnit all
            if( $user->has_cap('staff') && isset($_REQUEST['redirect_to']) && strpos($_REQUEST['redirect_to'], 'gf_entries') !== false) {

            $url = $_REQUEST['redirect_to'];

            }
        }
    }
    return $url;
}
add_filter('login_redirect', 'staff_login_redirect', 10, 3 );

function transient_login_redirect( $url, $request, $user ) {
    if ( $user && is_object( $user ) && is_a( $user, 'WP_User' ) ) {
        if (!$user->has_cap('administrator') && !$user->has_cap('staff') ) {
        //go away
        $url= home_url('/access-denied');
        }
    }
    return $url;
}
add_filter('login_redirect', 'transient_login_redirect', 10, 3);

The final solution was to check for several things, on top of splitting up the logic into different functions and hook into the login_redirect hook.

For admins, I just send them wherever.

For staff, I check if they're going to the one place in the backend where they should be on any given day, gravity forms page 'gf_entries', using strpos(). If they're not headed to that area of wp-admin via the $_REQUEST['redirect_to'] parameter, then we send them over to /resources (my internal page for staff resources).

Thanks for your help everyone!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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