Skip to content

Instantly share code, notes, and snippets.

@cawa-93
Forked from kellenmace/class-download-remote-image.php
Last active October 14, 2024 14:31
Show Gist options
  • Save cawa-93/750e88207b15085b88263c142e854bc5 to your computer and use it in GitHub Desktop.
Save cawa-93/750e88207b15085b88263c142e854bc5 to your computer and use it in GitHub Desktop.
Download and Insert a Remote Image File into the WordPress Media Library
<?php
namespace Plugin\Sideloader;
/**
* Function handles downloading a remote file and inserting it
* into the WP Media Library.
* @param string $url HTTP URL address of a remote file
* @param int $post_id The post ID the media is associated with
* @param string $desc Description of the side-loaded file
* @param string $post_data Post data to override
*
* @see https://developer.wordpress.org/reference/functions/media_handle_sideload/
*
* @example $attachment_id = sideload( $url [, $post_id [, $desc [, $post_data]]] );
* @return int|WP_Error The ID of the attachment or a WP_Error on failure
*/
function sideloader($url, $post_id = 0, $desc = null, $post_data = null) {
// URL Validation
if ( ! wp_http_validate_url( $url ) ) {
return new WP_Error('invalid_url', 'File URL is invalid', array( 'status' => 400 ));
}
// Gives us access to the download_url() and media_handle_sideload() functions.
if( ! function_exists('download_url') || !function_exists('media_handle_sideload') ) {
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 file to temp dir.
$temp_file = download_url( $url );
if ( is_wp_error( $temp_file ) ) {
@unlink($temp_file);
return $temp_file;
}
// An array similar to that of a PHP `$_FILES` POST array
$file_url_path = parse_url($url, PHP_URL_PATH);
$file_info = wp_check_filetype( $file_url_path );
$file = array(
'tmp_name' => $temp_file,
'type' => $file_info['type'],
'name' => basename( $file_url_path ),
'size' => filesize( $temp_file ),
);
// Move the temporary file into the uploads directory.
$attachment_id = media_handle_sideload( $file, $post_id, $desc, $post_data );
@unlink($temp_file);
return $attachment_id;
}
@rxnlabs
Copy link

rxnlabs commented Jun 3, 2022

Thank you for this. This worked extremely well with a few modifications. The line where you catch a WordPress error attempts to unlink a file that was never downloaded, which leads to a fatal error and also another fatal error is thrown since $post_data defaults to null when it should be an array . To fix this:

<?php
namespace Plugin\Sideloader;

/**
 * Function handles downloading a remote file and inserting it
 * into the WP Media Library.
 * @param string $url HTTP URL address of a remote file
 * @param int $post_id The post ID the media is associated with
 * @param string $desc Description of the side-loaded file
 * @param string $post_data Post data to override
 *
 * @see https://developer.wordpress.org/reference/functions/media_handle_sideload/
 *
 * @example $attachment_id = sideload( $url [, $post_id [, $desc [, $post_data]]] );
 * @return int|WP_Error The ID of the attachment or a WP_Error on failure
 */
function sideloader($url, $post_id = 0, $desc = null, $post_data = array()) {
	// URL Validation
	if ( ! wp_http_validate_url( $url ) ) {
		return new WP_Error( 'invalid_url', 'File URL is invalid', array( 'status' => 400 ) );
	}

	// Gives us access to the download_url() and media_handle_sideload() functions.
	if ( ! function_exists( 'download_url' ) || ! function_exists( 'media_handle_sideload' ) ) {
		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 file to temp dir.
	$temp_file = download_url( $url );

	// if the file was not able to be downloaded
	if ( is_wp_error( $temp_file ) ) {
		return $temp_file;
	}

	// An array similar to that of a PHP `$_FILES` POST array
	$file_url_path = parse_url( $url, PHP_URL_PATH );
	$file_info     = wp_check_filetype( $file_url_path );
	$file          = array(
		'tmp_name' => $temp_file,
		'type'     => $file_info['type'],
		'name'     => basename( $file_url_path ),
		'size'     => filesize( $temp_file ),
	);

	if ( empty( $post_data ) ) {
		$post_data = array();
	}

	// Move the temporary file into the uploads directory.
	$attachment_id = media_handle_sideload( $file, $post_id, $desc, $post_data );


	@unlink( $temp_file );

	return $attachment_id;
}

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