+ .htaccess';
+ $rewrite_file_loc = '' . $home_path . '';
+ $rewrite_rule_loc = sprintf( wp_kses( __( 'in the WordPress rewrite block (the WordPress block usually starts with %s and ends with %s), just below the line reading %s', 'media-vault' ), array( 'strong' => array() ), false ), '# BEGIN WordPress', '# END WordPress', 'RewriteRule ^index\.php$ - [L]' );
+
+ if ( ! is_multisite() && ! get_option( 'permalink_structure' ) ) {
+
+ $rewrite_rule_loc = __( 'above any other rewrite rules in the file.', 'media-vault' );
+
+ printf( wp_kses( __( 'Media Vault works best with %s enabled, so it is strongly recommended that you %s! If, however, you really really want to use ugly permalinks, then...', 'media-vault' ), array( 'i' => array() ), false ), '' . esc_html__( 'Pretty Permalinks', 'media-vault' ) . '', '' . esc_html__( 'enable them', 'media-vault' ) . '' );
+ echo "\n";
+ }
+
+ printf( esc_html__( 'Add the following to your %s file in %s', 'media-vault' ), $rewrite_file_type, $rewrite_file_loc );
+ echo ' ', $rewrite_rule_loc;
+ ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/mv-extra-deactivation-steps.php b/mv-extra-deactivation-steps.php
new file mode 100644
index 0000000..21ae81a
--- /dev/null
+++ b/mv-extra-deactivation-steps.php
@@ -0,0 +1,233 @@
+
+ * @license GPL-3.0+
+ */
+
+
+
+/**
+ * Display a notice in WP admin to the Admins to prompt
+ * them to do the extra steps to fully deactivate the
+ * Media Vault plugin
+ *
+ * @since 0.8.5
+ */
+function mgjp_mv_extra_deactivation_steps_notice() {
+
+ // only show to admins on single site install or
+ // network admins on multisite install
+ if ( ! current_user_can( 'install_plugins' ) )
+ return;
+
+ $screen = get_current_screen();
+ if ( is_multisite() ) {
+ if ( 'plugins-network' !== $screen->id )
+ return;
+ } else {
+ if ( 'plugins' !== $screen->id )
+ return;
+ }
+
+ if ( 'disallowed' !== get_site_option( 'mgjp_mv_deactivation' ) )
+ return;
+
+ mgjp_mv_admin_notice(
+ '' . __( 'Almost done!', 'media-vault' ) . ' - ' . __( 'Because of your setup, Media Vault requires some extra steps before it is deactivated. If you really want to deactivate, just click the button and follow the instructions!', 'media-vault' ),
+ array(
+ array(
+ 'link' => network_admin_url( 'plugins.php?page=mgjp-mv-eds' ),
+ 'text' => __( 'Fully Deactivate Media Vault', 'media-vault' )
+ ),
+ array(
+ 'link' => network_admin_url( 'plugins.php?page=mgjp-mv-eds&cancel_deactivation=1&_wpnonce=' . wp_create_nonce( 'mgjp_mv_deactivation' ) ),
+ 'text' => __( 'Cancel Deactivation', 'media-vault' )
+ )
+ )
+ );
+
+}
+add_action( 'admin_notices', 'mgjp_mv_extra_deactivation_steps_notice' );
+add_action( 'network_admin_notices', 'mgjp_mv_extra_deactivation_steps_notice' );
+
+
+/**
+ * Adds an admin page to the plugins admin menu dropdown.
+ * The page displays instructions to admins to fully deactivate
+ * the Media Vault plugin
+ *
+ * @since 0.8.5
+ */
+function mgjp_mv_extra_deactivation_steps_page() {
+
+ if ( is_multisite() && ! is_network_admin() )
+ return;
+
+ add_submenu_page(
+ 'plugins.php',
+ __( 'Media Vault Deactivation Helper', 'media-vault' ),
+ __( 'Media Vault Deactivation', 'media-vault' ),
+ 'install_plugins',
+ 'mgjp-mv-eds',
+ 'mgjp_mv_render_extra_deactivation_steps_page'
+ );
+
+}
+add_action( 'admin_menu', 'mgjp_mv_extra_deactivation_steps_page' );
+add_action( 'network_admin_menu', 'mgjp_mv_extra_deactivation_steps_page' );
+
+
+/**
+ * Render the page
+ *
+ * @since 0.8.5
+ */
+function mgjp_mv_render_extra_deactivation_steps_page() {
+
+ wp_enqueue_style( 'mgjp-mv-eas-page', plugins_url( 'css/mv-eas-page.css', __FILE__ ), 'all', null );
+
+ global $is_apache;
+
+ $home_path = get_home_path();
+ $rewrite_rules_enabled = mgjp_mv_check_rewrite_rules( true );
+ $eds_supported = $is_apache;
+
+ if ( isset( $_POST['true_deactivation'] ) ) {
+ if ( $rewrite_rules_enabled ) {
+ ?>
+
+
+ At least one Media Vault rewrite rule is still functional. Media Vault will not be properly deactivated if the rewrite rules are not removed because they will cause problems when attempting to access files that are in the Media Vault protected folders.', 'media-vault' ), array( 'em' => array(), 'strong' => array() ) ); ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Apache Server' );
+
+ if ( is_multisite() )
+ $errors['Multisite'] = sprintf( esc_html_x( 'you are running a %s installation', 'as in: "you are on a WordPress Multisite installation"', 'media-vault' ), 'WordPress MultiSite' );
+
+ if ( ! isset( $errors ) && ! get_option( 'permalink_structure' ) )
+ $errors['Nopretty'] = sprintf( esc_html_x( 'you do not have %s enabled', 'as in: "you do not have Pretty Permalinks enabled"', 'media-vault' ), '' . esc_html__( 'Pretty Permalinks' ) . '' );
+
+ if ( ! isset( $errors ) && ! is_writable( $home_path . '.htaccess' ) )
+ $errors['Nonwritable'] = sprintf( esc_html__( 'the site\'s %s file is not writable', 'as in: "the site\'s .htaccess file is not writable "', 'media-vault' ), '.htaccess' );
+
+ if ( isset( $errors ) ) {
+
+ $error_txt = '';
+ $last_error = array_pop( $errors );
+ if ( count( $errors ) > 0 )
+ $error_txt .= implode( ', ', $errors ) . ' ' . esc_html__( 'and', 'media-vault' ) . ' ';
+ $error_txt .= $last_error . ',';
+
+ printf( esc_html_x( 'However, because %s the plugin was unable to successfully update the rewrite rules for this site programmatically.', 'as in: "Because *you are running WordPress MultiSite* Media Vault cannot do it automatically"', 'media-vault' ), $error_txt );
+
+ } else {
+
+ esc_html_e( 'However for some reason the plugin was unable to successfully update the rewrite rules for this site.', 'media-vault' );
+
+ }
+
+ printf( wp_kses( __( 'In order to manually fully %s Media Vault on your setup please carefully follow the instructions below:', 'media-vault' ), array( 'strong' => array() ), false ), 'deactivate' );
+ ?>
+
+
+
+ temporarily deactivate Media Vault and do not mind leaving the rewrite rules functioning, simply click the "Temporarily Deactivate Media Vault" button. However, if you are planning on permanently deactivating Media Vault make sure to follow the steps below, otherwise you may experience problems when trying to access attachment files still in the Media Vault protected folders.', 'media-vault' ), array( 'strong' => array() ) ); ?>
+
+
+
+
+
+
+
+
+ .htaccess';
+ $rewrite_file_loc = '' . $home_path . '';
+
+ printf( wp_kses( __( 'From your %s file in %s, remove all the code between the lines starting with %s and ending with %s.', 'media-vault' ), array( 'strong' => array() ) ), $rewrite_file_type, $rewrite_file_loc, '# Media Vault Rewrite Rules', '# Media Vault Rewrite Rules End' );
+ ?>
+
';
+
+ 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' )
+ . '
\'' . implode( '\'
\'', $errors ) . '\'
'
+ . '
' . $standard_error_txt . '
';
+ 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 );
+ }
+
+ } // end of permission checks
+
+ //-------------------------------------------------------------------//
+
+ header( 'Content-Type: ' . $mimetype ); // always send this
+ if ( false === strpos( $_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS' ) )
+ header( 'Content-Length: ' . filesize( $file ) );
+
+ 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();
+
+ flush();
+
+ readfile( $file );
+ exit;
+}
\ No newline at end of file
diff --git a/mv-metaboxes.php b/mv-metaboxes.php
new file mode 100644
index 0000000..d7a85fe
--- /dev/null
+++ b/mv-metaboxes.php
@@ -0,0 +1,178 @@
+
+ * @license GPL-3.0+
+ */
+
+
+/** Register custom metabox **/
+add_meta_box(
+ 'mgjp_mv_protection_metabox',
+ __( 'Media Vault Protection Settings', 'media-vault' ),
+ 'mgjp_mv_render_attachment_protection_metabox',
+ 'attachment',
+ 'side'
+);
+
+
+/**
+ * Enqueue metabox styles in head of attachment
+ * edit page
+ *
+ * @since 0.8.9
+ */
+function mgjp_mv_attachment_protection_metabox_styles_and_scripts() {
+
+ $screen = get_current_screen();
+ if ( 'attachment' !== $screen->id )
+ return;
+
+ // enqueue metabox styles
+ wp_enqueue_style( 'mgjp-mv-att-edit-css', plugins_url( 'css/mv-attachment-edit.css', __FILE__ ), 'all', null );
+
+}
+add_action( 'admin_enqueue_scripts', 'mgjp_mv_attachment_protection_metabox_styles_and_scripts' );
+
+
+/**
+ * Rendering function for the Media Vault attachment
+ * metabox
+ *
+ * @since 0.7.1
+ *
+ * @uses mgjp_mv_get_the_permissions()
+ * @uses mgjp_mv_is_protected()
+ * @param $post object WP_Post object of current attachment
+ */
+function mgjp_mv_render_attachment_protection_metabox( $post ) {
+
+
+ wp_nonce_field( 'mgjp_mv_protection_metabox', 'mgjp_mv_protection_metabox_nonce' );
+
+
+ $permission = get_post_meta( $post->ID, '_mgjp_mv_permission', true );
+
+ $permissions = mgjp_mv_get_the_permissions();
+
+ if ( empty( $permission ) || ! isset( $permissions[$permission] ) )
+ $permission = 'default';
+
+ $default = array(
+ 'default' => array(
+ 'select' => __( 'Use Default Setting', 'media-vault' )
+ )
+ );
+ $permissions = $default + $permissions; ?>
+
+
+
+
+ ID ) ); ?>>
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/mv-options-media-library.php b/mv-options-media-library.php
new file mode 100644
index 0000000..932931d
--- /dev/null
+++ b/mv-options-media-library.php
@@ -0,0 +1,294 @@
+
+ * @license GPL-3.0+
+ */
+
+
+
+/**
+ * Remove WP List Table row actions in the Media Library List Table
+ * if the attachment is protected and the user is not permitted to access it
+ *
+ * @since 0.7
+ *
+ * @uses mgjp_mv_check_user_permitted() returns true if user is permitted to access
+ * specified attachment
+ * @param $actions array Array of row actions available for specific attachment
+ * @param $post object WP_Post object of currently rendering attachment
+ * @return array Return row actions untouched if user permitted to access attachment
+ * @return array Empty array if no access permitted
+ */
+function mgjp_mv_modify_media_library_row_actions( $actions, $post ) {
+
+ // check if current user is permitted to access the post
+ if ( ! mgjp_mv_check_user_permitted( $post->ID ) )
+ return array( esc_html__( 'You do not have permission to access this attachment', 'media-vault' ) );
+
+ return $actions;
+}
+add_filter( 'media_row_actions', 'mgjp_mv_modify_media_library_row_actions', 10, 2 );
+
+
+/**
+ * Register Media Vault custom column to WP Media Library (wp-admin/upload.php)
+ * list table.
+ *
+ * @since 0.4
+ *
+ * @param array $columns array of columns for WP Media List Table
+ * @return array Array of columns, including custom column, for WP Media List Table
+ */
+function mgjp_mv_register_media_library_custom_column( $columns ) {
+
+ $columns['mgjp_mv_info'] = 'Media Vault';
+
+ return $columns;
+}
+add_filter( 'manage_upload_columns', 'mgjp_mv_register_media_library_custom_column' );
+
+
+/**
+ * Render function for Media Vault custom column in WP Media Library list table.
+ *
+ * @since 0.4
+ *
+ * @uses mgjp_mv_get_the_permissions()
+ * @param $column_name string name-id of current column
+ * @param $post_id int ID of post being evaluated
+ */
+function mgjp_mv_render_media_library_custom_column( $column_name, $post_id ) {
+
+ if ( 'mgjp_mv_info' != $column_name )
+ return;
+
+ if ( ! $permission = mgjp_mv_get_the_permission( $post_id ) )
+ return;
+
+ $permissions = mgjp_mv_get_the_permissions();
+
+ $permission = isset( $permissions[$permission] ) ? $permissions[$permission] : '';
+
+ $description = isset( $permission['description'] ) && ! empty( $permission['description'] ) ?
+ esc_html( $permission['description'] ) :
+ ''
+ . esc_html__( 'Undetermined! Permissions have been misconfigured for this attachment!', 'media-vault' )
+ . ''; ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ id ) {
+
+ if ( isset( $_REQUEST['mgjp-mv-protected'] ) && (int) $_REQUEST['mgjp-mv-protected'] ) {
+ $message = sprintf(
+ _n(
+ 'Media file is now protected.', //singular
+ '%s media files are now protected.', //plural
+ $_REQUEST['mgjp-mv-protected'],
+ 'media-vault'
+ ), number_format_i18n( $_REQUEST['mgjp-mv-protected'] )
+ );
+ echo '
+
+
\ No newline at end of file
diff --git a/mv-options-media-vault.php b/mv-options-media-vault.php
new file mode 100644
index 0000000..bfe3ed5
--- /dev/null
+++ b/mv-options-media-vault.php
@@ -0,0 +1,309 @@
+
+ * @license GPL-3.0+
+ */
+
+
+/** Register plugin settings **/
+register_setting( 'media', 'mgjp_mv_default_permission' );
+register_setting( 'media', 'mgjp_mv_options', 'mgjp_mv_options_sanitize' );
+register_setting( 'media', 'mgjp_mv_ir', 'mgjp_mv_ir_sanitize' );
+
+
+add_settings_section(
+ 'mgjp_mv_general_settings',
+ null,
+ 'mgjp_mv_render_general_settings_info_txt',
+ 'media'
+);
+
+
+add_settings_field(
+ 'default_permission',
+ __( 'Default Protected File Permissions', 'media-vault' ),
+ 'mgjp_mv_render_default_permission_field',
+ 'media',
+ 'mgjp_mv_general_settings',
+ array( 'label_for' => 'mgjp_mv_default_permission' )
+);
+
+add_settings_field(
+ 'default_upload_protection',
+ __( 'Default Upload Protection', 'media-vault' ),
+ 'mgjp_mv_render_checkbox_field',
+ 'media',
+ 'mgjp_mv_general_settings',
+ array(
+ 'label_for' => 'mgjp_mv_default_upload_protection',
+ 'option' => 'mgjp_mv_options',
+ 'option_id' => 'default_upload_protection',
+ 'value' => 'on',
+ 'desc' => __( 'Set media file upload protection to be enabled by default when uploading new files through the Add New Media page in the WordPress Admin.', 'media-vault' )
+ )
+);
+
+add_settings_field(
+ 'place_holder_img',
+ __( 'Image Placeholder', 'media-vault' ),
+ 'mgjp_mv_render_place_holder_img_field',
+ 'media',
+ 'mgjp_mv_general_settings'
+);
+
+
+/**
+ * Sanitization function for mgjp_mv_option settings
+ *
+ * @since 0.8
+ *
+ * @param $input array of options from settings page
+ * @return array sanitized array of mgjp_mv_options
+ */
+function mgjp_mv_options_sanitize( $input ) {
+
+ $options = get_option( 'mgjp_mv_options' );
+
+ $options['default_upload_protection'] = isset( $input['default_upload_protection'] ) ? 'on' : 'off';
+
+ return $options;
+}
+
+
+/**
+ * Sanitization function for mgjp_mv_ir settings
+ *
+ * @since 0.8
+ *
+ * @param $input array of options from settings page
+ * @return array sanitized array of mgjp_mv_ir options
+ */
+function mgjp_mv_ir_sanitize( $input ) {
+
+ $options = get_option( 'mgjp_mv_ir' );
+
+ $options['is_on'] = isset( $input['is_on'] ) ? ! ! $input['is_on'] : false;
+
+ if ( isset( $input['id'] ) && wp_attachment_is_image( absint( $input['id'] ) ) )
+ $options['id'] = absint( $input['id'] );
+ else
+ add_settings_error(
+ 'mgjp_mv_ir',
+ 'invalid-attachment-id',
+ __( 'The Media Vault placeholder image ID must be the ID of an existing image attachment in your media library. Please select a different Media Vault placeholder image.', 'media-vault' )
+ );
+
+ if ( isset( $input['default'] ) && wp_attachment_is_image( absint( $input['default'] ) ) )
+ $options['default'] = absint( $input['default'] );
+
+ return $options;
+}
+
+
+/**
+ * Render the General Settings info txt
+ *
+ * @since 0.4
+ */
+function mgjp_mv_render_general_settings_info_txt() {
+
+ echo '
Media Vault
';
+ echo '
';
+ esc_html_e( 'Media Vault is a plugin that allows you to protect media files in your uploads folder.', 'media-vault' );
+ echo ' ';
+ esc_html_e( 'Here you can set options for:', 'media-vault' );
+ echo '
+
+
\ No newline at end of file
diff --git a/readme.txt b/readme.txt
new file mode 100644
index 0000000..ccb57a0
--- /dev/null
+++ b/readme.txt
@@ -0,0 +1,188 @@
+=== Media Vault ===
+Contributors: Max GJP
+Donate Link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=6KFT65LQXEHFQ
+Tags: media, security, protection, attachments, downloads, download links, powerful, shortcode, flexible, simple, uploads, images, multisite, files, links, private, documents
+Requires at least: 3.5.0
+Tested up to: 3.8.1
+Stable tag: 0.8.12
+License: GPLv3 or later
+License URI: http://www.gnu.org/licenses/gpl-3.0.html
+
+Protect attachment files from direct access using powerful and flexible restrictions. Offer safe download links for any file in your uploads folder.
+
+== Description ==
+
+= Protected Attachment Files =
+
+Media Vault cordons off a section of your WordPress uploads folder and secures it, protecting all files within by passing requests for them through a *powerful, flexible and completely customizable* set of permission checks.
+
+After activating the plugin, to protect attachment files with Media Vault you can:
+
+* use the *Media Uploader admin page* to upload new protected attachments,
+* use the *Media Vault metabox* to toggle file protection on the 'Edit Media' admin page,
+* use the the *Media Vault Protection Settings* fields in the new Media Modal, or,
+* using *bulk actions* in your Media Library page, you can change file protection on multiple pre-existing attachments at once.
+
+By default the only permission check that the plugin does on media files is that the user requesting them be logged in. You can change this *default* behavior from the 'Media Settings' page in the 'Settings' menu of the WordPress Admin. You can also change the restrictions set on attachments on an individual basis by means of either the Media Vault metabox on the 'Edit Media' page or the Media Vault Protection Settings fields in the new Media Modal.
+
+You can also write your own custom restrictions using the `mgjp_mv_add_permission()` function. See [this support question](http://wordpress.org/support/topic/restrict-only-for-subscribers?replies=5) for more details.
+
+= Safe Download Links =
+
+Creating a cross-browser compatible download link for a file is a harder task than might be expected. Media Vault handles this for you, and it does so while preserving all the file security features discussed earlier like blocking downloads to people who should not have access to the file.
+
+The download links are available through a simple shortcode that you can use in your post/page editor screen:
+
+ [mv_dl_links ids="1,2,3"]
+
+where 'ids' are the comma separated list of attachment ids you would like to make available for download in the list.
+
+
+*Note:* Plugin comes with styles ready for WordPress 3.8+!
+
+*Note:* **Now supports WordPress MultiSite!**
+
+== Installation ==
+
+= Install Through your Blog's Admin =
+*This sometimes does not to work on `localhost`, so if you're running your site off your own computer it's simpler to use the second method.*
+
+1. Go to the 'Plugins' menu in WordPress and select 'Add New'.
+1. Type 'Media Vault' in the Search Box and press the 'Search' button.
+1. When you find 'Media Vault', click 'Install Now' and after reading it, click 'ok' on the little alert that pops up.
+1. When the plugin finishes installing, simply click 'Activate Now'.
+
+= Downloading from WordPress.org =
+
+1. Clicking the big 'Download' button on the right on this page (wordpress.org/plugins/media-vault/) will download the plugin's `zip` folder (`mediavault.zip`).
+1. Upload this `zip` folder to your server; to the `/wp-content/plugins/` directory of the site you wish to install the plugin on.
+1. Extract the contents of the `zip`. Once it is done you can delete the `mediavault.zip` file if you wish.
+1. Activate the plugin through the 'Plugins' menu in WordPress.
+
+
+Once you have Media Vault activated and fully enabled don't forget to go and check out the plugin's settings on the 'Media Settings' page under the admin 'Settings' menu.
+
+== Frequently Asked Questions ==
+
+= How do I toggle File Protection on an existing Attachment? =
+
+You have two options. If you only want to toggle File Protection on **a single attachment**, you can do it directly from the attachment's Edit page. In the 'Media Vault Settings' metabox in the right column, you can toggle protection by clicking the button that will either say 'Add to Protected' or 'Remove from Protected'. Remember to click 'Update' to save the changes you have made.
+
+If you want to toggle File Protection on **multiple attachments**, the plugin comes with two bulk actions that can be performed in the Media Library page in the WordPress Admin. On the Media Library page select the attachment or attachments you would like to manipulate by ticking the box next to their title. Then from the 'bulk options' dropdown select either the 'Add to Protected' or 'Remove from Protected' option and click the 'Apply' button next to the dropdown.
+
+You can verify that the action took effect by looking at the Media Vault column in the Media Library list table. It will display when an attachment's files are protected as well as the permissions set on the particular attachment.
+
+= Can files uploaded from the front-end be automatically protected? =
+
+Yes they can, see [this support question](http://wordpress.org/support/topic/default-upload-protection-from-front-end?replies=5) for more details!
+
+= How are unprotected files handled? How does this plugin work? =
+
+This question was recently asked and answered in [this support thread](https://wordpress.org/support/topic/how-the-unprotected-files-are-handeled?replies=3), check it out!
+
+== Screenshots ==
+
+1. The WordPress Media Upload page with Media Vault file protection activated.
+2. An example of the access denied prompt produced by a custom file access restriction implemented very simply using Media Vault.
+3. The WordPress Media Upload page with Media Vault file protection activated (in WP mp6 & WP 3.8+)
+
+== Changelog ==
+
+= 0.8.12 =
+fixed bug in `mv-file-handler.php` causing php Notice and corrupted files. Big thanks to user [ikivanov](http://profiles.wordpress.org/ikivanov) for pointing it out and providing the solution!
+
+= 0.8.11 =
+
+* fixed bug in `mv-metaboxes.php` causing php Notice. Thank you user [ikivanov](http://profiles.wordpress.org/ikivanov) for pointing it out!
+* fixed bug in `mv-metaboxes.php` causing metabox stylesheet not to be served
+
+= 0.8.10 =
+Fixed typo causing php error in `mv-extra-activation-steps.php`. Thank you user [wwn2013](http://profiles.wordpress.org/wwn2013) for pointing it out!
+
+= 0.8.9 =
+
+* Added Attachment Edit fields to the new Media Modal to make it easier to manage which files are protected with Media Vault and what permissions are set on each protected file.
+* Fixed visual bug with IE8 and the general sibling selector not showing permissions in the Media Vault Metabox on the attachment edit admin page.
+* Organized minified js code into seperate folder
+
+= 0.8.8 =
+fixed bug in `mv-file-handler.php` that allowed files to be viewed in the protected folder when 'Save uploads in year/month folders' was *not* selected. Thanks to [WayneHarris](http://profiles.wordpress.org/wayneharris) for pointing the issue out.
+
+= 0.8.7 =
+added a body class to the WP admin to let Media Vault know to use the new 3.8+ styles
+
+= 0.8.6 =
+fixed code that required php 5.4 and above, to be compatible with older versions of php
+
+= 0.8.5 =
+
+* Now the plugin is not fully enabled if the rewrite rules are detected to not be fully functioning as required
+* Added flag to indicate Media Vault can **only** be network activated on WordPress Multisite installs
+* Added return to homepage link in standard access denied message on protected media
+* Added Media Vault Activation/Deactivation Helper (MVADH) to support setups where Media Vault cannot automatically configure all components it needs to function, particularly the rewrite rules. Currently, MVADH supports single & multisite WordPress installs on Apache + mod_rewrite. Support for more server technologies coming soon. *MVADH not supporting a particular server technology **does not** mean Media Vault cannot work with that technology*, just that you may need to figure some of how to make the rewrite rules work by yourself.
+* Added **much** better support for WP multisite: better activation support, better deactivation support, better uninstallation support, better rewrite rule support, better file-handling support, better plugin update support.
+* Added MVADH rewrite rule support for ugly permalink setups
+* Made some performance tweaks & minor bugfixing
+
+= 0.8 =
+
+* added functionality to allow a place-holder image to replace a requested protected image.
+* refactored permission resolving functions to be more thorough and efficient.
+* modified `mgjp_mv_admin_check_user_permitted()` function to handle non admin checking and renamed it to `mgjp_mv_check_user_permitted()` to reflect this.
+* added plugin update handling class to manage per update required changes fluidly.
+* created an `uninstall.php` file and moved all settings removal actions there so that settings are now saved when a user only deactivates and does not remove the plugin.
+* added a link to the Media Vault settings to the Plugins page.
+* fixed bug with the Media Vault metabox not being able to set the default permission on the attachment.
+* fixed bug with the `mgjp_mv_get_the_permission()` function returning the wrong permission.
+
+= 0.7.1 =
+The Metabox - added a Media Vault metabox to the attachment editor screen to manage protection meta + bugfixing on the bulk actions script
+
+= 0.7 =
+*Minor remastering of permission checking code to address protected attachment access from within the WordPress backend. Highly recommended to immediately update.*
+
+* Rewrote default permissions to return rather than using `wp_die` directly. They now MUST either return `true` upon determining the current user is permitted to access a particular attachment; or if access is denied: `false` or a [`WP_Error`](http://codex.wordpress.org/Class_Reference/WP_Error) object with an error message included.
+* Added `mgjp_mv_admin_check_user_permitted()` function to use permission functions to change access to attachments while within the WP Admin.
+* Hooked into the 'user_has_cap' and 'media_row_actions' filters to restrict what users could see and manipulate in the backend for the specific attachments they did not have the permission to access.
+* Rewrote the custom permission checking function handling section of the file-handling script `mv-file-handler.php` to accommodate the changes to the way custom permission functions now return values.
+
+= 0.6 =
+Initial Release.
+
+== Upgrade Notice ==
+
+= 0.8.12 =
+fixed bug in `mv-file-handler.php` causing php Notice and corrupted files. Big thanks to user [ikivanov](http://profiles.wordpress.org/ikivanov) for pointing it out and providing the solution!
+
+= 0.8.11 =
+fixed bug in `mv-metaboxes.php` causing php Notice. Thank you user [ikivanov](http://profiles.wordpress.org/ikivanov) for pointing it out!
+
+= 0.8.10 =
+fixed typo causing php error in `mv-extra-activation-steps.php`. Thank you user [wwn2013](http://profiles.wordpress.org/wwn2013) for pointing it out!
+
+= 0.8.9 =
+Added Attachment Edit Fields to the new Media Modal and fixed visual bug with IE8
+
+= 0.8.8 =
+fixed bug in `mv-file-handler.php` that allowed files to be viewed in the protected folder when 'Save uploads in year/month folders' was *not* selected. Thanks to [WayneHarris](http://profiles.wordpress.org/wayneharris) for pointing the issue out.
+
+= 0.8.7 =
+added a body class to the WP admin to let Media Vault know to use the new 3.8+ styles
+
+= 0.8.6 =
+fixed code that required php 5.4 and above, to be compatible with older versions of php
+
+= 0.8.5 =
+The WPMU update - more organized code, now 90% more optimized to run fine both on single-site installs as well as multisite installs.
+
+= 0.8 =
+The Update update - good amount of bugfixing, and streamlining of code. Added a class to handle fluid plugin updates and some functions to allow for image placeholders to appear in the place of restricted images.
+
+= 0.7.1 =
+The Metabox - added a Media Vault metabox to the attachment editor screen to manage protection meta + bugfixing
+
+= 0.7 =
+Version 0.7 includes minor remastering of the permission checking code to address protected attachment access from within the WordPress backend. It is strongly recommended that you upgrade from version 0.6.
+
+= 0.6 =
+This is the original release version.
\ No newline at end of file
diff --git a/uninstall.php b/uninstall.php
new file mode 100644
index 0000000..d4b5cf5
--- /dev/null
+++ b/uninstall.php
@@ -0,0 +1,81 @@
+
+ * @license GPL-3.0+
+ */
+
+
+/** Make sure this file is not being called directly **/
+if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) || ! current_user_can( 'delete_plugins' ) ) {
+ header( 'Status: 403 Forbidden' );
+ header( 'HTTP/1.1 403 Forbidden' );
+ exit();
+}
+
+
+
+/**
+ * Media Vault internal Uninstall function for a single
+ * blog install or for each blog site
+ * in network activation mode
+ *
+ * @since 0.8.5
+ */
+function _mgjp_mv_uninstall_local( $blog_id = 0 ) {
+
+ // Delete the default Media Vault placeholder image if it
+ // still exists
+ $ir['default'] = get_option( 'mgjp_mv_ir' );
+ if ( $ir['default'] && wp_attachment_is_image( $ir['default'] ) )
+ wp_delete_attachment( $ir['default'], true );
+
+ // Delete all Media Vault local options from the local options table
+ delete_option( 'mgjp_mv_version' );
+ delete_option( 'mgjp_mv_default_permission' );
+ delete_option( 'mgjp_mv_options' );
+ delete_option( 'mgjp_mv_ir' );
+
+ // Delete all Media Vault attachment metadata from the local postmeta table
+ delete_post_meta_by_key( '_mgjp_mv_permission' );
+ delete_post_meta_by_key( 'mgjp_mv_meta' );
+}
+
+
+
+// Flush rewrite rules to remove all Media Vault rewrite rules from
+// the site's .htaccess file
+remove_filter( 'mod_rewrite_rules', 'mgjp_mv_add_plugin_rewrite_rules' );
+flush_rewrite_rules();
+
+
+// Delete all Media Vault network-wide options from the options table
+delete_site_option( 'mgjp_mv_version' );
+delete_site_option( 'mgjp_mv_enabled' );
+delete_site_option( 'mgjp_mv_deactivation' );
+
+
+if ( ! is_multisite() ) {
+
+ // run the uninstall function for the single site
+ _mgjp_mv_uninstall_local();
+
+} else if ( ! wp_is_large_network() ) {
+ global $wpdb;
+
+ $blog_ids = $wpdb->get_col( "SELECT `blog_id` FROM `$wpdb->blogs`" );
+
+ // run the uninstall function for each site in the network
+ foreach ( $blog_ids as $blog_id ) {
+
+ switch_to_blog( $blog_id );
+ _mgjp_mv_uninstall_local( $blog_id );
+ restore_current_blog();
+
+ }
+}
\ No newline at end of file