Want to know parameters that can be passed to user_can() for access control by user capabilities

When using user_can() you pass it the user ID (or object) and the “capability” you want to check:

$user_can = user_can( $user_id, 'edit_posts' );

The list of built in roles, and what capabilities they have, is available here. You can pass any of those to the function to determine if a user has that capability based on their role.

However, that is only the list of built-in capabilities. Plugins are able to add their own capabilities, which means that you can add your own capabilities. So really anything can be passed to user_can(), it just needs to be a capability that users can have. This is why a specific list is not included in the function documentation.

Originally I had misunderstood your question, and assumed you were asking what additional arguments can be passed to user_can(), apart from capabilities (which you just wanted a list of). What I had written in response to that is below.


Any additional arguments are passed through to WP_User::has_cap() as the $options... argument, which is:

(int) (Optional) ID of a specific object to check against if $cap is a
“meta” capability. Meta capabilities such as edit_post and edit_user
are capabilities used by by the map_meta_cap() function to map to
primitive capabilities that a user or role has, such as edit_posts and
edit_others_posts.

These “meta” capabilities are passed to the map_meta_cap() function to determine what actual capabilities are required (“actual” capabilities being being the ones that are assigned to a user or role).

For example, edit_post is a meta capability, and the map_meta_cap() function determines which capability the user requires for edit_post to be true. If they are the author of the post then the required capability is edit_posts. If they are not, then it’s edit_others_posts.

For this to work map_meta_cap needs to know the post ID, which can be passed to user_can():

$user_can = user_can( $user_id, 'edit_post', $post_id );

This can also be used for users:

$user_can = user_can( $user_id, 'promote_user', $user_id );

A partial list of built-in “meta” capabilities is in the documentation for map_meta_cap().

So, this means that user_can() can accept the ID of the object that a capability is being checked against.

So for the built-in capabilities, the only additional argument that you can pass to user_can() is the object ID of the post, comment, user or term that is related to the meta capability that you’re checking.

However, this is not the full story. The truth is that you can pass any additional arguments to user_can() that you want. They won’t do anything for any of the built in capabilities, but they will be available for you if you use the map_meta_cap() filter to add your own meta capabilities.

For example, let’s say I have a custom database table with my own types of content, but I want to use the capabilities system of WordPress. In this example, let’s say I have something called “participants”, and I want to control who has permission to edit them. I can create my own two capabilities, edit_participants and edit_others_participants, and assign them to user roles as appropriate. Now I need to use user_can() to determine if a user can edit a particular participant:

$user_can = user_can( $user_id, 'edit_participant' );

edit_participant is not a capability that I assign to a role. Instead I need to use the map_meta_cap filter to add my logic to determine which is which:

add_filter(
    'map_meta_cap',
    function( $caps, $cap, $user_id, $args ) {
        if ( $cap === 'edit_participant' ) {
            // Your logic here.
        }

        return $caps;
    }
);

Inside the callback for the map_meta_cap I have the array of actual capabilities required, $caps, the meta capability that’s currently being checked, $cap, the $user_id that was passed to user_can(), and then $args. This last argument, $args is an array containing all additional arguments passed to user_can().

For example, if I pass the ID to user_can():

$user_can = user_can( $user_id, 'edit_participant', $participant_id );

Then I can access it like this:

function( $caps, $cap, $user_id, $args ) {
    if ( $cap === 'edit_participant' ) {
        $participant_id = $args[0];

        // Your logic here.
    }

    return $caps;
}

This means that I can pass any number of arguments to user_can() that I need:

$user_can = user_can( $user_id, 'edit_participant', $a, $b, $c );

So that I can use them for the capability mapping:

function( $caps, $cap, $user_id, $args ) {
    if ( $cap === 'edit_participant' ) {
        $a = $args[0];
        $b = $args[1];
        $c = $args[2];

        // Your logic here.
    }

    return $caps;
}