Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

My basic scenario is the following:

I have a directory on my server that gets filled with images via ftp every once in a while. I would want to move these images to the wp upload directory and then add them to the media library with wp_insert_attachment(). I thought wp_handle_sideload() to be the correct function for this but if fed with an absolute path to one of the images it returns an error.

Heres my code so far:

function oo_attach_images($images, $id){   

 //$images is an array of anbsolute image paths, $id is the id of a post I want the images to be attached to.

    require_once(ABSPATH . '/wp-admin/includes/file.php');
    require_once(ABSPATH . '/wp-admin/includes/image.php');

    foreach($images as $image){

        $override = array('test_form' => FALSE);

        $file = wp_handle_sideload($image, $override);

        print_r($file); //returns: Array ( [error] => )

        $attachment = array(
            'post_mime_type' => $file['type'],
            'post_title' => basename($image),
            'post_content' => ' ',
            'post_status' => 'inherit'
        );

        $attach_id = wp_insert_attachment( $attachment, $file['file'], $id );

        $attach_data = wp_generate_attachment_metadata( $attach_id, $file['file'] );
        wp_update_attachment_metadata( $attach_id,  $attach_data );


    }
}

I looked into similar questions, but none of the solutions outlined there seemed to have anything to do with the sideload itself failing. Frankly, I believe that I do not pass the right kind of file path to wp_handle_sideload(), but since its undocumented in codex I have no idea what kind of input it might expect. Does anyone know what I need to change to make this work?

share|improve this question
    
I figured it out, firstly I was using the wrong function. The right one is media_handle_sideload(). The problem was, that these wp upload functions expect an array with the same structure as $_FILES passed, therefore I passed my absolute paths and other info into the function as an array similar to $_FILES. Id love to give yout the code, but thanks to the "you cant answer your own question yet" limitation ill have to wait some more before ill be able to. –  Anatol Nov 25 '11 at 16:11

3 Answers 3

up vote 1 down vote accepted

Your files array needs to mimic the $_FILES global so you need to make a dummy page with some file inputs that prints or dumps the contents of $_FILES to see how it is structured. Make a variable that looks like that with your data and pass that wp_handle_sideload().

EDIT:

This answer was correct at the time of writing and is if you wish to use wp_handle_sideload(). media_handle_sideload() allow you to attach the media to a post at the same time.

See @anatol's own answer for a full solution.

share|improve this answer
1  
It'd be easier to just lookup the docs -- php.net/manual/en/features.file-upload.post-method.php –  Ian Dunn Dec 17 '13 at 12:03

I used Anatol's code but ran into trouble when pulling images using HTTP. To fix this, use download_url first to get a local copy of the image.

It's also useful to know that media_handle_sideload returns the attachment_id number which you can use to display the image after you've uploaded it.

foreach($images as $image){
  $tmp_name = download_url( $image ); // get the image and save it locally temporarily
  $array = array(
    'name' => basename( $image ),
    'type' => 'image/jpeg',
    'tmp_name' => $tmp_name,
    'error' => 0,
    'size' => filesize( $tmp_name )
  );
  $_image_id = media_handle_sideload($array, $id);
  $_src = wp_get_attachment_url( $_image_id );
  echo '<img src="' . $_src . '" />';
}
share|improve this answer

This is the surprisingly simple code that ultimately worked out to do what it's supposed to:

function oo_attach_images($images, $id){ //$images is an array of image urls, $id is the ID of the post I want the images to be attached to

    require_once(ABSPATH . '/wp-admin/includes/file.php');
    require_once(ABSPATH . '/wp-admin/includes/media.php');
    require_once(ABSPATH . '/wp-admin/includes/image.php');

    foreach($images as $image){

        $array = array( //array to mimic $_FILES
            'name' => basename($image), //isolates and outputs the file name from its absolute path
            'type' => 'image/jpeg', //yes, thats sloppy, see my text further down on this topic
            'tmp_name' => $image, //this field passes the actual path to the image
            'error' => 0, //normally, this is used to store an error, should the upload fail. but since this isnt actually an instance of $_FILES we can default it to zero here
            'size' => filesize($image) //returns image filesize in bytes
        );

        media_handle_sideload($array, $id); //the actual image processing, that is, move to upload directory, generate thumbnails and image sizes and writing into the database happens here
    }
}

The one issue left is the MIME type. The function that would return the type of the file provided isnt supported on my server. Therefore, if you want to use this code you might want to build in some kind of check to keep the upload from accepting files that aren't images.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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