Skip to content

Instantly share code, notes, and snippets.

@RadGH
Last active February 2, 2024 15:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RadGH/be30af96617b13e7848a4626ef179bbd to your computer and use it in GitHub Desktop.
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.…
<?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;
}
@RadGH
Copy link
Author

RadGH commented Feb 2, 2024

This plugin was created to test my function rs_upload_from_url() which has its own Gist page here: https://gist.github.com/RadGH/966f8c756c5e142a5f489e86e751eacb

To use this plugin:

  1. Download this script from Gist, or use this link 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.

When you run the test script, the results should look like this:

Screenshot of the test results screen showing four images that were uploaded.

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