WordPress: Upload user-submitted files from the frontend

There are many use cases for allowing users to upload files from the frontend, but the trick is making sure the file is uploaded and saved in the WordPress media library correctly. You can easily use standard PHP functions to handle the upload and then store the file wherever you like, but then you won’t be able to take advantage of the media attachment system that WordPress uses. An image that is uploaded correctly, for example, will have all the various sizes available as well as the meta data, such as title, description and caption. You will also be able to edit all of this from the media library in your WordPress dashboard.

This snippet will handle the upload for you and save the file in your media library correctly. All you need to do is pass the uploaded file array to the function – all uploaded files are stored in the $_FILES array so you just need to loop through that and upload each file from there. The function will return the ID of the attachment so you can handle any further processing from there. I’ve also included a basic usage example below.


<?php
function upload_user_file( $file = array() ) {
require_once( ABSPATH . 'wp-admin/includes/admin.php' );
$file_return = wp_handle_upload( $file, array('test_form' => false ) );
if( isset( $file_return['error'] ) || isset( $file_return['upload_error_handler'] ) ) {
return false;
} else {
$filename = $file_return['file'];
$attachment = array(
'post_mime_type' => $file_return['type'],
'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $filename ) ),
'post_content' => '',
'post_status' => 'inherit',
'guid' => $file_return['url']
);
$attachment_id = wp_insert_attachment( $attachment, $file_return['url'] );
require_once(ABSPATH . 'wp-admin/includes/image.php');
$attachment_data = wp_generate_attachment_metadata( $attachment_id, $filename );
wp_update_attachment_metadata( $attachment_id, $attachment_data );
if( 0 < intval( $attachment_id ) ) {
return $attachment_id;
}
}
return false;
}
?>

view raw

upload.php

hosted with ❤ by GitHub


<?php
if( ! empty( $_FILES ) ) {
foreach( $_FILES as $file ) {
if( is_array( $file ) ) {
$attachment_id = upload_user_file( $file );
}
}
}
?>

view raw

usage.php

hosted with ❤ by GitHub

Remember that if you want your form to be able to handle file uploads then you need to add the enctype="multipart/form-data" attribute to the <form> tag.

23 Thoughts

  1. I am wanting to use this snipped, but I’m not quite sure how to connect the file upload input type with this function. Can you provide a simple usage example of this snippet?

    Thank you in advance!

    1. If you have a form with file upload fields (i.e. type="file") then after posting, the uploaded files are stored in the $_FILES array. The second piece of code in this post will handle that array.

      Remember that if you want your form to be able to handle file uploads then you need to add the enctype="multipart/form-data" attribute to the form tag.

      1. Hi Hugh Lashbrooke,

        Very well snippets ever this.

        Thanks again for your great snippets for my plugin developement.
        I’m newbie in wordpress so can you give me full overview of this snippet.
        I want html code and where to use this snippets in wordpress?

        Please let me know.!

        I’m waiting for your pleasent reply,

        Regards,
        Laxmanvel

  2. Hello Hugh Lashbrooke,

    Great help.

    I tried your script and it works great. The image is saved in three sizes in folders by date, and is shown in wordpress media library.

    But it is not displayed as feature image in the post, and therefore I can not show the image as thumbnail in and frontend.

    You can, please, tell me, what I have to do, to show the image as a thumbnail?

    Very Thanks

  3. function upload_user_file( $file = array() ) {

    require_once( ABSPATH . ‘wp-admin/includes/admin.php’ );

    $file_return = wp_handle_upload( $file, array(‘test_form’ => false ) );

    if( isset( $file_return[‘error’] ) || isset( $file_return[‘upload_error_handler’] ) ) {
    return false;
    } else {

    $filename = $file_return[‘file’];

    $attachment = array(
    ‘post_mime_type’ => $file_return[‘type’],
    ‘post_title’ => preg_replace( ‘/.[^.]+$/’, ”, basename( $filename ) ),
    ‘post_content’ => ”,
    ‘post_status’ => ‘inherit’,
    ‘guid’ => $file_return[‘url’]
    );

    $attachment_id = wp_insert_attachment( $attachment, $file_return[‘url’] );

    require_once (ABSPATH . ‘wp-admin/includes/image.php’ );
    $attachment_data = wp_generate_attachment_metadata( $attachment_id, $filename );
    wp_update_attachment_metadata( $attachment_id, $attachment_data );

    if( 0 < intval( $attachment_id ) ) {
    return $attachment_id;
    }
    }

    return false;
    }

  4. Thank you for your post. I can’t understand why I don’t have any various sizes and any meta data, such as title, description and caption. Also I don’t have this image in the media library at all.. What should I check, how do you think?

  5. Just checked your code along side the core function “media_handle_upload”. I will use yours as it seems more straightforward for images. 😉

    Thanks for the snippet and kudos for the solution.

  6. This is a handy bit of code, but line 22 has an error:
    > $attachment_id = wp_insert_attachment( $attachment, $file_return[‘url’] );
    The Codex says the second argument must be an absolute path to the file in the uploads directory, not the file’s URI.

    I’m not sure if the code’s been working for everyone else, but for me the result was a mangled URL (repeated directories) pointing at a non-existent file. This was on a multisite install, so that may have been a factor. Switching the second argument to $filename fixed the issue.

  7. This snippet has been very helpful, and I’m getting images/files to upload however, I’m still getting a Specified File Failed Upload Test and therefore cannot get attachment data to return a URL to the user. Can view image in Media Library. Any direction would be so helpful!

  8. Does anyone know if this works for non-logged in users?
    I am using it in a frontend form but it only works when the user is logged in.

  9. For the better part of a two days I’ve failed with the native media_handle_upload for a front end form. However, your code worked with the upload the first time. Thanks so much. I’m ecstatic.

    What I’d like to find out is how to get the url from the attachment _id. I’ve been using wp_get_attachment_url(attachment _id) with no luck.

    Please say where I’m going wrong.

    Thanks.

    1. I mean adress= title post …………………………………………………………………………………………

Leave a Reply