By Christine Cooper

2013-04-09 17:07:32 8 Comments

I have a large number of users with Editor Capabilities that help to go through the post submissions. This is my current setup for this role:

Editor Capabilities

As you can see, they are allowed to edit_posts and edit_others_posts but they cannot edit_published_posts. This means that they can edit posts that are in Draft and Pending status.

Now, I want to restrict them to only be able to edit pending posts. So, they won't have the ability to touch draft posts (unless if they are the author of the post). Unfortunately there is no capability like edit_pending_posts... there should be.

How do I solve this?


@fuxia 2013-04-15 04:48:58

This is actually not hard. To add a new capability, call WP_Roles->add_cap(). You have to do this just once, because it will be stored in the database. So we use a plugin activation hook.

Note to other readers: All of the following code is plugin territory.

register_activation_hook( __FILE__, 'epp_add_cap' );

 * Add new capability to "editor" role.
 * @wp-hook "activate_" . __FILE__
 * @return  void
function epp_add_cap()
    global $wp_roles;

    if ( ! isset( $wp_roles ) )
        $wp_roles = new WP_Roles;

    $wp_roles->add_cap( 'editor', 'edit_pending_posts' );

Now we have to filter all calls for …

current_user_can( $post_type_object->cap->edit_post, $post->ID );

… because that is how WordPress checks if an user can edit a post. Internally, this will be mapped to the edit_others_posts capability for other authors posts.

So we have to filter user_has_cap and look into our new edit_pending_posts capability when some wants to use the edit_post capability.

I have included delete_post too, because this also a kind of an edit.

Sound complicated, but it is really simple:

add_filter( 'user_has_cap', 'epp_filter_cap', 10, 3 );

 * Allow editing others pending posts only with "edit_pending_posts" capability.
 * Administrators can still edit those posts.
 * @wp-hook user_has_cap
 * @param   array $allcaps All the capabilities of the user
 * @param   array $caps    [0] Required capability ('edit_others_posts')
 * @param   array $args    [0] Requested capability
 *                         [1] User ID
 *                         [2] Post ID
 * @return  array
function epp_filter_cap( $allcaps, $caps, $args )
    // Not our capability
    if ( ( 'edit_post' !== $args[0] && 'delete_post' !== $args[0] )
        or empty ( $allcaps['edit_pending_posts'] )
        return $allcaps;

    $post = get_post( $args[2] );

    // Let users edit their own posts
    if ( (int) $args[1] === (int) $post->post_author
        and in_array(
            array ( 'draft', 'pending', 'auto-draft' )
        $allcaps[ $caps[0] ] = TRUE;
    elseif ( 'pending' !== $post->post_status )
    { // Not our post status
        $allcaps[ $caps[0] ] = FALSE;

    return $allcaps;

@Christine Cooper 2013-04-16 18:41:50

I made tests and ran into a few issues. Firstly, I had edit_posts and edit_others_posts on with the new edit_pending_posts. I tried just having edit_pending_posts on without the other two and the post menu did not appear. When testing this, I found that I could add a new post, but couldn't save the draft (You are not allowed to edit this post notice). Did you test to save your own post in this role? Editing pending posts are fine.

@fuxia 2013-04-16 18:58:23

@ChristineCooper This happened because $post->post_author is passed as a string, but $args[1] as an integer. Sometimes. Stupid WordPress! I fixed it by casting both to integers. And I allowed editors to edit their own published posts. If you don’t want that, remove the return line in the block after // Let users edit their own posts.

@Christine Cooper 2013-04-16 19:12:42

Got it! One issue remains. I tested your updated code and it worked fine! However I do not want to allow the editors to edit their published posts so I removed that return $allcaps; line and the same permission issue appears with the saving of draft. Why?

@fuxia 2013-04-16 19:16:00

Hm, works for me. My capability settings

@Christine Cooper 2013-04-16 19:23:55

Just to confirm, you were referring to remove the return line under $allcaps[ $caps[0] ] = TRUE;? Very odd that I am experiencing this, it doesn't make sense logically that it shouldn't work for me if it does for you, here is my setup:

@fuxia 2013-04-16 19:33:20

I don’t see edit_pending_posts in your screenshot? That is essential.

@Christine Cooper 2013-04-16 19:35:54

Sorry it is ticked, just didn't include it in the screenshot:

@Christine Cooper 2013-04-16 19:50:08

Another potential issue. I noticed that Admins have all roles ticked as default, including this one, which disables admins from editing drafts etc. Is it possible to untick it for Admins? I noticed that my User Role Editor plugin doesn't have the option to edit Admin capabilities.

@fuxia 2013-04-16 19:52:13

Try the plugin Members.

Related Questions

Sponsored Content

1 Answered Questions

3 Answered Questions

[SOLVED] How to get all users with Author role capabilities?

3 Answered Questions

[SOLVED] Do custom user roles have any default capabilities?

1 Answered Questions

[SOLVED] What capability allows someone to change a page's/post's author?

1 Answered Questions

1 Answered Questions

[SOLVED] Stop users of author role from editing already pending posts

1 Answered Questions

Sponsored Content