Last active
February 2, 2024 15:15
-
-
Save RadGH/be30af96617b13e7848a4626ef179bbd to your computer and use it in GitHub Desktop.
WordPress Plugin used to test uploading images from a URL using the function rs_upload_from_url(). Here is a link to a screenshot of the results screen: https://s3.us-west-2.amazonaws.com/elasticbeanstalk-us-west-2-868470985522/ShareX/2024/02/chrome_2024-02-02_07-03-56.jpg. Here is a link to usage instructions, and how to download: https://gist.…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
Plugin Name: RS Sideload Test | |
Description: Test your website's ability to upload images from a URL using the function `rs_upload_from_url()`. To get started, visit your site url ending in `?rs_9e86e751eacb` to run the tool. See Gist at the plugin URL below for more information. | |
Plugin URI: https://gist.github.com/RadGH/be30af96617b13e7848a4626ef179bbd | |
Author: Radley Sustaire | |
Author URI: https://gist.github.com/RadGH | |
Version: 1.3.1 | |
*/ | |
// Gist for this plugin: | |
// https://gist.github.com/RadGH/be30af96617b13e7848a4626ef179bbd | |
// Gist for the original function: | |
// https://gist.github.com/RadGH/966f8c756c5e142a5f489e86e751eacb | |
// How to use: | |
// 1. Download the plugin from Gist, or click here to download as a Zip: https://gist.github.com/RadGH/be30af96617b13e7848a4626ef179bbd/download | |
// 2. Upload the plugin to WordPress and activate it. | |
// 3. Visit your website url ending with: ?rs_9e86e751eacb | |
// 4. The test will upload 4 images from a Google CDN. | |
// 5. Each image will display the result, a preview, and links to edit or delete the image. | |
// 6. A button to delete all test images is available at the end. | |
// | |
// To see an example of the result page | |
// @see https://s3.us-west-2.amazonaws.com/elasticbeanstalk-us-west-2-868470985522/ShareX/2024/02/chrome_2024-02-02_07-03-56.jpg | |
if ( ! defined('ABSPATH') ) exit; | |
// Call the main function when ?rs_9e86e751eacb is provided in the URL. | |
if ( isset($_GET['rs_9e86e751eacb']) ) { | |
add_action( 'init', 'rs_test_local_file_upload' ); | |
} | |
/** | |
* The main function to test url image uploads and display the results, and offers a way to quickly delete them. | |
* | |
* @return void | |
*/ | |
function rs_test_local_file_upload() { | |
// Support to delete all test images that have been uploaded. | |
// This uses post meta so it shouldn't interfere with other images. | |
if ( isset($_GET['delete_all']) ) { | |
$test_images = new WP_Query( array( | |
'post_type' => 'attachment', | |
'meta_key' => 'rs_test_image', | |
'meta_value' => '9e86e751eacb', | |
'post_status' => 'any', | |
'posts_per_page' => -1, | |
) ); | |
$count = 0; | |
$failed = array(); | |
if ( $test_images->have_posts() ) { | |
while ( $test_images->have_posts() ) { | |
$test_images->the_post(); | |
if ( wp_delete_attachment( get_the_ID(), true ) ) { | |
$count += 1; | |
}else{ | |
$failed[] = get_the_ID(); | |
} | |
} | |
} | |
$message = '<p>Deleted '. $count .' test image(s).</p>'; | |
if ( $failed ) { | |
$message .= '<p>Failed to delete: '. implode(', ', $failed) .'</p>'; | |
} | |
$message .= '<p><a href="'. esc_attr(admin_url('upload.php')) .'" class="button">Go to Media</a></p>'; | |
wp_die( $message, 'Test Images Deleted', array( 'response' => 200 ) ); | |
exit; | |
} | |
// When deleting a single image at a time, WordPress redirects back to the same URL. | |
// Rather than run this tool again, we just show the image was deleted. | |
if ( isset($_GET['deleted']) ) { | |
$message = '<p>Image deleted</p>'; | |
$message .= '<p><a href="'. esc_attr(admin_url('upload.php')) .'" class="button">Go to Media</a></p>'; | |
// Add JS to automatically close the page | |
$message .= '<script>window.close();</script>'; | |
wp_die( $message, 'Image Deleted', array( 'response' => 200 ) ); | |
exit; | |
} | |
// Here are the images that will be uploaded. | |
// The images are from Google's WEBP demonstration page: | |
// @see https://developers.google.com/speed/webp/gallery1 | |
// | |
$image_urls = array( | |
'https://www.gstatic.com/webp/gallery/1.jpg', | |
'https://www.gstatic.com/webp/gallery/1.webp', | |
'https://www.gstatic.com/webp/gallery/2.jpg', | |
'https://www.gstatic.com/webp/gallery/2.webp', | |
// 'https://www.gstatic.com/webp/gallery/3.jpg', | |
// 'https://www.gstatic.com/webp/gallery/3.webp', | |
// 'https://www.gstatic.com/webp/gallery/4.jpg', | |
// 'https://www.gstatic.com/webp/gallery/4.webp', | |
// 'https://www.gstatic.com/webp/gallery/5.jpg', | |
// 'https://www.gstatic.com/webp/gallery/5.webp', | |
); | |
// The URL to delete all test images that were uploaded | |
$delete_all_url = add_query_arg(array('delete_all' => 1)); | |
// Page title to show the results | |
$page_title = 'Test File Upload from URL'; | |
// Build the result as $message | |
$message = '<h2>'. esc_html($page_title) .'</h2>'; | |
$message .= '<p>This example will upload '. count($image_urls) .' image(s) using <code>rs_upload_from_url()</code>. For more details <a href="https://gist.github.com/RadGH/be30af96617b13e7848a4626ef179bbd" target="_blank">view the plugin on Gist</a>.</p>'; | |
// Start image container | |
$message .= '<div class="image-results">'; | |
// Upload each file and show the result | |
foreach ( $image_urls as $url ) { | |
$filename = basename($url); | |
// Post title, content, and alt text are optional. | |
$post_title = 'Test Image: ' . $filename; | |
$post_content = 'This is a test image uploaded from the URL: ' . $url; | |
$alt_text = 'This alt text is for a test image named ' . $filename; | |
// Here is where the magic happens | |
$attachment_id = rs_upload_from_url( $url, $post_title, $post_content, $alt_text ); | |
// Show the result for the image | |
$message .= '<div class="image-result">'; | |
$message .= '<h3>'. esc_html($filename) .' - Upload '. ($attachment_id ? 'Success' : 'Failed') .'</h3>'; | |
if ( $attachment_id ) { | |
// Upload successful, show the image and links to edit and delete | |
$edit_url = get_edit_post_link($attachment_id); | |
$image_url = wp_get_attachment_image_url($attachment_id, 'medium'); | |
$trash_url = get_delete_post_link($attachment_id, '', true); | |
// Post meta to identify these test images to bulk delete later | |
update_post_meta( $attachment_id, 'rs_test_image', '9e86e751eacb' ); | |
// Show the image | |
$message .= '<p><a href="'. esc_attr($image_url) .'" target="_blank"><img src="'. esc_attr($image_url) .'" style="width: auto; height: auto; max-width: 100%; max-height: 350px;" alt=""></a></p>'; | |
// Show some links | |
$message .= '<p class="buttons"><a href="'. esc_url( $edit_url ) .'" target="_blank" class="button">Edit</a> <a href="'. esc_url( $trash_url ) .'" target="_blank" class="button">Delete</a></p>'; | |
} | |
// End of a single image result | |
$message .= '</div>'; | |
} | |
// End of image container | |
$message .= '</div>'; | |
// End of all images. Show a link to bulk delete all test images. | |
$message .= '<p class="submit"><a href="'. esc_url( $delete_all_url ) .'" class="button">Delete all test images</a></p>'; | |
// Show a link to the media library | |
$message .= '<p><a href="'. esc_attr(admin_url('upload.php')) .'" class="button">Go to Media</a></p>'; | |
// Add CSS to format in a grid | |
$message .= '<style>.image-results { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 15px; } .image-result { padding: 0 20px 10px; border: 1px solid #ddd; } .buttons { text-align: center; }</style>'; | |
// Add JS to make an image transparent when the delete link is opened | |
$message .= '<script>document.querySelectorAll(".image-result a.button").forEach((btn) => {btn.addEventListener("click", () => {btn.closest(".image-result").querySelector("img").style.opacity=0.25; btn.closest(".buttons").remove();})});</script>'; | |
// Show the results in a wp_die screen | |
wp_die( $message, $page_title, array( 'response' => 200 ) ); | |
exit; | |
} | |
/** | |
* Upload a file to the media library using a URL. | |
* | |
* @version 1.3 | |
* @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) | |
* | |
* @return int|false | |
*/ | |
function rs_upload_from_url( $url, $title = null, $content = null, $alt = 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; | |
// Get the filename and extension ("photo.png" => "photo", "png") | |
$filename = pathinfo($url, PATHINFO_FILENAME); | |
$extension = pathinfo($url, 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; | |
// 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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This plugin was created to test my function
rs_upload_from_url()
which has its own Gist page here: https://gist.github.com/RadGH/966f8c756c5e142a5f489e86e751eacbTo use this plugin:
When you run the test script, the results should look like this: