Skip to content

Instantly share code, notes, and snippets.

@hissy
Created November 7, 2013 11:07
Show Gist options
  • Save hissy/7352933 to your computer and use it in GitHub Desktop.
Save hissy/7352933 to your computer and use it in GitHub Desktop.
[WordPress] Add file to media library programmatically
<?php
$file = '/path/to/file.png';
$filename = basename($file);
$upload_file = wp_upload_bits($filename, null, file_get_contents($file));
if (!$upload_file['error']) {
$wp_filetype = wp_check_filetype($filename, null );
$attachment = array(
'post_mime_type' => $wp_filetype['type'],
'post_parent' => $parent_post_id,
'post_title' => preg_replace('/\.[^.]+$/', '', $filename),
'post_content' => '',
'post_status' => 'inherit'
);
$attachment_id = wp_insert_attachment( $attachment, $upload_file['file'], $parent_post_id );
if (!is_wp_error($attachment_id)) {
require_once(ABSPATH . "wp-admin" . '/includes/image.php');
$attachment_data = wp_generate_attachment_metadata( $attachment_id, $upload_file['file'] );
wp_update_attachment_metadata( $attachment_id, $attachment_data );
}
}
@hissy
Copy link
Author

hissy commented Aug 5, 2019

@thegreentimtam $attachment_id is the newly created post id

@fredbradley
Copy link

Hey - been using this for a while and it works great.

However I have a new requirement where I just want to import images to Media Library, but NOT set as attachment to particular post.

Is that possible? All the functions here require a $parent_post_id

@fredbradley
Copy link

Sorry - just read the docs for wp_insert_attachment().. turns out you don't have to supply a parent id.

https://codex.wordpress.org/Function_Reference/wp_insert_attachment

@hissy
Copy link
Author

hissy commented Aug 8, 2019

Yup, you don't have to pass $parent_post_id if you don't want to attach it

@srjwebster
Copy link

This works consistently as long as you're not waiting for the reply. I am using a rest endpoint to generate products from a remote source and using a method link this to create the images.

I have found if you have more than a few media sizes this can easily risk timing out the web-server if it has an anywhere near reasonable wait time.

A site I'm using has 28 different media sizes and we never manage to run the wp_generate_attachment_metadata and get a reply before the timeout is reached. Annoyingly our service then assumes failure and tries again, and again and again. Eventually crashing the server and leaving us with hundreds of duplicate images!

Just recording this here as its top of google for timeouts regarding the use of this function.

@fabriziofeitosa
Copy link

@srjwebster
I am in the same situation. No solution for multiple uploads.

@srjwebster
Copy link

@srjwebster
I am in the same situation. No solution for multiple uploads.

@fabriziofeitosa I found that by removing some unused media sizes, and by turning off image optimisation plugin wp smush I could run this n a much shorter timeframe. A few seconds compared to several minutes. Definitely not a solution, something asynchronous seems necessary to do this on a frequent basis.

@abhijitaitwade
Copy link

Script is very good and its worked.

Thanks!!

@ibabul
Copy link

ibabul commented Aug 6, 2020

Life Saver

@ravahdati
Copy link

Thanks a lot, your code is very good.

@mintbird
Copy link

It's worked on WP 5.6!

@diazoxide
Copy link

Not working.

Fatal error: Call to undefined function wp_get_current_user() in /home/username/public_html/wp/wp-includes/capabilities.php on line 424

Run your code on init hook

@tuan-ph
Copy link

tuan-ph commented Sep 9, 2021

If you receive the file via method POST like:
$file = (binary)
instead of absolute path like this:
$file = '/path/to/file.png';

You have to use $file['tmp_name'] when calling wp_upload_bits
wp_upload_bits($filename, null, file_get_contents($file['tmp_name']))

The rest of above code works great!
Thanks again.

@SyntaxError843
Copy link

wp_insert_attachment has the option to return a WP Error instance on failure set to false by default, it will return a zero instead.

So the check for is_wp_error will always return false unless you supply true as a 4th argument.

wp_insert_attachment( $attachment, $upload_file['file'], $parent_post_id, true )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment