Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

restricting file upload types #49

Open
wants to merge 23 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
d6cb9c7
[wip] Restricting file upload types
kkarpieszuk Mar 23, 2022
be912e3
Merge remote-tracking branch 'origin/develop' into fut/35-restricting…
kkarpieszuk May 24, 2022
1a009b7
[fixup] works but it needs to enable native types during registration
kkarpieszuk May 26, 2022
a4d04b7
[fixup] auto enable native file formats
kkarpieszuk May 26, 2022
408cbd7
[fixup] rephrazed description over table
kkarpieszuk May 26, 2022
3d44042
Merge remote-tracking branch 'origin/develop' into fut/35-restricting…
kkarpieszuk Jun 1, 2022
b89ff68
[fixup] added working version of the front end filtering
kkarpieszuk Jun 1, 2022
4912193
[fixup] moved inits to Plugin class
kkarpieszuk Jun 1, 2022
748c7a7
[fixup] phpdoc
kkarpieszuk Jun 1, 2022
e3ee0cf
[fixup] decoupled Allowed and Plugin class
kkarpieszuk Jun 21, 2022
e1ab53f
[fixup] performance fix for getting native types
kkarpieszuk Jun 21, 2022
cedfe75
[fixup] phpcs
kkarpieszuk Jun 21, 2022
5f566dc
[fixup] removed todo
kkarpieszuk Jun 21, 2022
4c14e87
[fixup] decoupled dispatcher
kkarpieszuk Jun 21, 2022
7ea8dbd
[fixup] decoupled Settings and Admin
kkarpieszuk Jun 21, 2022
9c68ffb
[fixup] added immediate native file type registration after installat…
kkarpieszuk Jun 23, 2022
d27e268
[fixup] fix native file types are disallowed by default and cannot be…
kkarpieszuk Jun 27, 2022
05e4b57
[fixup] applied suggested changes
kkarpieszuk Jun 27, 2022
d599f47
[fixup] plugin instantiation fix
kkarpieszuk Jun 28, 2022
c03506e
[fixup] new StoredTypes helper class
kkarpieszuk Jun 29, 2022
f635358
[fixup] cleaned Dispatcher
kkarpieszuk Jun 29, 2022
de17721
[fixup] renamed hooks
kkarpieszuk Jun 29, 2022
dd68c81
[fixup] parameter default value as array
kkarpieszuk Jun 29, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion assets/css/style.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion assets/css/style.css.map

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions assets/css/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ $border-color: #ccd0d4;

.file-upload-types-table {
padding-right: 30px;
width: 100%;

.before-table {
display: flex;
Expand Down
6 changes: 3 additions & 3 deletions file-upload-types.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* Domain Path: /languages/
*/

use FileUploadTypes\Plugin as PluginAlias;
use FileUploadTypes\Plugin;

// Exit if accessed directly.
defined( 'ABSPATH' ) || exit;
Expand Down Expand Up @@ -135,11 +135,11 @@ function file_upload_types_wp_notice() {
*
* @since 1.0.0
*
* @return PluginAlias
* @return Plugin
*/
function file_upload_types() {

$instance = PluginAlias::get_instance();
$instance = Plugin::get_instance();

$instance->init();

Expand Down
131 changes: 131 additions & 0 deletions src/Allowed.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
<?php

namespace FileUploadTypes;

/**
* Logic related to filtering wp_get_mime_types results, mostly on front end.
*
* @since {VERSION}
*/
class Allowed {

/**
* Enabled types.
*
* @since {VERSION}
*
* @var array
*/
private $enabled_types = [];

/**
* Register hooks.
*
* @since {VERSION}
*
* @return void
*/
public function hooks() {

add_filter( 'upload_mimes', [ $this, 'allowed_types' ] );
}

/**
* File types allowed to upload.
*
* @link https://developer.wordpress.org/reference/functions/wp_get_mime_types/
*
* @since {VERSION}
*
* @param array $mime_types List of all allowed in WordPress mime types.
*
* @return array
*/
public function allowed_types( $mime_types ) {

foreach ( $mime_types as $extensions => $mime ) {
$extensions_array = explode( '|', $extensions );
$mime_types = count( $extensions_array ) === 1
? $this->remove_single_extension( $extensions, $mime_types )
: $this->process_multiple_extensions( $extensions_array, $mime_types );
}

return $mime_types;
}

/**
* Maybe remove single extension.
*
* @since {VERSION}
*
* @param string $extension File extension.
* @param array $mime_types WordPress allowed types.
*
* @return array
*/
private function remove_single_extension( $extension, $mime_types ) {

if ( ! array_key_exists( $extension, $this->get_enabled_types() ) ) {
unset( $mime_types[ $extension ] );
}

return $mime_types;
}

/**
* Process each extension from pipeline separated extensions.
*
* If extension is not allowed, remove it from mime types.
*
* @since {VERSION}
*
* @param array $extensions Allowed extensions, exploded on | sign.
* @param array $mime_types WordPress allowed mime types.
*
* @return array Filtered WordPress allowed mime types.
*/
private function process_multiple_extensions( $extensions, $mime_types ) {

$concatenated_extensions = implode( '|', $extensions );
$mime = $mime_types[ $concatenated_extensions ];

unset( $mime_types[ $concatenated_extensions ] );

foreach ( $extensions as $index => $extension ) {
if ( ! array_key_exists( $extension, $this->get_enabled_types() ) ) {
unset( $extensions[ $index ] );
}
}
if ( ! empty( $extensions ) ) {
$mime_types[ implode( '|', $extensions ) ] = $mime;
}

return $mime_types;
}

/**
* Get stored FUT enabled types.
*
* @since {VERSION}
*
* @return array|string[]
*/
private function get_enabled_types() {

if ( ! $this->enabled_types ) {

$plugin = Plugin::get_instance();

// Only add first mime type to the allowed list. Aliases will be dynamically added when required.
$this->enabled_types = array_map(
static function( $enabled_types ) {

return sanitize_mime_type( ! is_array( $enabled_types ) ? $enabled_types : $enabled_types[0] );
},
$plugin->enabled_types()
);
}

return $this->enabled_types;
}
}
67 changes: 67 additions & 0 deletions src/Migrations/Dispatcher.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

namespace FileUploadTypes\Migrations;

/**
* Various logic dispatcher class.
*
* @since {VERSION}
*/
class Dispatcher {

/**
* Register hooks.
*
* @since {VERSION}
*/
public function hooks() {

add_action( 'init', [ $this, 'run' ] );
}

/**
* Run all migration logics.
*
* @since {VERSION}
*/
public function run() {

$already_run = get_option( 'file_upload_types_migrations_done', [] );
$option_changed = false;

foreach ( $this->get_migrations_list() as $name => $callback ) {

if ( ! isset( $already_run[ $name ] ) && is_callable( $callback ) && $callback() ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, add a blank line before if.

$already_run[ $name ] = 1;
$option_changed = true;
}
}

if ( $option_changed ) {
update_option( 'file_upload_types_migrations_done', $already_run );
}
}

/**
* Get available migrations.
*
* @since {VERSION}
*
* @return array[]
*/
private function get_migrations_list() {

// phpcs:disable WPForms.PHP.ValidateHooks.InvalidHookName
return [
/**
* Get callback method for add_native_file_upload_types migration.
*
* @since {VERSION}
*
* @param callable $callback Callback.
*/
'add_native_file_upload_types' => apply_filters( 'file_upload_types_migrations_dispatcher_add_native_file_upload_types_callback', null ),
];
// phpcs:enable WPForms.PHP.ValidateHooks.InvalidHookName
}
}
73 changes: 57 additions & 16 deletions src/Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

namespace FileUploadTypes;

use FileUploadTypes\Restrict\Native\Admin;
use FileUploadTypes\Migrations\Dispatcher;

/**
* Main Plugin Class.
*
Expand All @@ -18,6 +21,33 @@ final class Plugin {
*/
protected static $instance;

/**
* Allowed object reference.
*
* @since {VERSION}
*
* @var Allowed;
*/
private $allowed;

/**
* Admin object.
*
* @since {VERSION}
*
* @var Admin
*/
private $admin;

/**
* Dispatcher object.
*
* @since {VERSION}
*
* @var Dispatcher
*/
private $dispatcher;

/**
* Main Plugin Instance.
*
Expand All @@ -42,9 +72,29 @@ public static function get_instance() {
*/
public function init() {

$this->allowed = new Allowed();
$this->admin = new Admin( $this->allowed );
$this->dispatcher = new Dispatcher();

$this->admin->hooks();
$this->allowed->hooks();
$this->dispatcher->hooks();

$this->hooks();
}

/**
* Get WordPress allowed mime types.
*
* @since {VERSION}
*
* @return string[]
*/
public function get_native_types() {

return $this->admin->get_types();
}

/**
* Register hooks.
*
Expand All @@ -55,7 +105,6 @@ private function hooks() {
add_action( 'init', [ $this, 'load_plugin_textdomain' ] );
add_action( 'init', [ $this, 'register_admin_area' ] );
add_filter( 'plugin_action_links_' . plugin_basename( FILE_UPLOAD_TYPES_PLUGIN_FILE ), [ $this, 'plugin_action_links' ], 10, 4 );
add_filter( 'upload_mimes', [ $this, 'allowed_types' ] );
add_filter( 'wp_check_filetype_and_ext', [ $this, 'real_file_type' ], 999, 5 );
}

Expand Down Expand Up @@ -114,13 +163,11 @@ public function plugin_action_links( $actions, $plugin_file, $plugin_data, $cont
*/
public function enabled_types() {

$stored_types = get_option( 'file_upload_types', [] );
$enabled_types = isset( $stored_types['enabled'] ) ? (array) $stored_types['enabled'] : [];
$custom_types_raw = isset( $stored_types['custom'] ) ? (array) $stored_types['custom'] : [];
$available_types = fut_get_available_file_types();
$return_types = $this->add_available_types( $available_types, $enabled_types );
$stored_types = new StoredTypes();
$available_types = array_merge( fut_get_available_file_types(), fut_get_native_file_types() );
$return_types = $this->add_available_types( $available_types, $stored_types->enabled );

foreach ( $custom_types_raw as $type ) {
foreach ( $stored_types->custom as $type ) {

if ( empty( $type['ext'] ) || empty( $type['mime'] ) ) {
continue;
Expand Down Expand Up @@ -168,23 +215,17 @@ private function add_available_types( $available_types, $enabled_types ) {
* @link https://developer.wordpress.org/reference/functions/wp_get_mime_types/
*
* @since 1.0.0
* @deprecated {VERSION}
*
* @param array $mime_types List of all allowed in WordPress mime types.
*
* @return array
*/
public function allowed_types( $mime_types ) {

// Only add first mime type to the allowed list. Aliases will be dynamically added when required.
$enabled_types = array_map(
static function( $enabled_types ) {

return sanitize_mime_type( ! is_array( $enabled_types ) ? $enabled_types : $enabled_types[0] );
},
$this->enabled_types()
);
_deprecated_function( __METHOD__, '{VERSION}', '\FileUploadTypes\Allowed::allowed_types' );

return array_replace( $mime_types, $enabled_types );
return $this->allowed->allowed_types( $mime_types );
}

// phpcs:disable WPForms.PHP.HooksMethod.InvalidPlaceForAddingHooks
Expand Down
Loading