wp-includes/capabilities.php:913Test whether the current user has a capability with current_user_can(), from broad caps like manage_options to meta caps like edit_post with a post ID. Returns a boolean; super admins pass almost every check, and passing role names instead of capabilities gives unreliable results.
Returns whether the current user has the specified capability.
$capabilitystring$argsmixedboolEvery example is editable and runs in a real WordPress booted in your browser by WordPress Playground. Press Run, then edit the code: clicking away re-runs it. Nothing is sent anywhere until you do.
Meta capabilities like edit_post take the post ID and are mapped to the real capability for that post.
wp_set_current_user( 1 );
echo 'as administrator:\n';
echo ' manage_options: ', var_export( current_user_can( 'manage_options' ), true ), "\n";
echo ' edit_post 1: ', var_export( current_user_can( 'edit_post', 1 ), true ), "\n\n";
wp_set_current_user( 0 );
echo "as a logged-out visitor:\n";
echo ' manage_options: ', var_export( current_user_can( 'manage_options' ), true ), "\n";
echo ' edit_post 1: ', var_export( current_user_can( 'edit_post', 1 ), true );Never check the role instead; capabilities are what plugins and roles actually modify.
Check the capability at the top of any state-changing handler, then verify the nonce; the two checks answer different questions.
add_action( 'admin_post_myplugin_save', 'myplugin_handle_save' );
function myplugin_handle_save() {
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( esc_html__( 'You are not allowed to do that.', 'myplugin' ) );
}
check_admin_referer( 'myplugin_save' );
// ...validate and persist the submitted settings...
wp_safe_redirect( admin_url( 'options-general.php?page=myplugin&saved=1' ) );
exit;
}A capability check alone does not prevent CSRF: the user may be capable but the request forged. Always pair current_user_can() with a nonce check before writing anything.
function current_user_can( $capability, ...$args ) { return user_can( wp_get_current_user(), $capability, ...$args );}Introduced in 2.0.0. Unchanged from 6.7.7 through 7.1.0.
Signature, return type and hooks compared across 5 parsed releases.
src/wp-includes/capabilities.php, and regenerated for each WordPress release so it tracks the code rather than a snapshot of it.