Upload Image & Attach to Post from Template

Here is some handy code that allows you to upload image(s) from a form on the front end of your WordPress site and have it become attached to a specific post. There is optional code that allows you to make the post the featured image (post thumbnail) as well. So for my example, let's say that you want to have users add images to a specific post from the front end. For this demonstration, it can be a photo gallery that you want multiple users to be able to add to. First things first, make a form in your template that will let the users choose multiple images to add to the post's gallery.
<!-- you can place the upload script into your theme folder or in a plugin -->
<form action="/path/to/upload/script/upload.php" method="POST" enctype="multipart/form-data">
        <input type="file" name="files[]" multiple>
        <!-- The following hidden field contains the post id for which you will be uploading images to -->
        <input type="hidden" name="post_id" value="100">
        <input type="submit" class="btn" value="Start Upload »">
Now here is the contents of upload.php
// if you have this in a file you will need to load "wp-load.php" to get access to WP functions.  If you post to "self" with this code then WordPress is by default loaded
require $_SERVER['DOCUMENT_ROOT'] . "/wp-load.php";
// require two files that are included in the wp-admin but not on the front end.  These give you access to some special functions below.
require $_SERVER['DOCUMENT_ROOT'] . "/wp-admin/includes/file.php";
require $_SERVER['DOCUMENT_ROOT'] . "/wp-admin/includes/image.php";

// required for wp_handle_upload() to upload the file
$upload_overrides = array( 'test_form' => FALSE );

global $current_user;
$logged_in_user = $current_user->ID;

// count how many files were uploaded
$count_files = count( $_FILES['files'] );

// load up a variable with the upload direcotry
$uploads = wp_upload_dir();

// foreach file uploaded do the upload
foreach ( range( 0, $count_files ) as $i ) {

        // create an array of the $_FILES for each file
        $file_array = array(
                'name'          => $_FILES['files']['name'][$i],
                'type'          => $_FILES['files']['type'][$i],
                'tmp_name'      => $_FILES['files']['tmp_name'][$i],
                'error'         => $_FILES['files']['error'][$i],
                'size'          => $_FILES['files']['size'][$i],

        // check to see if the file name is not empty
        if ( !empty( $file_array['name'] ) ) {

                // upload the file to the server
            $uploaded_file = wp_handle_upload( $file_array, $upload_overrides );

                // checks the file type and stores in in a variable
            $wp_filetype = wp_check_filetype( basename( $uploaded_file['file'] ), null );       

            // set up the array of arguments for "wp_insert_post();"
            $attachment = array(
                'post_mime_type' => $wp_filetype['type'],
                'post_title' => preg_replace('/.[^.]+$/', '', basename( $uploaded_file['file'] ) ),
                'post_content' => '',
                'post_author' => $logged_in_user,
                'post_status' => 'inherit',
                'post_type' => 'attachment',
                'post_parent' => $_POST['post_id'],
                'guid' => $uploads['baseurl'] . '/' . $file_array['name']

            // insert the attachment post type and get the ID
            $attachment_id = wp_insert_post( $attachment );

                // generate the attachment metadata
                $attach_data = wp_generate_attachment_metadata( $attachment_id, $uploaded_file['file'] );

                // update the attachment metadata
                wp_update_attachment_metadata( $attachment_id,  $attach_data );

                // this is optional and only if you want to.  it is here for reference only.
                // you could set up a separate form to give a specific user the ability to change the post thumbnail
                // set_post_thumbnail( $_POST['post_id', $attachment_id );

// setup redirect.  i used the referer so that i can say "file uploaded" in a div if the files query string variable is set.
header("Location: " . $_SERVER['HTTP_REFERER'] . "/?files=uploaded");
Now automatically, any image uploaded to this form will be added to the gallery for this page/post. Depending upon your server's limits for uploaded files, you will be limited to an amount of data that can be uploaded at once.
Post a comment
  1. Ian Wilson

    I'm not sure if this applies to older versions of WP ... when converting this uploader for 3.8.1 and for the purpose of uploading without getting tied to a specific post ID the photos would upload fine, but no image would be displayed. The fix for this issue: you'll need to add this parameter to the $attachment_id variable ... $uploaded_file['file'] ... your variable should look something like this now ... $attachment_id = wp_insert_attachment($attachment, $uploaded_file['file']); ... documentation on wp_insert_attachment: http://codex.wordpress.org/Function_Reference/wp_insert_attachment.

  2. Ask Experts » Fixing "Undefined offset" when working with upload forms

    […] I said i am new to uploading recordsdata from a form … i am the use of this code to check out and remember uploading … i am sure it’s going to be one thing in reality […]

  3. stinkysGTI

    Hello, Thank you for doing this. It's exactly what I've been trying to do, but couldn't figure it out. I implemented this into my functions.php file, but for some reason it goes into an infinite loop. It added 100's of entries into the database, but no actual image files (I tried to load them directly and I get a 404). The loop eventually stops because I get an error coming from the formatting.php file: Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 523800 bytes) I tested it with 3 files that total less than 1mb. Any ideas why this is happening? Thank you for any help :)

    • stinkysGTI

      I should also add that for the html part, I removed the submit button and changed the hidden input's value to $post->ID. Like I mentioned before, I added your code to functions.php as a new function that runs when the post is saved. I also moved the following so it's outside of the function: require $_SERVER['DOCUMENT_ROOT'] . "/wp-load.php"; // require two files that are included in the wp-admin but not on the front end. These give you access to some special functions below. require $_SERVER['DOCUMENT_ROOT'] . "/wp-admin/includes/file.php"; require $_SERVER['DOCUMENT_ROOT'] . "/wp-admin/includes/image.php"; With them inside the function, it kept throwing errors. Perhaps my changes broke it somehow?

      • stinkysGTI

        So I got it to stop looping and it adds a successful entry into the database by changing wp_insert_post to wp_insert_attachment. However, the path isn't correct. For example, this is what's being added to the database: http://sitename.com/gardencrest/wp-content/uploads/sites/4/022.png but it should be: http://sitename.com/gardencrest/wp-content/uploads/sites/4/2013/12/022.png

        • Shifreen

          Please try this $upload_dir = wp_upload_dir(date('Y/m')); It will solve your problem.

          • Ian Wilson

            Actually, you can get the subdirectories into the url using built-in wp_upload_dir functions ... as follows wp_upload_dir['url'] ... documentation can be found here: http://codex.wordpress.org/Function_Reference/wp_upload_dir ;)

Real Time Web Analytics ^