Why does my custom WP role need edit_posts to edit images?

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”.

Read More

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
  ); 

Related posts

Leave a Reply

2 comments

  1. 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.

    EDIT

    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'?

  2. 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…