How to programmatically import media files to WordPress

On several occastions, I’ve been asked to create a custom import from one CMS to WordPress. Sticking information into the right tables is usually pretty easy, but one of the biggest problems I have is moving images and not only keeping the file association but also generating the various image sizes used by WordPress programatically rather than through WordPress’ interface.

Since I’m sure someone else has run into this problem, here’s the function that I use to do it:

/* Import media from url
 *
 * @param string $file_url URL of the existing file from the original site
 * @param int $post_id The post ID of the post to which the imported media is to be attached
 *
 * @return boolean True on success, false on failure
 */

function fetch_media($file_url, $post_id) {
	require_once(ABSPATH . 'wp-load.php');
	require_once(ABSPATH . 'wp-admin/includes/image.php');
	global $wpdb;

	if(!$post_id) {
		return false;
	}

	//directory to import to	
	$artDir = 'wp-content/uploads/importedmedia/';

	//if the directory doesn't exist, create it	
	if(!file_exists(ABSPATH.$artDir)) {
		mkdir(ABSPATH.$artDir);
	}

	//rename the file... alternatively, you could explode on "/" and keep the original file name
	$ext = array_pop(explode(".", $file_url));
	$new_filename = 'blogmedia-'.$post_id.".".$ext; //if your post has multiple files, you may need to add a random number to the file name to prevent overwrites

	if (@fclose(@fopen($file_url, "r"))) { //make sure the file actually exists
		copy($file_url, ABSPATH.$artDir.$new_filename);

		$siteurl = get_option('siteurl');
		$file_info = getimagesize(ABSPATH.$artDir.$new_filename);

		//create an array of attachment data to insert into wp_posts table
		$artdata = array();
		$artdata = array(
			'post_author' => 1, 
			'post_date' => current_time('mysql'),
			'post_date_gmt' => current_time('mysql'),
			'post_title' => $new_filename, 
			'post_status' => 'inherit',
			'comment_status' => 'closed',
			'ping_status' => 'closed',
			'post_name' => sanitize_title_with_dashes(str_replace("_", "-", $new_filename)),											'post_modified' => current_time('mysql'),
			'post_modified_gmt' => current_time('mysql'),
			'post_parent' => $post_id,
			'post_type' => 'attachment',
			'guid' => $siteurl.'/'.$artDir.$new_filename,
			'post_mime_type' => $file_info['mime'],
			'post_excerpt' => '',
			'post_content' => ''
		);

		$uploads = wp_upload_dir();
		$save_path = $uploads['basedir'].'/importedmedia/'.$new_filename;

		//insert the database record
		$attach_id = wp_insert_attachment( $artdata, $save_path, $post_id );

		//generate metadata and thumbnails
		if ($attach_data = wp_generate_attachment_metadata( $attach_id, $save_path)) {
			wp_update_attachment_metadata($attach_id, $attach_data);
		}

		//optional make it the featured image of the post it's attached to
		$rows_affected = $wpdb->insert($wpdb->prefix.'postmeta', array('post_id' => $post_id, 'meta_key' => '_thumbnail_id', 'meta_value' => $attach_id));
	}
	else {
		return false;
	}

	return true;
}

Tags: , ,

22 Comments to "How to programmatically import media files to WordPress"

  1. Kim Class says:

    Thanks for the information. I hope this will help me I have been looking for a post like this for the last few weeks. There just isn’t much information about importing images.

  2. Yotam says:

    Thanks a ton for this!
    Was searching all over.

  3. Sujith says:

    Thank alotttttttttttt. you saved my day

  4. Artur says:

    You sir, prevented me from a lot of work! Just thank you buddy!

  5. Mian Majid says:

    Superb code, it saved my many hours.

  6. David M. says:

    Thanks very usefull

  7. Karsten says:

    Hi! Thanks for the code – but how and from where do I call it? …

  8. Michael Cole says:

    Perfection needed to do some other little tweaks but perfection..

    Karsten if you need help…

    to call it just call the page with eg:
    site.com/importer.php

    add these lines to the very bottom to say what to import..

    $a= fetch_media(‘/var/hostdata/import/image01.jpg’,100);
    $a= fetch_media(‘/var/hostdata/import/image02.jpg’,100);

    both files will then be imported

  9. Etnea says:

    Great, it worked! 🙂

  10. Thank you very much.
    It was all I was looking for.

    I made a script to import the POST and now used their role to bring the images.

  11. AK says:

    You’re the best!))
    You’ve helped me so much, that you can’t even imagine!

    Best regards, man! and Thank YOU!

  12. Dave says:

    Great function! Thanks.

  13. Bilal Khalid says:

    That was really helpful and it saved me many hours.

    Thank you!

  14. Asher says:

    your script certainly seems to promise a cure for my headache only if I could get it to work. I have a feed of images that i need to import in. I have your script as a php file in root directory of the site (site/your script). I have a another php file that calls your function. it is not working. Any help would be greatly appreciated.

  15. Tori Tako says:

    I used this today and it worked like a charm. Just modified it a bit to loop through an array of URL’s 😀

    Thanks a bunch!

  16. Bruce says:

    Thanks! Saved me a ton of work…

  17. Lukáš says:

    Great, thank you very much!

Leave a Reply

Your email address will not be published. Required fields are marked *

Nikki Blight – Web/PHP Developer