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!
/wp-admin/
, you want them to be redirected to/resources
? Are you sure that theelseif
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 reachedelseif ( 'staff' === $role_name && ($_REQUEST['redirect_to'] == $admin_url || empty( $_REQUEST['redirect_to'] )))