18

I am involved in a large migration from another CMS to WordPress. We have a copy of the database and have worked out how to extract the content and programmatically create WordPress posts from it using an instantiation of the wpdb class.

However, there are a couple of thousand images which we would like to pull across automatically, generate the various sizes, and then attach to the posts, to save about a week's work!

Is there a way I can get an image from a remote site by URL and save it in my wp-uploads folder? I guess this uses wp_http but I'm unfamiliar with that.

Once I've got the image and saved it I'm ok as I can then use wp_generate_attachment_metadata to create the various sizes and wp_insert_attachment to attach it to a post.

Thanks Simon

2 Answers 2

34

There's actually a great function that will do all three of those things for you:

media_sideload_image( $url, $post_id, $description );

The first argument is the remote url of the image you want to download. The second argument is the post id of the post to which you want to attach the image. The third argument is optional, but will be a description if included.

I'd suggest finding a way to throttle the downloads so that you don't keep timing out, such as limiting the number of images it pulls in per load and setting the importer to refresh itself between downloads, or using AJAX to do them one at a time asynchronously.

4
  • 1
    that is absolutely fantastic john, thank you so much - it works perfectly. the throttling is not an issue as i've set it to wait for a keypress after each post import to give us a chance to manually check the details and note any problematic ones. Commented Mar 18, 2011 at 15:28
  • 1
    just because I needed the Id of the attachment to be connected to another post, here is a good way to do that
    – axel
    Commented Sep 15, 2014 at 9:18
  • This works greatly, but can we do the same thing with a non-image file. With a PDF for example. If I try to run the same function with a PDF I have got this error message: array(1) { ["image_sideload_failed"]=> array(1) { [0]=> string(18) "Invalid image URL." } } Commented Jun 12, 2023 at 13:45
  • @MarcelloPerri the fastest way to do that would be to add the file extensions you need to the filter for the sideload function before you run the sideload function: add_filter( 'image_sideload_extensions', fn( $exts ) => array_merge( $exts, [ 'pdf' ] ) );. As far as I can tell, there's nothing about the function that requires the files to be images. Commented Jun 12, 2023 at 21:43
7

John's answer is correct re: using media_sideload_image, just note that you may need to require these scripts before if you aren't doing this within the context of WP Admin:

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

See https://codex.wordpress.org/Function_Reference/media_sideload_image#Notes

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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