Skip to content

Instantly share code, notes, and snippets.

@rmpel
Last active March 21, 2024 08:16
Show Gist options
  • Save rmpel/f5e8e17757992df631c78a15a1a6ddd6 to your computer and use it in GitHub Desktop.
Save rmpel/f5e8e17757992df631c78a15a1a6ddd6 to your computer and use it in GitHub Desktop.
The definitive way to add more filetypes to WordPress Media.
<?php
/**
* Filters that assist in uploading additional filetypes.
*
* @package Your_Package
* @subpackage Your_Package/Includes
*/
namespace Your_Package\Includes;
/**
* Central spot to manage the uploads.
*/
class Uploads {
/**
* Constructor.
*/
public function __construct() {
add_filter( 'upload_mimes', [ $this, 'filter_upload_mimes' ] );
add_filter( 'site_option_upload_filetypes', [ $this, 'filter_site_option_upload_filetypes' ] );
add_filter( 'wp_check_filetype_and_ext', [ $this, 'determine_proper_filetype_and_ext' ], 9, 5 );
}
/**
* Array of allowed mime types keyed by the file extension.
* The first in the list is used when any of the mimes are found for that extension.
*
* @var array[]
*/
static $mimes = [
'geojson' => [ 'application/json', 'text/json' ],
'json' => [ 'application/json', 'text/json' ],
'kml' => [ 'application/vnd.google-earth.kml+xml', 'application/xml', 'text/xml' ],
'csv' => [ 'text/csv', 'text/plain', 'application/csv', 'text/comma-separated-values' ],
];
/**
* Filter: upload_mimes; add additional filetypes to the allowed upload filetypes.
*
* @param string[] $mimes Array of allowed mime types keyed by the file extension.
*
* @return mixed
*/
public function filter_upload_mimes( $mimes ) {
$additional_mimes = self::$mimes;
// Reduce the array to only the first mime type.
$additional_mimes = array_map( 'reset', $additional_mimes );
// Merge the additional mimes with the existing mimes.
$mimes = array_merge( $mimes, $additional_mimes );
return $mimes;
}
/**
* Filter: site_option_upload_filetypes; add additional filetypes to the allowed upload filetypes.
*
* @param string $option_value Space separated list of allowed filetypes (extensions).
*
* @return string
*/
public function filter_site_option_upload_filetypes( $option_value ) {
$option_value = explode( ' ', $option_value );
$option_value = array_merge( $option_value, array_keys( self::$mimes ) );
$option_value = array_unique( $option_value );
$option_value = implode( ' ', $option_value );
return $option_value;
}
/**
* Filter: wp_check_filetype_and_ext; determine the proper filetype based on extension and a list of allowed mime types.
* WordPress only allows one filetype per extension, this filter implementation allows us to support multiple filetypes per extension.
*
* @param array $file_data An array of data for a single file, as determined by WordPress during upload.
* @param string $file Unused in this implementation. The path to the uploaded file.
* @param string $filename The name of the uploaded file.
* @param string[] $mimes Unused in this implementation.
* @param string $real_mime The mime-type as determined by PHP's Fileinfo extension.
*
* @return mixed
*/
public function determine_proper_filetype_and_ext( $file_data, $file, $filename, $mimes, $real_mime ) {
$file_ext = pathinfo( $filename, PATHINFO_EXTENSION );
foreach ( self::$mimes as $ext => $mime ) {
if ( $ext === $file_ext && in_array( $real_mime, self::$mimes[ $ext ], true ) ) {
$file_data['ext'] = $ext;
$file_data['type'] = reset( self::$mimes[ $ext ] );
}
}
return $file_data;
}
}
new Uploads();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment