I’ve set up an options page for my CPT that contains the drag'n'drop upload area (just like Media → Add New). Basicly, I’ve copied all the relevant stuff from wp-admin/media-new.php and it works like charming.
This is the code of my options page:
/**
* Callback for the submenu page
*/
function syk_bulk_import_callback() {
// Taken from media-new.php
if ( ! current_user_can( 'upload_files' ) ) {
wp_die( __( 'Sorry, you are not allowed to upload files.' ) );
}
wp_enqueue_script( 'plupload-handlers' );
$post_id = 0;
if ( isset( $_REQUEST['post_id'] ) ) {
$post_id = absint( $_REQUEST['post_id'] );
if ( ! get_post( $post_id ) || ! current_user_can( 'edit_post', $post_id ) ) {
$post_id = 0;
}
}
if ( $_POST ) {
if ( isset( $_POST['html-upload'] ) && ! empty( $_FILES ) ) {
check_admin_referer( 'media-form' );
// Upload File button was clicked.
$upload_id = media_handle_upload( 'async-upload', $post_id );
if ( is_wp_error( $upload_id ) ) {
wp_die( $upload_id );
}
}
wp_redirect( admin_url( 'edit.php?post_type=symbol&page=syk-bulk-import' ) );
exit;
}
$form_class = 'media-upload-form type-form validate';
if ( get_user_setting( 'uploader' ) || isset( $_GET['browser-uploader'] ) ) {
$form_class .= ' html-uploader';
}
?>
<div class="wrap">
<h1>Massenimport</h1>
<div id="poststuff">
<div id="post-body" class="metabox-holder columns-1">
<div class="postbox-container">
<div class="postbox">
<div class="postbox-header">
<h2>Upload files</h2>
</div>
<div class="inside">
<form enctype="multipart/form-data" method="post" class="<?php echo esc_attr( $form_class ); ?>" id="file-form">
<?php media_upload_form(); ?>
<script type="text/javascript">
var post_id = <?php echo absint( $post_id ); ?>, shortform = 3;
</script>
<input type="hidden" name="post_id" id="post_id" value="<?php echo absint( $post_id ); ?>" />
<?php wp_nonce_field( 'media-form' ); ?>
<div id="media-items" class="hide-if-no-js"></div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<?php
}
But I need these files to go to a custom folder within wp-content/uploads. For images uploaded through a single cusom post’s edit screen I switch the upload dir using the wp_handle_upload_prefilter
hook:
// Upload directory switch for Symbole
add_filter( 'wp_handle_upload_prefilter', 'syk_uldir_switch_pre' );
function syk_uldir_switch_pre( $file ) {
add_filter( 'upload_dir', 'syk_uldir_switch' );
return $file;
}
add_filter( 'wp_handle_upload', 'syk_uldir_switch_post' );
function syk_uldir_switch_post( $file ) {
remove_filter( 'upload_dir', 'syk_uldir_switch' );
return $file;
}
function syk_uldir_switch( $upload_dir ) {
$is_symbol = false;
// Check if upload is from custom post type edit screen
if ( isset( $_REQUEST['post_id'] ) ) {
$post_id = $_REQUEST['post_id'];
if ( get_post_type( $post_id ) == 'symbol' )
$is_symbol = true;
if ( is_object( get_post( $post_id ) ) && get_post_type( get_post( $post_id )->post_parent ) == 'symbol' )
$is_symbol = true;
}
// Change upload dir for post type 'symbol'
if ( $is_symbol ) {
$upload_dir['subdir'] = '/symbole';
$upload_dir['path'] = $upload_dir['basedir'].$upload_dir['subdir'];
$upload_dir['url'] = $upload_dir['baseurl'].$upload_dir['subdir'];
}
return $upload_dir;
}
But this won’t work for uploads coming from my CPT options screen. Can I somehow ‘detect’ where the upload comes from in my hook callback? Or can I add something in the options page telling WordPress where to upload those files?
Right now I’m not quite sure which is the right place to achieve this. Any ideas?
dl-file.php
isn't too different in concept from thems-file.php
system WordPress has. If you used that system then the folder the files are in would be irrelevant and you could use a post meta flag to control which files require a login or not. There are other methods too, but it's important that your question is self contained. Even if you didn't change the code you need to mention it so people can reproduce