I have a form with a WP Media to allow user uploads for a custom post type on the front end. Every time I try to upload as a user I can the message You don't have permission to attach files to this post.

Investigating it further, I get denied action in the file ajax-actions.php where it checks current_user_can( 'edit_post', $post_id ) before uploading the file. I've bent myself backwards trying to user user_has_cap filter to allow user to this action, but it looks awfully unsecured:

public function allow_user_to_upload( $allcaps, $caps, $args ) {

    if ( $args[2] != 9 ) // 9 is the post_id where the form is
        return $allcaps;

    foreach ($caps as $cap ) {
        $allcaps[$cap] = true;

    return $allcaps;

} add_filter( 'user_has_cap', array( $this, 'allow_user_to_upload'), 100, 3 );

This works but it looks terribly unsecured. There must be a better way to do this, please help!!!

  • At first glance this looks like it is allowing users to do anything with that particular post. You probably need to find a way to check in this function that all they're doing is uploading something - and you probably want to check also that what they're uploading is safe. – Tim Malone May 13 '16 at 5:01
  • Would this help? wordpress.stackexchange.com/questions/42068/… – fsenna May 13 '16 at 5:08
  • Yep Tim, that's the problem, it is allowing users to do anything to that post. I tried checking for the cap edit_post since that's what it is called for in the ajax-actions.php file, but it denies on unfiltered_html cap first. If I try to allow unfiltered_html then it fails on a different capability and so on... I've never used this filter before, so I don't really know what i am doing. Fsenna, thanks for your link, I didn't see anything on user capabilities but I will study it further, I'll probably learn something new. – Caio Mar May 13 '16 at 5:21
  • What kind of user is? Has he upload_files capability? Are you mapping the capabilities of the CPT to deafult "post" or are you using custom capability_type? – cybmeta May 13 '16 at 5:45
  • @cybmeta, answering your questions, the user has customer role, the CPT's capabilities are mapped to post and customer role has upload_files capability. Like I said, I don't know how to work around this while keeping everything in the safe side. A page ( of the post_type 'page') holds the form to submit the CPT, so when current_user_can('edit_post', $post_id) is called, $post_id is a type of page post_type, and customers aren't allowed to edit, which makes sense the denial... but yet there must be a way to safely accept such request. – Caio Mar May 13 '16 at 5:57

If I understood correctly the situation described in the question and its comments, the user has capabilities to upload files and to edit your post type, so you shouldn't be fitering capabilities, the user already has the correct capabilities.

The problem is that wp_editor() use the global $post by default, and in your context the global $post is for the page where you embed the editor.

The solution: set the global $post to the post being edited before executing wp_editor():

global $post;
// Set the global post to your post object
// Exmple if the ID of your post is 2
$post = get_post( 2 );

If you are in a new post form:

global $post;
// Get default post object of my_post_type
$post = get_default_post_to_edit( 'my_post_type', true );
  • Yes! Thank you @cybmeta!!! This solved part of the problem. I ultimately had to change the CPT's capability_type argument from post to my-cpt-slug and allow users to the capability edit_published_{my-cpt-slug}. When uploading a file, WP first checks for the permission upload_files and then edit_posts and edit_published_post and so on (if more are applicable)... The plugin I am using was creating a conflict because it has its on custom capabilities internally and yet it's capability type is mapped to post... creating inconsistencies and conflict. Finally got roles & caps down! – Caio Mar May 14 '16 at 14:09

If you want to allow user to upload files. edit_post is wrong cap to check. Instead you will need to add cap upload_files to users and check against it. If you want to allow only images you may custom filer the allowed MIME type.

See more at https://codex.wordpress.org/Roles_and_Capabilities#upload_files

  • Thanks @Sisir! I know what you are saying, and I agree, however, the async upload action in ajax-actions.php checks first for the capabiltiy upload_files and then after it checks for edit_post. This is in the WP core, I shouldn't have to hack it, you know. – Caio Mar May 13 '16 at 7:37
  • What happens if you set $allcaps['upload_files'] = true; and return it from the filter? Instead of setting everything as true. – Sisir May 13 '16 at 8:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.