<?php
/**
* Secure Download File
*/
if ( isset( $_GET['secure_download'] ) ) {
secure_download_file( $_GET['secure_download'], '' );
}
/**
* Encrypt All Attachment Links
*/
add_action( 'template_redirect', 'encrypt_all_attachment_links' );
function encrypt_all_attachment_links() {
ob_start( function( $buffer ) {
return preg_replace_callback(
'|/wp-content/uploads/d{4}/[^s"']+(.[^s"')]+)|',
function( $matches ) {
$file_url = get_site_url() . $matches[0];
return encrypt_file_url( $file_url, false, '' );
},
$buffer
);
});
}
/**
* Method Encrypt File Url
*
* This method will encrypt the file url.
*
* @param string $attachment_url The url of the file.
* @param bool $site_url_prefix (Optional) Should it add the site_url() before the file path? Default is true.
* @param string $ciphering (Optional) The encryption algorithm. Leave it empty for use base64.
* @param string $key (Optional) The encryption key.
* @return Encrypted_URL The encrypted url.
*/
function encrypt_file_url( string $attachment_url, bool $site_url_prefix = true, string $ciphering = 'AES-128-CBC', string $key = 'YOUR_KEY_HERE' ) {
// Parse the URL into components
$attachment_arr = parse_url($attachment_url, -1);
// Store the scheme and host into a separate variable
$attachment_site = $attachment_arr['scheme'] . '://' . $attachment_arr['host'] . '/';
// Store the path component of the URL
$attachment_path = $attachment_arr['path'];
// Encrypt the path component of the URL
if ( empty( $ciphering ) ) {
//Just use base64
$encrypted_url = base64_encode( $attachment_path );
} else {
//Use ciphering algorithm
$encrypted_url = openssl_encrypt( $attachment_path, $ciphering, $key, 0, base64_encode( $key ) );
//Use base64 for becoming url friendly
$encrypted_url = base64_encode( $encrypted_url );
}
// Concatenate the scheme and host with the encrypted path and return the result
if ( $site_url_prefix ) {
return $attachment_site . '?secure_download=' . $encrypted_url;
} else {
return '?secure_download=' . $encrypted_url;
}
}
/**
* Method Secure Download File
*
* This method will decrypt the file path and view or download it.
*
* @param string $file_hash The encrypted url.
* @param string $ciphering (Optional) The encryption algorithm. Leave it empty to use base64.
* @param string $key (Optional) The encryption key.
* @param string $disposition (Optional) The beheaviour: inline means that it will open in the browser / attachment will download the file.
* @return void
*/
function secure_download_file( string $file_hash, string $ciphering = 'AES-128-CBC', string $key = 'YOUR_KEY_HERE', string $disposition = 'inline' ) {
//Decode base64
$file_hash_decoded = base64_decode( $file_hash );
//Decrypt path to file
if ( empty( $ciphering ) ) {
$decrypted_url = $file_hash_decoded;
} else {
//Decrypt using cipher
$decrypted_url = openssl_decrypt( $file_hash_decoded, $ciphering, $key, 0, base64_encode( $key ) );
}
//Build full file path
$file_path = site_url() . $decrypted_url;
//Download file
header( 'Content-Description: File Transfer' );
header( 'Content-Type: application/octet-stream' );
header( 'Content-Disposition: ' . $disposition . '; filename="'.basename( $file_path ).'"' );
header( 'Expires: 0' );
header( 'Cache-Control: must-revalidate' );
header( 'Pragma: public' );
//Ignore SSL
stream_context_set_default(
[
'ssl' => [
'verify_peer' => false,
'verify_peer_name' => false,
],
]
);
readfile( $file_path );
}//
