Skip to content

Instantly share code, notes, and snippets.

@bitflower
Forked from hakre/dl-file.php
Last active October 18, 2023 18:00
Show Gist options
  • Save bitflower/8fe55c0667da8b292a71 to your computer and use it in GitHub Desktop.
Save bitflower/8fe55c0667da8b292a71 to your computer and use it in GitHub Desktop.
File protection depending on ACF (Advanced custom fields) field.
<?php
/*
* dl-file.php
*
* Protect uploaded files with login.
*
* @link http://wordpress.stackexchange.com/questions/37144/protect-wordpress-uploads-if-user-is-not-logged-in
*
* @author hakre <http://hakre.wordpress.com/>
* @license GPL-3.0+
* @registry SPDX
*/
require_once('wp-load.php');
// Read file parameter
list($basedir) = array_values(array_intersect_key(wp_upload_dir(), array('basedir' => 1)))+array(NULL);
$file = rtrim($basedir, '/') . '/' . str_replace('..', '', isset($_GET['file']) ? $_GET['file'] : '');
// Is the file set as protected?
$upload_dir_paths = wp_upload_dir();
$parts = explode("uploads", $file);
$fileFull = $upload_dir_paths['baseurl'] . $parts[1];
$attID = pn_get_attachment_id_from_url($fileFull);
$isProtected = get_field('geschuetzt', $attID);
if ($isProtected) {
// If the user isn't logged in -> redirect to login page
if (is_user_logged_in() == false) {
// User is not logged in
auth_redirect();
}
}
// Otherwise deliver file
if (!$basedir || !is_file($file)) {
status_header(404);
die('404 &#8212; File not found.');
}
$mime = wp_check_filetype($file);
if( false === $mime[ 'type' ] && function_exists( 'mime_content_type' ) )
$mime[ 'type' ] = mime_content_type( $file );
if( $mime[ 'type' ] )
$mimetype = $mime[ 'type' ];
else
$mimetype = 'image/' . substr( $file, strrpos( $file, '.' ) + 1 );
header( 'Content-Type: ' . $mimetype ); // always send this
if ( false === strpos( $_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS' ) )
header( 'Content-Length: ' . filesize( $file ) );
$last_modified = gmdate( 'D, d M Y H:i:s', filemtime( $file ) );
$etag = '"' . md5( $last_modified ) . '"';
header( "Last-Modified: $last_modified GMT" );
header( 'ETag: ' . $etag );
header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', time() + 100000000 ) . ' GMT' );
// Support for Conditional GET
$client_etag = isset( $_SERVER['HTTP_IF_NONE_MATCH'] ) ? stripslashes( $_SERVER['HTTP_IF_NONE_MATCH'] ) : false;
if( ! isset( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) )
$_SERVER['HTTP_IF_MODIFIED_SINCE'] = false;
$client_last_modified = trim( $_SERVER['HTTP_IF_MODIFIED_SINCE'] );
// If string is empty, return 0. If not, attempt to parse into a timestamp
$client_modified_timestamp = $client_last_modified ? strtotime( $client_last_modified ) : 0;
// Make a timestamp for our most recent modification...
$modified_timestamp = strtotime($last_modified);
if ( ( $client_last_modified && $client_etag )
? ( ( $client_modified_timestamp >= $modified_timestamp) && ( $client_etag == $etag ) )
: ( ( $client_modified_timestamp >= $modified_timestamp) || ( $client_etag == $etag ) )
) {
status_header( 304 );
exit;
}
// If we made it this far, just serve the file
readfile( $file );
// Function that returns the ID from the URL of an attachment
function pn_get_attachment_id_from_url($attachment_url = '') {
global $wpdb;
$attachment_id = false;
// If there is no url, return.
if ('' == $attachment_url) {
return;
}
// Get the upload directory paths
$upload_dir_paths = wp_upload_dir();
// Make sure the upload path base directory exists in the attachment URL, to verify that we're working with a media library image
if (false !== strpos($attachment_url, $upload_dir_paths['baseurl'])) {
// If this is the URL of an auto-generated thumbnail, get the URL of the original image
$attachment_url = preg_replace('/-\d+x\d+(?=\.(jpg|jpeg|png|gif)$)/i', '', $attachment_url);
// Remove the upload path base directory from the attachment URL
$attachment_url = str_replace($upload_dir_paths['baseurl'] . '/', '', $attachment_url);
// Finally, run a custom database query to get the attachment ID from the modified attachment URL
$attachment_id = $wpdb->get_var($wpdb->prepare("SELECT wposts.ID FROM $wpdb->posts wposts, $wpdb->postmeta wpostmeta WHERE wposts.ID = wpostmeta.post_id AND wpostmeta.meta_key = '_wp_attached_file' AND wpostmeta.meta_value = '%s' AND wposts.post_type = 'attachment'", $attachment_url));
}
return $attachment_id;
}
@bitflower
Copy link
Author

Place file in WP root (where wp-config.php etc. reside). Add these lines to your .htaccess:

RewriteCond %{REQUEST_FILENAME} -s
RewriteRule ^wp-content/uploads/(.*)$ dl-file.php?file=$1 [QSA,L]

Credit goes to hakre, see this post:
http://wordpress.stackexchange.com/questions/37144/how-to-protect-uploads-if-user-is-not-logged-in

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment