This may be obvious to someone other than myself. I think I remember reading somewhere that an "image" is indeed a form of "post".

  • I have a custom post type called "listing"
  • I have a custom WP role of "client"

When I'm logged in as the "client", and I launch the media popup, browse to an image, click "show" to open it up, and then click "edit image", I get a -1. Ie. nothing else displays but "-1".

I can fix this issue by assigning my custom role the capability of "edit_posts". Why is this? As soon as I do this, I'm plagued with another problem, the "client" user role now has access to posts, comments & tools, which I don't want.

Perhaps I haven't set up my custom post type correctly with the capabilities? How can I allow the "client" to edit the images but not have access to posts?

      $args = array(
    'label' => 'Listing',
    'description' => '',
    'public' => true,
    'show_ui' => true,
    'show_in_menu' => true,
    'show_in_nav_menus' => true,
    'map_meta_cap' => true,
    'capability_type' => 'listing',
    'capabilities' => array(
                    'edit_post' => 'edit_listing',
                    'read_post' => 'read_listing',
                    'delete_post' => 'delete_listing',
                    'edit_posts' => 'edit_listings',
                    'edit_others_posts' => 'edit_others_listings',
                    'publish_posts' => 'publish_listings',
                    'read_private_posts' => 'read_private_listings',
                    'delete_posts' => 'delete_listings',
                    'delete_private_posts' => 'delete_private_listings',
                    'delete_published_posts' => 'delete_published_listings',
                    'delete_others_posts' => 'delete_others_listings',
                    'edit_private_posts' => 'edit_private_listings',
                    'edit_published_posts' => 'edit_published_listings',
    'menu_position' => 5, 
    'hierarchical' => false,
    'has_archive' => false, 
    'rewrite' => array('slug' => 'listing'), 
    'query_var' => true,
    'supports' => array('title'),
    'labels' => $labels
  • Here are the capabilities I'm assigning to my custom wordpress role in case anyone can spot something delete_listing delete_listings delete_published_listings edit_listing edit_listings edit_published_listings publish_listing publish_listings read read_listing upload_files And I seem to need the following also for editing & deleting the images. Thought these would be remapped to edit_listings and delete_listings edit_posts delete_posts
    – Andrew
    Jul 5, 2011 at 1:54
  • I found the following post which I'm currently looking into. Seems to be a larger issue than I thought where edit_posts is required. Looks like there is a general problem when using custom post types + custom roles + taxonomies wordpress.org/support/topic/…
    – Andrew
    Jul 5, 2011 at 4:18

2 Answers 2


If I had to guess: because images are Attachments, and Attachments are a Post-Type. Thus, in order to edit an image, which is an attachment, which is a post, requires the edit_post capability.


Don't you have your capability mapping array keys/values reversed?

e.g. you have 'edit_posts' => 'edit_listings'. Shouldn't it instead be 'edit_listings' => 'edit_posts'?

  • In my custom post type setup above I've remapped by edit_posts to edit_listings, and the custom wordpress role has "edit_listings" assigned to it. I thought this was the purpose of remapping them, perhaps I was wrong?
    – Andrew
    Jul 4, 2011 at 15:00
  • See edit in updated answer. Jul 4, 2011 at 15:08
  • Bennett I reversed them but it didn't seem to have any affect and I still need edit_posts in order to be able to edit the image. Still shows -1 without it. I originally followed Justin Tadlock's "setting up your custom post type" example below where he has the _posts on the left and the remapped capabilities on the right. justintadlock.com/archives/2010/07/10/…
    – Andrew
    Jul 5, 2011 at 1:49
  • After some time working with custom post types, role and capabilities I believe I understand them a great deal more. You were right, an image is a post, therefore in order for a user to be able to edit an image they uploaded, they need edit_posts. For them to delete an image, they need delete_posts. Not sure why my edit_listings didn't correctly map to edit_posts in the first place however.
    – Andrew
    Sep 12, 2011 at 23:46

I know this question is a year old now, but I have just discovered there is in fact a way to achieve this, so posting it here in case it's useful to other people:

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

function my_user_has_cap( $user_caps, $req_cap, $args ) {

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

    if ( 'attachment' != $post->post_type )
        return $user_caps;

    if ( 'delete_post' == $args[0] ) {

        if ( $user_caps['delete_others_posts'] )
            return $user_caps;

        if ( !isset( $user_caps['delete_others_listings'] ) or !$user_caps['delete_others_listings'] )
            return $user_caps;

        $user_caps[$req_cap[0]] = true;


    if ( 'edit_post' == $args[0] ) {

        if ( $user_caps['edit_others_posts'] )
            return $user_caps;

        if ( !isset( $user_caps['edit_others_listings'] ) or !$user_caps['edit_others_listings'] )
            return $user_caps;

        $user_caps[$req_cap[0]] = true;


    return $user_caps;


This is based mainly on this Codex article.

I'm still getting my head round capabilities filters and it's 2:04am, so my code may well be improveable...

  • This worked for me. Just a note, there is an extra ")" in the first line of code. In my case, since I'm using a plugin to show people only their own uploads, all I needed was the if statement to check it this is an attachment.
    – coopersita
    Mar 27, 2013 at 17:23
  • glad it's useful for you - i've now removed the extraneous bracket, thanks for spotting that. Mar 27, 2013 at 21:41

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.