Add file extension to temporary file

The problem:

When you download an image with an extension, for example jsbach_image.jpg, it will look like this in the temp directory:

/tmp/jsbach.tmp

but when you download an image without an extension, for example mozart_image, you will get:

/tmp/mozart 

But the latter one will not pass the filetype- and extension tests in the wp_handle_sideload() function, called by the media_handle_sideload() function.

A possible solution:

We can trick it to pass the test, by renaming (or copying) the temp file with an extension.

You can try the following modifications:

/**
 * Upload an image from an url, with support for filenames without an extension
 * 
 * @link   http://wordpress.stackexchange.com/a/145349/26350
 * @param  string $imageurl
 * @return string $attachment_url
 */
function upload_image_from_url( $imageurl )
{
    require_once( ABSPATH . 'wp-admin/includes/image.php' );
    require_once( ABSPATH . 'wp-admin/includes/file.php' );
    require_once( ABSPATH . 'wp-admin/includes/media.php' );

    // Get the file extension for the image
    $fileextension = image_type_to_extension( exif_imagetype( $imageurl ) );

    // Save as a temporary file
    $tmp = download_url( $imageurl );

    // Check for download errors
    if ( is_wp_error( $tmp ) ) 
    {
        @unlink( $file_array[ 'tmp_name' ] );
        return $tmp;
    }

    // Image base name:
    $name = basename( $imageurl );

    // Take care of image files without extension:
    $path = pathinfo( $tmp );
    if( ! isset( $path['extension'] ) ):
        $tmpnew = $tmp . '.tmp';
        if( ! rename( $tmp, $tmpnew ) ):
            return '';
        else:
            $ext  = pathinfo( $imageurl, PATHINFO_EXTENSION );
            $name = pathinfo( $imageurl, PATHINFO_FILENAME )  . $fileextension;
            $tmp = $tmpnew;
        endif;
    endif;

    // Upload the image into the WordPress Media Library:
    $file_array = array(
        'name'     => $name,
        'tmp_name' => $tmp
    );
    $id = media_handle_sideload( $file_array, 0 );

    // Check for handle sideload errors:
    if ( is_wp_error( $id ) )
    {
        @unlink( $file_array['tmp_name'] );
        return $id;
    }

    // Get the attachment url:
    $attachment_url = wp_get_attachment_url( $id );

    return $attachment_url;
}  

I hope this helps.

Leave a Comment