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'], '/' ) ) > 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.