使选项页面上的内联上载程序(Plupload)上载到特定文件夹

时间:2021-07-07 作者:mischnu

我已经为我的CPT设置了一个选项页面,其中包含拖放上传区域(就像媒体一样→ 添加新)。基本上,我已经从wp admin/media new复制了所有相关内容。php和它的工作方式很迷人。

This is what my options page looks like

这是“我的选项”页面的代码:

/**
* 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
}
但我需要这些文件go to a custom folder within wp-content/uploads. 对于通过单个cusom post的编辑屏幕上传的图像,我使用wp_handle_upload_prefilter 挂钩:

// 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;
}
但这不适用于从我的CPT选项屏幕上传的内容。我是否可以在挂钩回调中“检测”上传来自何处?或者我可以在选项页面中添加一些内容,告诉WordPress在哪里上传这些文件?

现在我不太确定哪一个地方是实现这一目标的正确地方。有什么想法吗?

1 个回复
最合适的回答,由SO网友:mischnu 整理而成

我终于找到了一个适合我的解决方案,我想与大家分享。这或多或少是EHerman发布的here, 我只是做了一些小改动,使代码适应我的情况。基本的想法是找出上传来自我的管理页面。这是通过检查我的管理页面名称的推荐人来完成的if ( strpos( $referrer, \'page=syk-bulk-import\' ) !== false ...:

add_filter( \'admin_init\', \'syk_bulk_import_admin\', 999 );
function syk_bulk_import_admin() {
  global $pagenow;
  $referrer = isset( $_SERVER[\'HTTP_REFERER\'] ) ? $_SERVER[\'HTTP_REFERER\'] : \'\';
  if ( strpos( $referrer, \'page=syk-bulk-import\' ) !== false && ( \'async-upload.php\' == $pagenow || \'media-upload.php\' == $pagenow ) ) {
    add_filter( \'upload_dir\', \'syk_admin_uldir_switch\' );
  }
}

function syk_admin_uldir_switch( $upload_dir ) {
  $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;
}
引入PHP 8str_contains() 这可能比strpos() 陈述