spivurno
2/2/2017 - 4:18 PM

Easy Digital Downloads: "Could not copy file" Fix For Windows Servers

Easy Digital Downloads: "Could not copy file" Fix For Windows Servers

<?php
/**
 * Easy Digital Downloads provides packages URLs that look something like this:
 * 
 * http://mysite.com/edd-sl/package_download/MTQ4NjA1NTA0NjphMDA5MTkzZjQ0NGRiNmVmMzczY2JhNTFiZWIxMWZiYzo0NzM3MzphM2Q5ZDA3NDQwMjZjZDFmOWVhYTBiNzBjMjVlZjI0YjpodHRwQC8vbXVzaWNmZXN0aXZhbC5zY2hvb2wubno
 * 
 * This generates a temporary filename for the update process that look something like this:
 * 
 * MTQ4NjA1NTA0NjphMDA5MTkzZjQ0NGRiNmVmMzczY2JhNTFiZWIxMWZiYzo0NzM3MzphM2Q5ZDA3NDQwMjZjZDFmOWVhYTBiNzBjMjVlZjI0YjpodHRwQC8vbXVzaWNmZXN0aXZhbC5zY2hvb2wubno.tmp
 *
 * Some Windows servers choke on filenames of this size. As a result, the update wil fail and WordPress
 * will give you a "Could not copy file." error.
 *
 * This solution (which is a little weird) will check if the package URL that is about to be downloaded 
 * by WordPress is an EDD package URL. If so, it will truncate the temporary filename to 50 characters.
 */
 
// initiate a fix for Windows servers where the GP package file name is too long and prevents installs/updates from processing
add_filter( 'upgrader_pre_download', 'maybe_shorten_edd_filename', 10, 4 );

/**
 * Check if the URL that is about to be downloaded is an EDD package URL. If so, hook our function to shorten
 * the filename.
 *
 * @param mixed  $return
 * @param string $package The URL of the file to be downloaded.
 *
 * @return mixed
 */
function maybe_shorten_edd_filename( $return, $package ) {
    if( strpos( $package, '/edd-sl/package_download/' ) !== false ) {
        add_filter( 'wp_unique_filename', 'shorten_edd_filename', 10, 2 );
    }
    return $return;
}

/**
 * Truncate the temporary filename to 50 characters. This resolves issues with some Windows servers which
 * can not handle very long filenames.
 *
 * @param string $filename
 * @param string $ext
 *
 * @return string
 */
function shorten_edd_filename( $filename, $ext ) {
    $filename = substr( $filename, 0, 50 ) . $ext;
    remove_filter( 'wp_unique_filename', 'shorten_edd_filename', 10 );
    return $filename;
}