Add Media Upload Capabilities Needed for Custom Role for non-Posts

Found the basic problem! Although a different context than the one you described, the root cause is probably the same.
I was trying to allow users to setup a personal page and upload an image to display there. I kept getting the dreaded “You don’t have permission to attach files to this post”.

The message itself comes from wp_ajax_upload_attachment() in /wp-admin/includes/ajax-actions.php, even though the user is working on the front-page, not the dashboard, because the plugin I’m using (Advanced Custom Fields — recommended!) makes use of wordpress library routines (thankfully it restricts access to library). The error occurs if current_user_can() fails to give permission.
(You can prove the message is in this routine by changing the message statement to something else.)

In turn, current_user_can() calls $current_user->has_cap() to get current capabilities.

has_cap() offers a nice filter that we can make use of, but it kept failing anyway. The reason was that it first calls map_meta_cap() which builds a large array of possible capabilities for this instance. If any one of those possible capabilities is left ’empty’ then has_cap returns false.

That means any custom filter that is determined to give permission must loop through the array and set everything true.
Seems to me that a better permanent solution would be for WordPress to ignore any cap that is not explicitly set to allow or disallow.

For now, here’s a sample filter function that works for me:

// allow users to add images to their home page
function allow_own_attachments( $user_caps, $req_caps, $args, $UserObj ) {
   if ( empty($args[2]) ) {
      return $user_caps;  // nothing to check
   }
   $post = get_post( $args[2] );  // post_id was passed here
   if ( $post->post_author == $UserObj->ID ) {  // this is my post
      foreach ( (array) $req_caps as $cap ) {
         if ( empty( $user_caps[ $cap ] ) )
            $user_caps[ $cap ] = true;
      }
   }
   $user_caps['edit_post'] = true; // tested by wp_ajax_upload_attachment()
   return $user_caps;
}
add_filter( 'user_has_cap', 'allow_own_attachments', 10, 4 );

Leave a Comment