Rendering the uploaded file in a wp.media object

I presume you’ve fixed this already but (in a blatant attempt to snaffle the bounty and) as mentioned in the comments there’s a simple fix, in your myplugin_meta_box_callback() function change the line

$mime_types      = array( 'application/pdf' );

to

$mime_types="application/pdf";

The library.type option to wp.media expects a string (which can be comma-separated with additional types) not an array.

This actually threw up a bug in the media.model.Attachments because if you look at where it was failing, the validator type() filter (line 997 in “media-models.js”)

        type: function( attachment ) {
            var type = this.props.get('type');
            return ! type || -1 !== type.indexOf( attachment.get('type') );
        },

then what this isn’t taking account of is that an attachment type like application/pdf is split into type and subtype by wp_prepare_attachment_for_js() in “media.php”, and this is only validating type, ie application (and validating in a pretty sloppy way too with no delimiters).

Anyway all that’s moot if you add the upload validator given by @Bainternet – here’s a variation of it:

add_action( 'admin_init', function () {
    add_filter( 'wp_handle_upload_prefilter', function ( $file ) {
        if ( empty( $_POST['allowed_mime_types'] ) || empty( $file['type'] ) ) {
            return $file;
        }
        $allowed_mime_types = explode( ',', $_POST['allowed_mime_types'] );
        if ( in_array( $file['type'], $allowed_mime_types ) ) {
            return $file;
        }
        // Cater for "group" allowed mime types eg "image", "audio" etc. to match
        // files of type "image/png", "audio/mp3" etc.
        if ( ( $slash_pos = strpos( $file['type'], "https://wordpress.stackexchange.com/" ) ) > 0 ) {
            if ( in_array( substr( $file['type'], 0, $slash_pos ), $allowed_mime_types ) ) {
                return $file;
            }
        }
        $file['error'] = __( 'Sorry, you cannot upload this file type for this field.' );
        return $file;
    } );

    add_filter( 'media_view_settings', function ( $settings, $post ) {
        $settings['mimeTypes']['application/pdf'] = __( 'All PDF items' );
        return $settings;
    }, 10, 2 );
} );

(The additional media_view_settings filter just changes the select filter text from “All media items” to “All PDF items”.)
You can then set the allowed_mime_types param (in the new way mentioned by @estepix) in your openModal() function directly after calling wp.media()

                this.modal = wp.media.frames.file_frame = wp.media(options);
                if (options.library && options.library.type && this.modal.uploader) {
                    this.modal.uploader.options.uploader.params.allowed_mime_types = options.library.type;
                }

and non-PDF files won’t be allowed to be uploaded.

Leave a Comment