Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Wordpress login to download uploaded files

Upload protected.php to root of WordPress website. The redirection rules is where all of the magic happens. With WP Engine use the following to target any file uploading in the media library with the -protected in the file name.

For example /wp-content/uploads/2016/08/logo**-protected**.jpg with be redirected to /protected.php?file=/2016/08/logo-protected.jpg.

<?php
/*
* protected.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
*/
// Fix to allow for large files without exhausting PHP memory: http://stackoverflow.com/questions/6627952/why-does-readfile-exhaust-php-memory/38986798#38986798
if (ob_get_level()) {
ob_end_clean();
}
ob_start();
require_once('wp-load.php');
require_once ABSPATH . WPINC . '/formatting.php';
require_once ABSPATH . WPINC . '/capabilities.php';
require_once ABSPATH . WPINC . '/user.php';
require_once ABSPATH . WPINC . '/meta.php';
require_once ABSPATH . WPINC . '/post.php';
require_once ABSPATH . WPINC . '/pluggable.php';
wp_cookie_constants();
$discard = ob_get_clean();
is_user_logged_in() || auth_redirect();
list($basedir) = array_values(array_intersect_key(wp_upload_dir(), array('basedir' => 1)))+array(NULL);
$file = $basedir.''.str_replace('..', '', isset($_GET[ 'file' ])?$_GET[ '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 );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.