current_user_can()WP 2.0.0

Whether the current user has a specific capability.

By default in WP, the current user is set on init action hook. Therefore, it is recommended to use this function not earlier than this action. However, it almost always works correctly from plugins_loaded action hook.

SuperAdmins of multisite network always have all capabilities (returns true), unless the checked cap is denied specifically. See. WP_User::has_cap().

The only way to explicitly disallow a single capability for super admins is to use the map_meta_cap filter where return do_not_allow. The disallowing like so: user->add_cap( 'capability', false ) will not work!

Use user_can() to check the capabilities of the specified user.

1 time — 0.0034041 sec (very slow) | 50000 times — 3.84 sec (fast) | PHP 7.4.8, WP 5.6

No Hooks.

Return

true|false. Whether the current user has the given capability. If $capability is a meta cap and $object_id is passed, whether the current user has the given meta capability for the given object.

Usage

current_user_can( $capability, ...$args );
$capability(string) (required)
Capability name. See here for the list of roles and capabilities.
$object_id(int) (required)

ID of the specific object to check against if $capability is a "meta" cap.

"Meta" capabilities, e.g. 'edit_post', 'edit_user', etc., are capabilities used by map_meta_cap() to map to other "primitive" capabilities, e.g. 'edit_posts', 'edit_others_posts', etc. Accessed via func_get_args() and passed to WP_User::has_cap(), then map_meta_cap().

Basic List of Capabilities

There are 6 roles in WordPress by default:

Super Admin Super Administrator. Has rights to manage the network sites. This role appears only in multisite installation.
administrator The administrator of the site (a separate site in the network multisite).
editor Editor. Has access to all posts, pages, comments, categories, tags, and links.
author Author. Can create, upload photos, edit and publish his posts.
contributor Contributor. Can create posts, which are then published by an editor or administrator.
subscriber Subscriber. Can't do anything except edit profile.

Which role the new user gets is specified in Settings > General. The data is saved in an options: users_can_register and default_role:

List of Capabilities by Roles

A list of primitive (fundamental) user caps. These are capabilities that the specified roles (users) have by default. This list of caps is set once, when you install WordPress - it is stored in the database wp_options table in the wp_user_roles option.

Capability Super-admin Admin Editor Author Contributor Subscriber
read yes yes yes yes yes yes
delete_posts yes yes yes yes yes
edit_posts yes yes yes yes yes
delete_published_posts yes yes yes yes
edit_published_posts yes yes yes yes
publish_posts yes yes yes yes
upload_files yes yes yes yes
delete_others_pages yes yes yes
delete_others_posts yes yes yes
delete_pages yes yes yes
delete_private_pages yes yes yes
delete_private_posts yes yes yes
delete_published_pages yes yes yes
edit_others_pages yes yes yes
edit_others_posts yes yes yes
edit_pages yes yes yes
edit_private_pages yes yes yes
edit_private_posts yes yes yes
edit_published_pages yes yes yes
manage_categories yes yes yes
manage_links yes yes yes
moderate_comments yes yes yes
publish_pages yes yes yes
read_private_pages yes yes yes
read_private_posts yes yes yes
unfiltered_html yes yes ¹ yes ¹
activate_plugins yes yes ²
create_users yes yes ¹
deactivate_plugins yes yes
delete_plugins yes yes ¹
delete_themes yes yes ¹
delete_users yes yes ¹
edit_dashboard yes yes
edit_files yes yes ¹
edit_plugins yes yes ¹
edit_theme_options yes yes
edit_themes yes yes ¹
edit_users yes yes ¹
export yes yes
import yes yes
install_languages yes yes ¹
install_plugins yes yes ¹
install_themes yes yes ¹
list_users yes yes
manage_options yes yes
promote_users yes yes
remove_users yes yes
switch_themes yes yes
update_core yes yes ¹
update_languages yes yes ¹
update_plugins yes yes ¹
update_themes yes yes ¹
unfiltered_upload yes ³ yes ³
manage_network_options yes
manage_network_plugins yes
manage_network_themes yes
manage_network_users yes
manage_network yes
manage_sites yes
setup_network yes
upgrade_network yes
  • ¹ — when one site (not a multisite).
  • ² — when one site (not a multisite). Or enabled in the network settings.
  • ³ — this right must be included separately, more below.

Meta Capabilities

Above is a list of primitive (fundamental) rights. But there are also so-called meta-rights. They are not saved anywhere, but are computed "on the fly" and eventually turn into a primitive right.

List of meta-rights:

activate_plugin
activate_plugins
add_comment_meta
add_post_meta
add_term_meta
add_user_meta
add_users
assign_categories
assign_post_tags
assign_term
create_app_password
create_sites
create_users
customize
deactivate_plugin
deactivate_plugins
delete_app_password
delete_app_passwords
delete_categories
delete_comment_meta
delete_page
delete_page
delete_plugins
delete_post
delete_post
delete_post_meta
delete_post_tags
delete_site
delete_sites
delete_term
delete_term_meta
delete_themes
delete_user
delete_user
delete_user_meta
delete_users
edit_app_password
edit_categories
edit_comment
edit_comment
edit_comment_meta
edit_css
edit_files
edit_page
edit_page
edit_plugins
edit_post
edit_post
edit_post_meta
edit_post_tags
edit_term
edit_term_meta
edit_themes
edit_user
edit_user
edit_user_meta
edit_users
erase_others_personal_data
export_others_personal_data
install_languages
install_plugins
install_themes
list_app_passwords
manage_links
manage_network
manage_network_options
manage_network_plugins
manage_network_themes
manage_network_users
manage_post_tags
manage_privacy_options
manage_sites
promote_user
promote_user
publish_post
read_app_password
read_page
read_page
read_post
read_post
remove_user
remove_user
resume_plugin
resume_theme
setup_network
unfiltered_html
unfiltered_upload
update_core
update_https
update_languages
update_php
update_plugins
update_themes
upgrade_network
upload_plugins
upload_themes

edit_term                   — WP 4.7 — It does not check who created the term - it only checks if the specified term and taxonomy exist.
delete_term                 — WP 4.7 —
assign_term                 — WP 4.7 —
activate_plugin             — WP 4.9 — current_user_can( 'activate_plugin', 'my-plugin/my-plugin.php' )
deactivate_plugin           — WP 4.9 — current_user_can( 'deactivate_plugin', 'my-plugin/my-plugin.php' )

export_others_personal_data — WP 4.9.6 — is_multisite() ? 'manage_network' : 'manage_options'
erase_others_personal_data  — WP 4.9.6 — is_multisite() ? 'manage_network' : 'manage_options'
manage_privacy_options      — WP 4.9.6 — is_multisite() ? 'manage_network' : 'manage_options'

update_php                  — WP 5.0 — is_multisite() ? is_super_admin() : update_core
update_https                — WP 5.7 — is_multisite() ? is_super_admin() : manage_options | update_core

create_app_password         — WP 5.7 — map_meta_cap( 'edit_user', $user_id )
list_app_passwords          — WP 5.7 — map_meta_cap( 'edit_user', $user_id )
read_app_password           — WP 5.7 — map_meta_cap( 'edit_user', $user_id )
edit_app_password           — WP 5.7 — map_meta_cap( 'edit_user', $user_id )
delete_app_passwords        — WP 5.7 — map_meta_cap( 'edit_user', $user_id )
delete_app_password         — WP 5.7 — map_meta_cap( 'edit_user', $user_id )

To check such rights, you need to pass additional parameters, such as the ID of the post for which you want to check whether the user can edit it. For example:

if( current_user_can( 'edit_post', 123 ) ){
	 echo 'The current user can edit post 123';
}

In this case, WP checks on the fly whether the user is the author of that post, or has the primitive right to edit all posts. As a result, if the check is passed, this meta right turns into a similar primitive right edit_posts that allows the action to be performed.

Read more about meta rights in map_meta_cap().

unfiltered_upload

By default, the unfiltered_upload capability is available to the administrator. However, this right is locked by default, i.e. roles will not pass the if( current_user_can('unfiltered_upload') ) despite having this right.

To make the unfiltered_upload capability start working as expected, you need to add following constant in wp-config.php:

define( 'ALLOW_UNFILTERED_UPLOADS', true );

With the definition of this constant, roles with unfiltered_upload permission will be able to upload files with any extension (without checking the file type).

For multisite, only the Super Administrator has the unfiltered_upload right. If another role has the unfiltered_upload right, it will simply be ignored. See checking the meta-right in map_meta_cap() for details:

case 'unfiltered_upload':
	if ( defined( 'ALLOW_UNFILTERED_UPLOADS' ) && ALLOW_UNFILTERED_UPLOADS && ( ! is_multisite() || is_super_admin( $user_id ) ) ) {
		$caps[] = $cap;
	} else {
		$caps[] = 'do_not_allow';
	}
	break;

Examples

0

#1 Сheck whether the user is an administrator or not:

// is user administrator
if( current_user_can( 'manage_options') ){
	echo 'The user has rights to change settings - it is admin';
}
0

#2 Use user_can() variant to check the rights of the current user:

// define the user globally
global $user;

if( user_can( $user->ID, 'manage_options' ) ){

	// do something that a user with these rights can do
}

manage_options - administrator rights.

0

#3 Example of using the second argument $args:

if( current_user_can( 'edit_post', 123 ) ) {
	 echo 'The current user can edit post 123.';
}
0

#4 Checking permissions for a single taxonomy element

Since version 4.7. It is now possible to check the rights for a single term. To do this, use the rights: edit_term, delete_term, assign_term.

For example, let's display a link to edit a taxonomy item only if the current current user has that right.

if( current_user_can( 'edit_term', $term_id ) ){

	echo '<a href=". get_edit_term_link( $term_id ) .'">Edit.</a>";
}
0

#5 Checking more than two roles

If you want to check more than two roles, you can check if the current user's role is inside an array of roles, for example:

$user = wp_get_current_user();
$allowed_roles = [ 'editor', 'administrator', 'author' ];

if ( array_intersect( $allowed_roles, $user->roles ) ) {

   // Stuff here for allowed roles
}
0

#6 Checking the role of the current user

It is not recommended to use the role name in current_user_can(), because the code may not work correctly.

An example of how not to do it:

// if the current user is an editor, the function will return:
current_user_can( 'administrator' ) // false
current_user_can( 'editor' )        // true
current_user_can( 'contributor' )   // false
current_user_can( 'subscriber' )    // false

Why shouldn't we write it that way? For example, we use the check current_user_can('editor'), which allows the Editor to do something and everything seems fine and the user with the 'editor' role passes the check, but the user with the 'administrator' role, which should also pass the check, does not!

Hack to be able to use role names in checking user rights

If you insert this hook in the file theme functions.php, then all the roles that are considered as lower-level access will be added to the list of rights of the user being checked. For example, for the user with the role of 'author', the roles 'contributor' and 'subscriber' will also be added. Thus, the check current_user_can( 'contributor' ) will also be passed for any role above this one - it is author > editor > administrator.

add_filter( 'user_has_cap', 'user_lower_roles_to_allcaps', 10, 4 );

/**
 * Add lower roles to the list of all caps of current checking user.
 *
 * @param bool[]   $allcaps Array of key/value pairs where keys represent a capability name and
 *                          boolean values represent whether the user has that capability.
 * @param string[] $caps    Required primitive capabilities for the requested capability.
 * @param array    $args    Arguments that accompany the requested capability check.
 * @param WP_User  $user    The user object.
 *
 * @return bool[]
 */
function user_lower_roles_to_allcaps( $allcaps, $caps, $args, $user ){

	$roles_chain = ' > administrator > editor > author > contributor > subscriber > ';

	// do nothing if no need
	if( false === strpos( $roles_chain, $args[0] ) ){
		return $allcaps;
	}

	$low_roles = '';
	foreach( $user->roles as $role ){

		$pos = strpos( $roles_chain, " > $role > " );

		if( false === $pos ){
			continue;
		}

		$_low_roles = substr( $roles_chain, $pos );

		if( strlen( $_low_roles ) > strlen( $low_roles ) ){
			$low_roles = $_low_roles;
		}
	}

	// add top roles to all caps
	$low_roles = explode( ' > ', trim( $low_roles, '> ' ) );
	foreach( $low_roles as $lowrole ){
		$allcaps[ $lowrole ] = 1;
	}

	return $allcaps;
}

Let's check how the hack works:

$user = get_userdata( 141 );  // editor
var_dump( user_can( $user, 'administrator' ) ); // bool(false)
var_dump( user_can( $user, 'contributor' ) );   // bool(true)
echo "---\n";

$user = get_userdata( 3 );    // author
var_dump( user_can( $user, 'administrator' ) ); // bool(false)
var_dump( user_can( $user, 'contributor' ) );   // bool(true)
echo "---\n";

$user = get_userdata( 1220 ); // contributor
var_dump( user_can( $user, 'administrator' ) ); // bool(false)
var_dump( user_can( $user, 'contributor' ) );   // bool(true)
var_dump( user_can( $user, 'subscriber' ) );    // bool(true)
echo "---\n";

$user = get_userdata( 2486 ); // subscriber
var_dump( user_can( $user, 'administrator' ) ); // bool(false)
var_dump( user_can( $user, 'contributor' ) );   // bool(false)
var_dump( user_can( $user, 'subscriber' ) );    // bool(true)
0

#7 Multiple user role checking function

To be able to reliably check the rights exactly by role, it would be convenient to list them in an array, but we can't write that (it would cause notices):

current_user_can( [ 'administrator', 'author' ] );

For this check I sometimes use this function:

/**
 * Checks if the specified role is in the roles of the current/specified user.
 *
 * @param string|array      $roles The name of the role you want to check with the current user.
 * @param empty|int|WP_User $user  Default: current user
 *
 * @return bool
 */
function is_user_role_in( $roles, $user = false ) {

	$user || $user = wp_get_current_user();

	if( is_numeric( $user ) ){
		$user = get_userdata( $user );
	}

	if( empty( $user->ID ) ){
		return false;
	}

	foreach( (array) $roles as $role ){
		if( isset( $user->caps[ $role ] ) || in_array( $role, $user->roles, true ) ){
			return true;
		}
	}

	return false;
}

Example usage:

if( is_user_role_in( [ 'new_role','new_role2' ] ) ){
	echo 'The role of the current user is new_role or new_role2';
}

if( is_user_role_in( [ 'new_role','new_role2' ], 5 ) ){
	echo 'User role 5 new_role or new_role2';
}

Notes

Changelog

Since 2.0.0 Introduced.
Since 5.3.0 Formalized the existing and already documented ...$args parameter by adding it to the function signature.
Since 5.8.0 Converted to wrapper for the user_can() function.

current_user_can() code WP 6.4.3

function current_user_can( $capability, ...$args ) {
	return user_can( wp_get_current_user(), $capability, ...$args );
}