166

How can I check to see if the current logged-in user is an administrator or an editor?

I know how to do each individually:

<?php if(current_user_can('editor')) { ?> 
    <!-- Stuff here for editors -->
<?php } ?>

<?php if(current_user_can('administrator')) { ?>
    <!-- Stuff here for administrators -->
<?php } ?>

But how do I work those in together? I.e., the user is an administrator or editor?

1
  • 14
    if( current_user_can('editor') || current_user_can('administrator') )
    – Shazzad
    Jan 30, 2014 at 14:10

6 Answers 6

315

First answer, not WordPress-related because it is just only PHP: Use the logic "OR" operator:

<?php if( current_user_can('editor') || current_user_can('administrator') ) {  ?>
    // Stuff here for administrators or editors
<?php } ?>

If you want to check more than two roles, you can check if the roles of the current user is inside an array of roles, something like:

$user = wp_get_current_user();
$allowed_roles = array('editor', 'administrator', 'author');
<?php if( array_intersect($allowed_roles, $user->roles ) ) {  ?>
   // Stuff here for allowed roles
<?php } ?>

However, current_user_can can be used not only with users' role name, but also with capabilities.

So, once both editors and administrators can edit pages, your life can be easier checking for those capabilities:

<?php if( current_user_can('edit_others_pages') ) {  ?>
    // Stuff here for user roles that can edit pages: editors and administrators
<?php } ?>

Have a look here for more information on capabilities.

7
  • 2
    do you need to check if is_logged_in(); ?
    – RobBenz
    May 1, 2017 at 11:09
  • 4
    @RobBenz no, in any of the cases. Because current_user_can() always returns false if the user is not logged in, and wp_get_current_user() will return an user without any role if the user is not logged in, so the array_intersect() will always be false.
    – gmazzap
    May 1, 2017 at 18:46
  • 5
    In the PHPDoc of the current_user_can() function, we can see the line "While checking against particular roles in place of a capability is supported in part, this practice is discouraged as it may produce unreliable results". So I think it would be better to avoid using roles while checking for a user's capability :-)
    – Erenor Paz
    Sep 1, 2017 at 9:58
  • 1
    @Garconis normally it should be an array. For some reason it seems for you is not an array. array_intersect($allowed_roles, (array)$user->roles ) will work with no issues.
    – gmazzap
    Jan 25, 2018 at 7:02
  • 1
    +1 not sure why people are raging againt using current_user_can for checking roles. It is documented in the API as legitimate usage, end of story. Is it smart to do? depends on the context Sep 27, 2021 at 5:21
20

First, current_user_can() should not be used to check a user's role - it should be used to check if a user has a specific capability.

Second, rather than being concerned with the user's role but instead focusing on capabilities, you don't have to bother with doing things like the problem asked about in the original question (which is checking if the user is an administrator OR an editor). Instead, if current_user_can() was being used as intended, which is to check for a user's capabilities, not their role, you wouldn't need the conditional check to contain an "or" (||) test. For example:

if ( current_user_can( 'edit_pages' ) ) { ...

edit_pages is a capability of both administrator and editor roles, but not any lower roles such as authors. This is how current_user_can() was intended to be used.

11
  • 5
    Please note: High level WP devs agree with this answer. You should try to avoid role checking as much as possible, use capabilties. I'm currently working on a project with multiple roles that only have the 'read' cap. The only solution is role checking for me. Sorry, I can't find the link, it was an open discussion on the WP Github.
    – Bjorn
    Apr 26, 2019 at 21:44
  • 3
    This should be the accepted answer, IMO. current_user_can should generally be used for capabilities, not roles. May 13, 2019 at 21:43
  • 1
    +1 to this, avoid checking roles via current_user_can(). If you want to check roles by key then perform a role check instead of a cap check :) Mar 5, 2020 at 11:43
  • What is the proper function then, for checking user roles explicitly & safely? It seems, it's a bit hard to find that (if exists). @Bjorn Apr 15, 2020 at 8:26
  • 1
    @Viktor Borítás There are multiple valid solutions on this page. But only use them if current_user_can() is not an option. Also, my comment is more security based. For example, if you want to restrict content for specific users in most cases a capability check is sufficient for this task.
    – Bjorn
    Apr 16, 2020 at 13:21
4

As @butlerblog reply stated, you should not use current_user_can to check against a role

This notice is specifically added in the PHP documentation of has_cap function which is called by current_user_can

While checking against a role in place of a capability is supported in part, this practice is discouraged as it may produce unreliable results.

The CORRECT way to do this is to get the user and check the $user->roles, like this:

if( ! function_exists( 'current_user_has_role' ) ){
    function current_user_has_role( $role ) {

        $user = get_userdata( get_current_user_id() );
        if( ! $user || ! $user->roles ){
            return false;
        }

        if( is_array( $role ) ){
            return array_intersect( $role, (array) $user->roles ) ? true : false;
        }

        return in_array( $role, (array) $user->roles );
    }
}

Here's some helper functions I use to do this (as sometimes i don't want just current user):

if( ! function_exists( 'current_user_has_role' ) ){
    function current_user_has_role( $role ){
        return user_has_role_by_user_id( get_current_user_id(), $role );
    }
}

if( ! function_exists( 'get_user_roles_by_user_id' ) ){
    function get_user_roles_by_user_id( $user_id ) {
        $user = get_userdata( $user_id );
        return empty( $user ) ? array() : $user->roles;
    }
}

if( ! function_exists( 'user_has_role_by_user_id' ) ){
    function user_has_role_by_user_id( $user_id, $role ) {

        $user_roles = get_user_roles_by_user_id( $user_id );

        if( is_array( $role ) ){
            return array_intersect( $role, $user_roles ) ? true : false;
        }

        return in_array( $role, $user_roles );
    }
}

Then you can just do this:

current_user_has_role( 'editor' );

or

current_user_has_role( array( 'editor', 'administrator' ) );

5
  • 1
    Access low-level properties is never a good idea in WP, surely is not the correct way. If the question one is looking for an answer to is "Is the current user an editor?" then using current_user_can is perfectly fine, actually, that's exactly the way to go. The fact that is preferable to use capabilities to "protect" operations is a different topic. Knowing the role of a user might be a legitimate thing, and in that case, current_user_can is perfectly fine to use.
    – gmazzap
    Mar 18, 2021 at 18:59
  • 1
    @gmazzap then why would it specifically say "While checking against particular roles in place of a capability is supported in part, this practice is discouraged as it may produce unreliable results." on current_user_can documentation page. Seems the documentation and your comment are contradicting, although I do understand what you're saying. With that said though, $roles is a public property on WP_User object and has been since 2.0.0. developer.wordpress.org/reference/functions/current_user_can
    – sMyles
    Mar 18, 2021 at 19:32
  • the documentation refers to the fact that, for example, an editor is usually able to edit posts. So you might be tempted to check for the user being an editor to allow editing a post. That is wrong because maybe the capability was filtered so that user despite being an editor should not edit the post. And it can be the other way around, a subscriber might be allowed to edit posts or that specific post only. Checking capability ensure those expected results are respected.
    – gmazzap
    Mar 31, 2021 at 6:46
  • That said, asking the question "Is this user an editor?" might still be a legitimate question. You should not ask it to determine if a user is allowed or not to do anything, but you might ask that question for some other reason. And if that's the case, then current_user_can with role name is just fine.
    – gmazzap
    Mar 31, 2021 at 6:47
  • Regarding roles, yes, that's a public property you can rely on to be there, but current_user_can has filters, for example, developer.wordpress.org/reference/hooks/user_has_cap or developer.wordpress.org/reference/hooks/map_meta_cap. If a plugin or anything is using those filters to change what current_user_can returns, by directly checking roles property you're gonna miss the filters, and thus reducing the compatibility of your code with others code.
    – gmazzap
    Mar 31, 2021 at 6:56
0

For admin

$current_user = wp_get_current_user();
if (!in_array('administrator', $current_user->roles)) {
   //do something
}

For editor

$current_user = wp_get_current_user();
if (!in_array('editor', $current_user->roles)) {
      //do something
}

Please note that is only working if you want to check the roles of the current user, if you need to check for any other specific user, you need to use get_user_by (https://developer.wordpress.org/reference/functions/get_user_by/) or similar methods to retrieve the user you want to check

-2
<?php if( current_user_can('editor')) :
  echo "welcome";
elseif( current_user_can('member')) :
  echo "welcome";
else :
 wp_die("<h2>To view this page you must first <a href='". wp_login_url(get_permalink()) ."' title='Login'>log in</a></h2>");
endif;
?>
4
  • 1
    It would be great if you could explain as how it helps OP.
    – bravokeyl
    Sep 29, 2016 at 17:32
  • You can allow to see the page only "editor" or "member" you can post this code direct in generic-page.php
    – seowmx
    Sep 29, 2016 at 17:36
  • 5
    Please don't just drop code. Add comments and some explanation how this solves the askers problem.
    – kraftner
    Sep 29, 2016 at 18:09
  • So your answer is code duplication for each role?
    – Julix
    Oct 22, 2019 at 17:20
-3

The correct answers to the above solution-question are by else programming basic:

if( current_user_can('administrator')) { 

<!-- only administrator will see this message -->

} else { 

        if( wp_get_current_user('editor')) {

<!-- only editor but no administrator will see this message -->

?>
<style type="text/css">#perhapsDIVremovalidentifier{
display:none;
</style>
}
<?php
} else {

<!-- the user is neither editor or administrator -->

}}  

Brief: The administrator is found, but if we push editor the administrator is as well found. So we just let the administrator pass through and identify the editor only.

Remember you should always use this code to call that above to minimize cpu code usage:

if(is_user_logged_in()){}
2
  • That is exactly what is stated in the question, and what the author doesn't want.
    – fuxia
    Jun 3, 2020 at 21:15
  • I've added brief so that we have no misunderstanding. It was hard to follow the else rules I believe.
    – Dealazer
    Jun 4, 2020 at 8:52

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.