-
-
Save RadGH/966f8c756c5e142a5f489e86e751eacb to your computer and use it in GitHub Desktop.
| <?php | |
| /** | |
| * This function uploads a file from a URL to the media library, designed to be placed in your own theme or plugin. | |
| * Metadata will be generated and images will generate thumbnails automatically. | |
| * | |
| * HOW TO USE: | |
| * 1. Add the function below to your theme or plugin | |
| * 2. Call the function and provide the URL to an image or other file. | |
| * 3. If successful, the attachment ID will be returned. | |
| * | |
| * BASIC USAGE: | |
| * $attachment_id = rs_upload_from_url( "https://www.gstatic.com/webp/gallery/1.jpg" ); | |
| * if ( $attachment_id ) echo wp_get_attachment_image( $attachment_id, 'large' ); | |
| * | |
| * DOWNLOAD AS A PLUGIN (optional): | |
| * Below is a link to a separate plugin you can upload to your site to help get started. | |
| * It is a fully-functional example and demonstrates upload both JPG and WEBP image by using a "secret" url. | |
| * It also provides an easy way to delete the test images that were created. | |
| * @see https://gist.github.com/RadGH/be30af96617b13e7848a4626ef179bbd | |
| * | |
| * To upload from a *LOCAL FILE PATH* instead of a URL: | |
| * @see: https://gist.github.com/RadGH/3b544c827193927d1772 | |
| */ | |
| /** | |
| * Upload a file to the media library using a URL. | |
| * | |
| * @version 1.4 | |
| * @author Radley Sustaire | |
| * @see https://gist.github.com/RadGH/966f8c756c5e142a5f489e86e751eacb | |
| * | |
| * @param string $url URL to be uploaded | |
| * @param null|string $title Override the default post_title | |
| * @param null|string $content Override the default post_content (Added in 1.3) | |
| * @param null|string $alt Override the default alt text (Added in 1.3) | |
| * @param null|string $caption Override the default caption / post excerpt (Added in 1.4) | |
| * | |
| * @return int|false | |
| */ | |
| function rs_upload_from_url( $url, $title = null, $content = null, $alt = null, $caption = null ) { | |
| require_once( ABSPATH . "/wp-load.php"); | |
| require_once( ABSPATH . "/wp-admin/includes/image.php"); | |
| require_once( ABSPATH . "/wp-admin/includes/file.php"); | |
| require_once( ABSPATH . "/wp-admin/includes/media.php"); | |
| // Download url to a temp file | |
| $tmp = download_url( $url ); | |
| if ( is_wp_error( $tmp ) ) return false; | |
| // Ignore query params to fix issues with certain URLS | |
| // @see https://gist.github.com/RadGH/966f8c756c5e142a5f489e86e751eacb?permalink_comment_id=5626880#gistcomment-5626880 | |
| $url_path = parse_url($url, PHP_URL_PATH); | |
| // Get the filename and extension ("photo.png" => "photo", "png") | |
| $filename = pathinfo($url_path, PATHINFO_FILENAME); | |
| $extension = pathinfo($url_path, PATHINFO_EXTENSION); | |
| // An extension is required or else WordPress will reject the upload | |
| if ( ! $extension ) { | |
| // Look up mime type, example: "/photo.png" -> "image/png" | |
| $mime = mime_content_type( $tmp ); | |
| $mime = is_string($mime) ? sanitize_mime_type( $mime ) : false; | |
| // Only allow certain mime types because mime types do not always end in a valid extension (see the .doc example below) | |
| $mime_extensions = array( | |
| // mime_type => extension (no period) | |
| 'text/plain' => 'txt', | |
| 'text/csv' => 'csv', | |
| 'application/msword' => 'doc', | |
| 'image/jpg' => 'jpg', | |
| 'image/jpeg' => 'jpeg', | |
| 'image/gif' => 'gif', | |
| 'image/png' => 'png', | |
| 'video/mp4' => 'mp4', | |
| ); | |
| if ( isset( $mime_extensions[$mime] ) ) { | |
| // Use the mapped extension | |
| $extension = $mime_extensions[$mime]; | |
| }else{ | |
| // Could not identify extension. Clear temp file and abort. | |
| wp_delete_file($tmp); | |
| return false; | |
| } | |
| } | |
| // Upload by "sideloading": "the same way as an uploaded file is handled by media_handle_upload" | |
| $args = array( | |
| 'name' => "$filename.$extension", | |
| 'tmp_name' => $tmp, | |
| ); | |
| // Post data to override the post title, content, and alt text | |
| $post_data = array(); | |
| if ( $title ) $post_data['post_title'] = $title; | |
| if ( $content ) $post_data['post_content'] = $content; | |
| if ( $caption ) $post_data['post_excerpt'] = $caption; | |
| // Do the upload | |
| $attachment_id = media_handle_sideload( $args, 0, null, $post_data ); | |
| // Clear temp file | |
| wp_delete_file($tmp); | |
| // Error uploading | |
| if ( is_wp_error($attachment_id) ) return false; | |
| // Save alt text as post meta if provided | |
| if ( $alt ) update_post_meta( $attachment_id, '_wp_attachment_image_alt', $alt ); | |
| // Success, return attachment ID | |
| return (int) $attachment_id; | |
| } |
@philbirnie Great suggestion, thanks! I updated the script to use wp_delete_file instead of @unlink.
Dose it support .webp format like this one?
https://a2zaitools.com/wp-content/uploads/2024/02/Drafts-AI-1024x501.webp
@mdbadsha Yep, I just tested and webp images work just fine.
To anyone else interested, I created a plugin to test this function which is available at another gist URL:
https://gist.github.com/RadGH/be30af96617b13e7848a4626ef179bbd
Instructions and a screenshot of the results are displayed on the first comment:
https://gist.github.com/RadGH/be30af96617b13e7848a4626ef179bbd#gistcomment-4870147
Hi,
The script works perfectly for URLs that have extensions like .jpg.
Can the code be adjusted for images from a URL that doesn’t have an extension, but the image can still be downloaded in jpg format?
An example is a Hikvision camera with the URL: http://user:password@publicIP/ISAPI/Streaming/channels/101/picture.
As you can see, the URL doesn’t have an extension at the end, but when the link is opened, the image is displayed and can be downloaded as a jpg.
another example is: https://unsplash.com/photos/woman-with-dslr-camera-e616t35Vbeg
@acot123 There is very basic support for that, but you will probably have to customize this part further: if ( ! $extension ) { ... }
You'll need to verify the mime_content_type is loading correctly and adjust the array of extensions if necessary.
Thanks a lot for this code! :) Two tweaks I needed in case you need them too:
Ignore query params so that URLs like this won't create a broken file.
// Get the filename and extension (".../folder/photo.png?query=..." => "photo", "png")
$url_path = parse_url($url, PHP_URL_PATH);
$filename = pathinfo($url_path, PATHINFO_FILENAME);
$extension = pathinfo($url_path, PATHINFO_EXTENSION);Set image caption if you need it.
function bc_upload_from_url([...], $caption = null ) {
[...]
if ( $caption ) $post_data['post_excerpt'] = $caption;@brickup-de Thanks for the contribution! I've added those to the original function, I think they are both useful additions.
Thanks for this! This is great, @RadGH! -- one minor suggestion: switch the
@unlink's withwp_delete_file; this will allow you to remove silence operators from your code (and, more importantly, allow the path to be filterable via thewp_delete_filefilter)