Skip to content

Instantly share code, notes, and snippets.

@kierzniak
Last active May 11, 2018 07:35
Show Gist options
  • Save kierzniak/12dce0c39b0e38fd82a480706e86d8da to your computer and use it in GitHub Desktop.
Save kierzniak/12dce0c39b0e38fd82a480706e86d8da to your computer and use it in GitHub Desktop.
Provide custom download link for password protected files
<?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