Last active
May 11, 2018 07:35
-
-
Save kierzniak/12dce0c39b0e38fd82a480706e86d8da to your computer and use it in GitHub Desktop.
Provide custom download link for password protected files
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Provide custom download link for password protected files | |
*/ | |
/** | |
* This probably should not be constant but for sake of example | |
* leave it like this; | |
*/ | |
define( 'PASSWORD_PROTECTED_POST_ID', 10 ); | |
/** | |
* Register activation hooks. Only works in plugin file. | |
*/ | |
register_activation_hook( __FILE__ , 'motivast_download_file_activate' ); | |
register_deactivation_hook( __FILE__ , 'motivast_download_file_activate' ); | |
/** | |
* Activation function | |
*/ | |
function motivast_download_file_activate() { | |
motivast_add_download_file_rewrite_rule(); | |
flush_rewrite_rules(); | |
} | |
/** | |
* Deactivation function | |
*/ | |
function motivast_download_file_deactivate() { | |
flush_rewrite_rules(); | |
} | |
/** | |
* Add rewrite rule for file download | |
* | |
* @return void | |
*/ | |
function motivast_add_download_file_rewrite_rule() { | |
/** | |
* This rewrite rule will match sample following link | |
* | |
* /download/91162629d258a876ee994e9233b2ad87 | |
* | |
* and "redirect" it to index.php with such a arguments | |
* | |
* index.php?download=1&download_id=91162629d258a876ee994e9233b2ad87 | |
*/ | |
add_rewrite_rule( '^download/([a-z0-9]{32})/?', 'index.php?download=1&download_id=$matches[1]', 'top' ); | |
} | |
/** | |
* Make WordPress aware of new query vars | |
* | |
* @param array $vars Query variables | |
* | |
* @return array | |
*/ | |
function motivast_add_download_query_vars( $vars ) { | |
$vars[] = 'download'; | |
$vars[] = 'download_id'; | |
return $vars; | |
} | |
add_filter( 'query_vars', 'motivast_add_download_query_vars' ); | |
/** | |
* Generate unique md5 id for every attachment when it is saved | |
* to the database | |
* | |
* @param array $data Array of updated attachment meta data. | |
* @param int $attachment_id Attachment post ID. | |
* | |
* @return array Post | |
*/ | |
function motivast_generate_unique_id_for_attachment( $data, $attachment_id ) { | |
/** | |
* Not secure but for our purpose suffcient | |
*/ | |
$id = md5( uniqid( mt_rand(), true) ); | |
update_post_meta( $attachment_id, '_mv_download_id', $id ); | |
return $data; | |
} | |
add_filter( 'wp_update_attachment_metadata', 'motivast_generate_unique_id_for_attachment', 10, 2 ); | |
/** | |
* Check if current url is download url and dowload file | |
* only when user have permission to do it. | |
* | |
* @return void | |
*/ | |
function motivast_download_file() { | |
$download = (int) filter_var( get_query_var('download'), FILTER_SANITIZE_NUMBER_INT ); | |
$download_id = filter_var( get_query_var('download_id'), FILTER_SANITIZE_STRING ); | |
/** | |
* Do not execute rest of the code if | |
* we are not on download url. | |
*/ | |
if( $download !== 1 ) { | |
return false; | |
} | |
/** | |
* Show 404 if user do not provde password for password protected post. | |
*/ | |
if ( post_password_required( PASSWORD_PROTECTED_POST_ID ) ) { | |
motivast_show_404_page(); | |
exit; | |
} | |
/** | |
* Get dowload file post | |
*/ | |
$args = array( | |
'post_type' => 'attachment', | |
'post_status' => 'inherit', | |
'meta_query' => array( | |
array( | |
'key' => '_mv_download_id', | |
'value' => $download_id, | |
'compare' => '=', | |
) | |
) | |
); | |
$query = new WP_Query($args); | |
/** | |
* Show 404 if there is no such a download file | |
*/ | |
if( ! $query->have_posts() ) { | |
motivast_show_404_page(); | |
exit; | |
} | |
$downloads = $query->get_posts(); | |
$download = current( $downloads ); | |
$path = get_attached_file( $download->ID ); | |
motivast_stream_file( $path, $download->post_mime_type ); | |
} | |
add_action( 'wp', 'motivast_download_file' ); | |
/** | |
* Stream file to browser | |
* | |
* @param string $path Full file path | |
* @param string $mime_type File mime type | |
* | |
* @return void | |
*/ | |
function motivast_stream_file( $path, $mime_type ) { | |
$fp = fopen( $path, 'rb' ); | |
header( 'Content-Type: ' . $mime_type ); | |
header( 'Content-Length: ' . filesize( $path ) ); | |
header( 'Content-Disposition: attachment; filename="' . basename( $path ) . '";'); | |
header( 'Content-Transfer-Encoding: binary'); | |
fpassthru( $fp ); | |
exit; | |
} | |
/** | |
* Show 404 page | |
* | |
* @return void | |
*/ | |
function motivast_show_404_page() { | |
global $wp_query; | |
$wp_query->set_404(); | |
status_header( 404 ); | |
get_template_part( 404 ); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment