Great Work
-
Use it to secure some of my contents on a mid sized Page.
Did some additional stuff to it:- Woocommerce membership (checks if a user already payed for chosen content or is subscriber)
- Add options to the Divi theme&Builder to restrict access to sections/blocks the same way as the media vault would do
- rewritten file serve code to handle ranged/streamed video and or other big data packages
- action added to use an s3 as primary file delivery as private links and the media vault as fallback (fileOnS3?header location s3:serve file)
If requested i’ll assist on similar topics.
If anybody is interested in the rewritten file serving php thing:
the following code is a part of the “mv-file-handler.php” file – there where no actions to overrule so i had to modify the original source:function mgjp_mv_get_file($rel_file, $action = ''){ // $rel_file = path to the file to view/download, // relative to the WP uploads folder // (eg:'/media-vault/2013/10/media-vault-150x150.jpg') $upload_dir = wp_upload_dir(); // only files in the WP uploads directory are allowed to be accessed: $file = rtrim($upload_dir['basedir'], '/').str_replace('..', '', isset($rel_file)?$rel_file:''); //---Basic Checks----------------------------------------------------// if(!$upload_dir['basedir'] || !is_file($file)){ status_header(404); wp_die('404. File not found.'); } $mime = wp_check_filetype($file); // Check filetype against allowed filetypes if(isset($mime['type']) && $mime['type']){ $mimetype = $mime['type']; }else{ status_header(403); wp_die(__('403. Forbidden.<br/>You cannot directly access files of this type in this directory on this server. Please contact the website administrator.')); } //---Permission Checks-----------------------------------------------// $file_info = pathinfo($rel_file); // check if file is protected by checking // if it is in the protected folder before // doing any permission checks if(0 === stripos($file_info['dirname'].'/', mgjp_mv_upload_dir('/', true))){ // disable caching of this page by caching plugins ------// if(!defined('DONOTCACHEPAGE')) define('DONOTCACHEPAGE', 1); if(!defined('DONOTCACHEOBJECT')) define('DONOTCACHEOBJECT', 1); if(!defined('DONOTMINIFY')) define('DONOTMINIFY', 1); //-------------------------------------------------------// // try and get attachment id from url -------------------// global $wpdb; $attachments = $wpdb->get_results( $wpdb->prepare( " SELECT post_id, meta_value FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value LIKE %s ", '_wp_attachment_metadata', '%'.$file_info['basename'].'%' ), ARRAY_A ); $attachment_id = false; foreach($attachments as $attachment){ $meta_value = unserialize($attachment['meta_value']); if(ltrim(dirname($meta_value['file']), '/') == ltrim($file_info['dirname'], '/')){ $attachment_id = $attachment['post_id']; break; } } // ------------------------------------------------------// if(!$permission = mgjp_mv_get_the_permission($attachment_id)) $permission = get_option('mgjp_mv_default_permission', 'logged-in'); $permissions = mgjp_mv_get_the_permissions(); // permission set up error detection $standard_error_txt = ' '.esc_html__('Therefore for safety and privacy reasons this file is unavailable. Please contact the website administrator.', 'media-vault').'<p><a href="'.home_url().'">←'.esc_html__('Return to homepage', 'media-vault').'</a></p>'; if(!isset($permissions[$permission])) wp_die(__('The permissions set for this file are not recognized.', 'media-vault').$standard_error_txt); if(!isset($permissions[$permission]['logged_in'])) $errors[] = 'logged_in'; if(!isset($permissions[$permission]['cb'])) $errors[] = 'cb'; if(isset($errors)){ $error_txt = __('The permissions set for this file have left the following important parameters undefined:', 'media-vault') .'<ul><li>\''.implode('\'</li><li>\'', $errors).'\'</li></ul>' .'<p>'.$standard_error_txt.'</p>'; wp_die($error_txt); } if($permissions[$permission]['logged_in']) is_user_logged_in() || auth_redirect(); // using is_user_logged_in is lighter than using just auth_redirect if(false !== $permissions[$permission]['cb']){ if(!is_callable($permissions[$permission]['cb'])) wp_die(__('The permission checking function set in this file\'s permissions is not callable.', 'media-vault').$standard_error_txt); $permission_check = call_user_func_array($permissions[$permission]['cb'], array($attachment_id, $rel_file, $file)); if(is_wp_error($permission_check)) wp_die($permission_check->get_error_message().$standard_error_txt); if(true !== $permission_check) wp_die(__('You do not have sufficient permissions to view this file.', 'media-vault').$standard_error_txt); } if(function_exists('attachment_get_remote_url') && $remote_url = attachment_get_remote_url($attachment_id)){ header("Location: ".$remote_url,TRUE,307); } } // end of permission checks //-------------------------------------------------------------------// $filesize = filesize($file); header('Content-Type: '.$mimetype); // always send this if(false === strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS')) header('Content-Length: '.$filesize); if('safeforce' !== $action){ //--OPEN FILE IN BROWSER functions-------------// $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('Cache-Control: no-store, no-cache, must-revalidate'); // HTTP 1.1. header('Pragma: no-cache'); // HTTP 1.0. header('Expires: Thu, 01 Dec 1994 16:00:00 GMT'); // Proxies // 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; } }else{ //--FORCE DOWNLOAD Functions-----------------------// // required for IE, otherwise Content-disposition is ignored if(ini_get('zlib.output_compression')) ini_set('zlib.output_compression', 'Off'); header('Pragma: public'); // required header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Cache-Control: private', false); // required for certain browsers header('Content-Disposition: attachment; filename="'.$file_info['basename'].'";'); header('Content-Transfer-Encoding: binary'); } // If we made it this far, just serve the file if(ob_get_length()) ob_clean(); $filesize = filesize($file); //Handel partial request header("Accept-Ranges: 0-$filesize"); $buffer_size = 1024 * 1024; //1MB #bigger = more ram usage but less cpu if(isset($_SERVER['HTTP_RANGE'])){ preg_match('/bytes=(\d+)-(\d+)?/', $_SERVER['HTTP_RANGE'], $matches); $offset = intval($matches[1]); $length = intval(isset($matches[2])?intval($matches[2]) - $offset:$filesize - $offset); if($length < 1) $length = $filesize - $offset; if($length > $buffer_size*10) $length = $buffer_size*10;//limit max partial *will trigger a ERR_CONTENT_LENGTH_MISMATCH on client but will perform better... header('HTTP/1.1 206 Partial Content'); header('Content-Range: bytes '.$offset.'-'.($offset + $length).'/'.$filesize); $file = fopen($file, 'r'); // seek to the requested offset, this is 0 if it's not a partial content request fseek($file, $offset); //split the file so we could <code>stream</code> just the range we need while($length > 0 && !feof($file)){ if($length > $buffer_size) $bytes_to_read = $buffer_size; else $bytes_to_read = $length; $length -= $bytes_to_read; echo fread($file, $bytes_to_read); flush(); } fclose($file); exit; } flush(); readfile($file); exit; }
- The topic ‘Great Work’ is closed to new replies.