最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

uploads - How to assign multiple file-mime-types to extension?

programmeradmin2浏览0评论

To allow extra file types for upload, we use:

add_filter('mime_types', 'my_mimes');
function my_mimes($all)
{
    $all['zip'] = 'application/zip';
    return $all;
}

But how to assign multiple file types to 1 extension? For example, zip extension might have application/zip mime and also application/x-zip (like, coming from 7zip). This way doesn't work:

$all['zip'] = ['application/zip', 'application/x-zip'] ;

To allow extra file types for upload, we use:

add_filter('mime_types', 'my_mimes');
function my_mimes($all)
{
    $all['zip'] = 'application/zip';
    return $all;
}

But how to assign multiple file types to 1 extension? For example, zip extension might have application/zip mime and also application/x-zip (like, coming from 7zip). This way doesn't work:

$all['zip'] = ['application/zip', 'application/x-zip'] ;
Share Improve this question edited Aug 29, 2019 at 9:16 T.Todua asked Dec 23, 2018 at 13:19 T.ToduaT.Todua 5,8609 gold badges52 silver badges79 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 10

Note the stricter mime type check since WP 5.0.1 where the file content and file extension must match. See e.g. this recent question on the vtt file type.

Secondary mime type for a given file extension

Here's a suggestion how to support a secondary mime type for a given file extension. Let's take .vtt as an example. The core assumes the mime type of text/vtt for that file extension, but the real mime type from finfo_file() can sometimes be text/plain. The finfo_file() seems to be somewhat buggy. We can add a support for it as a secondary mime type with:

/**
 * Support for 'text/plain' as the secondary mime type of .vtt files,
 * in addition to the default 'text/vtt' support.
 */
add_filter( 'wp_check_filetype_and_ext', 'wpse323750_secondary_mime', 99, 4 );    

function wpse323750_secondary_mime( $check, $file, $filename, $mimes ) {
    if ( empty( $check['ext'] ) && empty( $check['type'] ) ) {
        // Adjust to your needs!
        $secondary_mime = [ 'vtt' => 'text/plain' ];

        // Run another check, but only for our secondary mime and not on core mime types.
        remove_filter( 'wp_check_filetype_and_ext', 'wpse323750_secondary_mime', 99, 4 );
        $check = wp_check_filetype_and_ext( $file, $filename, $secondary_mime );
        add_filter( 'wp_check_filetype_and_ext', 'wpse323750_secondary_mime', 99, 4 );
    }
    return $check;
}

Here we use the wp_check_filetype_and_ext filter to see if the check failed. In that case we run wp_check_filetype_and_ext() again but now only on our secondary mime type, disabling our filter callback in the meanwhile to avoid an infinite loop.

Multiple mime types for a given file extension

If we need to support more than two mime types for the .vtt files, then we can expand the above snippet with:

/**
 * Demo: Support for 'text/foo' and 'text/bar' mime types of .vtt files,
 * in addition to the default 'text/vtt' support.
 */
add_filter( 'wp_check_filetype_and_ext', 'wpse323750_multi_mimes', 99, 4 );

function wpse323750_multi_mimes( $check, $file, $filename, $mimes ) {
    if ( empty( $check['ext'] ) && empty( $check['type'] ) ) {
        // Adjust to your needs!
        $multi_mimes = [ [ 'vtt' => 'text/foo' ], [ 'vtt' => 'text/bar' ] ];

        // Run new checks for our custom mime types and not on core mime types.
        foreach( $multi_mimes as $mime ) {
            remove_filter( 'wp_check_filetype_and_ext', 'wpse323750_multi_mimes', 99, 4 );
            $check = wp_check_filetype_and_ext( $file, $filename, $mime );
            add_filter( 'wp_check_filetype_and_ext', 'wpse323750_multi_mimes', 99, 4 );
            if ( ! empty( $check['ext'] ) ||  ! empty( $check['type'] ) ) {
                return $check;
            }
        }
    }
    return $check;
}

I hope you can test it further and adjust it to your needs.

A little improved birgire's answer. Had to add multiple mime types for svg, but because svg is forbidden by default, had to add dynamic filter to upload_mimes:

class Multiple_Mimes {

    public static function init() {
        add_filter( 'wp_check_filetype_and_ext', [self::class, 'add_multiple_mime_types'], 99, 3 );
    }


    public static function add_multiple_mime_types( $check, $file, $filename ) {
        if ( empty( $check['ext'] ) && empty( $check['type'] ) ) {
            foreach ( self::get_allowed_mime_types() as $mime ) {
                remove_filter( 'wp_check_filetype_and_ext', [ self::class, 'add_multiple_mime_types' ], 99 );
                $mime_filter = function($mimes) use ($mime) {
                    return array_merge($mimes, $mime);
                };

                add_filter('upload_mimes', $mime_filter, 99);
                $check = wp_check_filetype_and_ext( $file, $filename, $mime );
                remove_filter('upload_mimes', $mime_filter, 99);
                add_filter( 'wp_check_filetype_and_ext', [ self::class, 'add_multiple_mime_types' ], 99, 3 );
                if ( ! empty( $check['ext'] ) || ! empty( $check['type'] ) ) {
                    return $check;
                }
            }
        }

        return $check;
    }


    public static function get_allowed_mime_types(){
        return [
            [ 'svg' => 'image/svg' ],
            [ 'svg' => 'image/svg+xml' ],
        ];
    }

}

I had a similar problem to solve where .zip files were seen as application/zip by PHP but detected as application/x-zip-compressed.

My workaround was to add this new value with an invented key

'xzip' => '`application/x-zip-compressed';

See https://github/WordPress/gutenberg/issues/23510

See also two WordPress TRACs:

  • https://core.trac.wordpress/ticket/40175
  • https://core.trac.wordpress/ticket/46775
发布评论

评论列表(0)

  1. 暂无评论