問題描述

我知道 plupload 將是 WordPress 3.3 的新上傳引擎,但我想知道是否有任何檔案如何與 WordPress 整合。

我已經具體如何收集 plUpload jQuery 物件的響應,一旦它上傳了所需的媒體,以及如何在元框中使用相同的功能建立一個相簿?

有人玩過嗎?

最佳解決方案

My specifically how to collect a response from the plUpload jQuery object once it has uploaded the media that you want and how one would use the same functionality in a meta box to create a gallery?

有一個特定的檔案來處理這個功能:/wp-includes/js/plupload/handlers.dev.js 。該檔案包含將 Plupload(third-party 拖放 multi-file 系統) 繫結到上傳器的所有掛接和觸發器。

您可能需要看兩個事件:”FileUploaded” 和”Upload Complete”

FileUploaded

請記住,新上傳者可以一次上傳多個檔案。所以如果在佇列中的每個檔案上傳之後都要做某些事情,你將使用 jQuery 來繫結到這個事件。

例如,WordPress 繫結以下內容:

uploader.bind('FileUploaded', function(up, file, response) {
    uploadSuccess(file, response.response);
});'

uploadSuccess 功能在這裡處理影像縮圖,從伺服器獲取附件後設資料,並將編輯/刪除按鈕繫結到正確的物件。

UploadComplete

UploadComplete 事件將在佇列中的所有內容完成上傳後觸發。如果要在整個下載完成後啟動一般的清理操作,這就是您要繫結的內容。

例如,WordPress 繫結以下內容:

uploader.bind('UploadComplete', function(up, files) {
    uploadComplete();
});

uploadComplete 功能只能啟用頁面上的”Insert gallery” 按鈕。

不幸的是…

… 似乎沒有辦法繫結這些事件。 uploader 物件存在於 handlers.js 檔案中的閉包中,Plupload 本身沒有方法來引用現有例項。你不能使用一個簡單的 jQuery 選擇器來嗅出它並新增一個自定義事件… 所以我們沒有運氣。

一方面,您可以在自己的系統中使用這些自定義事件 at-will 。只需將您自己的 handlers.js 檔案的自己的版本與您自己的事件相結合,就可以做任何你想要的工作。但是,對於現有的上傳者,您將不得不使用現有的 API 。

請記住,新的 Pluploader 在與舊 Flash 上​​傳者相同的時間呼叫相同的方法。所以我最好的猜測是,任何現有的駭客或整合你應該繼續工作。

測試這個假設

 I have a plugin 使用現有的上傳者上傳檔案附件,並在自定義元欄位中顯示該 URL 。它像舊的上傳器一樣像魔術一樣工作,所以我在 WP 3.3 中啟動了它,看看它是否與新的上傳者一起使用。

而且它!

因此,如果您已經與媒體上傳器整合,您的系統仍然可以使用新系統,而無需任何更改。

次佳解決方案

(這只是一個基於 EAMann 答案的例項)

// include js
add_action('admin_enqueue_scripts', function($page){

  // check if this your page here with the upload form!
  if(($page !== 'post.php') || (get_post_type() !== 'post'))
    return;

  wp_enqueue_script('plupload-all');
});



// this adds a simple metabox with the upload form on the edit-post page
add_action('add_meta_boxes', function(){
  add_meta_box('gallery_photos', __('Photos'), 'upload_meta_box', 'post', 'normal', 'high');

});                                               



// so here's the actual uploader
// most of the code comes from media.php and handlers.js
function upload_meta_box(){ ?>
   <div id="plupload-upload-ui" class="hide-if-no-js">
     <div id="drag-drop-area">
       <div class="drag-drop-inside">
        <p class="drag-drop-info"><?php _e('Drop files here'); ?></p>
        <p><?php _ex('or', 'Uploader: Drop files here - or - Select Files'); ?></p>
        <p class="drag-drop-buttons"><input id="plupload-browse-button" type="button" value="<?php esc_attr_e('Select Files'); ?>" class="button" /></p>
      </div>
     </div>
  </div>

  <?php

  $plupload_init = array(
    'runtimes'            => 'html5,silverlight,flash,html4',
    'browse_button'       => 'plupload-browse-button',
    'container'           => 'plupload-upload-ui',
    'drop_element'        => 'drag-drop-area',
    'file_data_name'      => 'async-upload',            
    'multiple_queues'     => true,
    'max_file_size'       => wp_max_upload_size().'b',
    'url'                 => admin_url('admin-ajax.php'),
    'flash_swf_url'       => includes_url('js/plupload/plupload.flash.swf'),
    'silverlight_xap_url' => includes_url('js/plupload/plupload.silverlight.xap'),
    'filters'             => array(array('title' => __('Allowed Files'), 'extensions' => '*')),
    'multipart'           => true,
    'urlstream_upload'    => true,

    // additional post data to send to our ajax hook
    'multipart_params'    => array(
      '_ajax_nonce' => wp_create_nonce('photo-upload'),
      'action'      => 'photo_gallery_upload',            // the ajax action name
    ),
  );

  // we should probably not apply this filter, plugins may expect wp's media uploader...
  $plupload_init = apply_filters('plupload_init', $plupload_init); ?>

  <script type="text/javascript">

    jQuery(document).ready(function($){

      // create the uploader and pass the config from above
      var uploader = new plupload.Uploader(<?php echo json_encode($plupload_init); ?>);

      // checks if browser supports drag and drop upload, makes some css adjustments if necessary
      uploader.bind('Init', function(up){
        var uploaddiv = $('#plupload-upload-ui');

        if(up.features.dragdrop){
          uploaddiv.addClass('drag-drop');
            $('#drag-drop-area')
              .bind('dragover.wp-uploader', function(){ uploaddiv.addClass('drag-over'); })
              .bind('dragleave.wp-uploader, drop.wp-uploader', function(){ uploaddiv.removeClass('drag-over'); });

        }else{
          uploaddiv.removeClass('drag-drop');
          $('#drag-drop-area').unbind('.wp-uploader');
        }
      });

      uploader.init();

      // a file was added in the queue
      uploader.bind('FilesAdded', function(up, files){
        var hundredmb = 100 * 1024 * 1024, max = parseInt(up.settings.max_file_size, 10);

        plupload.each(files, function(file){
          if (max > hundredmb && file.size > hundredmb && up.runtime != 'html5'){
            // file size error?

          }else{

            // a file was added, you may want to update your DOM here...
            console.log(file);
          }
        });

        up.refresh();
        up.start();
      });

      // a file was uploaded 
      uploader.bind('FileUploaded', function(up, file, response) {

        // this is your ajax response, update the DOM with it or something...
        console.log(response);

      });

    });   

  </script>
  <?php
}


// handle uploaded file here
add_action('wp_ajax_photo_gallery_upload', function(){

  check_ajax_referer('photo-upload');

  // you can use WP's wp_handle_upload() function:
  $status = wp_handle_upload($_FILES['async-upload'], array('test_form'=>true, 'action' => 'photo_gallery_upload'));

  // and output the results or something...
  echo 'Uploaded to: '.$status['url'];

  exit;
});

有更多的 plupload 事件可以使用,檢視它的 documentation ….

第三種解決方案

這是一個擴充套件到 @One Trick Pony 的答案。此外,除了將檔案上傳到正確的檔案外,還會將該檔案另存為附件:

<?php
// include js
add_action('admin_enqueue_scripts', function($page){

  // check if this your page here with the upload form!
  if(($page !== 'post.php') || (get_post_type() !== 'post'))
    return;

  wp_enqueue_script('plupload-all');
});



// this adds a simple metabox with the upload form on the edit-post page
add_action('add_meta_boxes', function(){
  add_meta_box('gallery_photos', __('Photos'), 'upload_meta_box', 'post', 'normal', 'high');

});                                               



// so here's the actual uploader
// most of the code comes from media.php and handlers.js
function upload_meta_box(){ ?>
   <div id="plupload-upload-ui" class="hide-if-no-js">
     <div id="drag-drop-area">
       <div class="drag-drop-inside">
        <p class="drag-drop-info"><?php _e('Drop files here'); ?></p>
        <p><?php _ex('or', 'Uploader: Drop files here - or - Select Files'); ?></p>
        <p class="drag-drop-buttons"><input id="plupload-browse-button" type="button" value="<?php esc_attr_e('Select Files'); ?>" class="button" /></p>
      </div>
     </div>
  </div>

  <?php

  $plupload_init = array(
    'runtimes'            => 'html5,silverlight,flash,html4',
    'browse_button'       => 'plupload-browse-button',
    'container'           => 'plupload-upload-ui',
    'drop_element'        => 'drag-drop-area',
    'file_data_name'      => 'async-upload',            
    'multiple_queues'     => true,
    'max_file_size'       => wp_max_upload_size().'b',
    'url'                 => admin_url('admin-ajax.php'),
    'flash_swf_url'       => includes_url('js/plupload/plupload.flash.swf'),
    'silverlight_xap_url' => includes_url('js/plupload/plupload.silverlight.xap'),
    'filters'             => array(array('title' => __('Allowed Files'), 'extensions' => '*')),
    'multipart'           => true,
    'urlstream_upload'    => true,

    // additional post data to send to our ajax hook
    'multipart_params'    => array(
      '_ajax_nonce' => wp_create_nonce('photo-upload'),
      'action'      => 'photo_gallery_upload',            // the ajax action name
    ),
  );

  // we should probably not apply this filter, plugins may expect wp's media uploader...
  $plupload_init = apply_filters('plupload_init', $plupload_init); ?>

  <script type="text/javascript">

    jQuery(document).ready(function($){

      // create the uploader and pass the config from above
      var uploader = new plupload.Uploader(<?php echo json_encode($plupload_init); ?>);

      // checks if browser supports drag and drop upload, makes some css adjustments if necessary
      uploader.bind('Init', function(up){
        var uploaddiv = $('#plupload-upload-ui');

        if(up.features.dragdrop){
          uploaddiv.addClass('drag-drop');
            $('#drag-drop-area')
              .bind('dragover.wp-uploader', function(){ uploaddiv.addClass('drag-over'); })
              .bind('dragleave.wp-uploader, drop.wp-uploader', function(){ uploaddiv.removeClass('drag-over'); });

        }else{
          uploaddiv.removeClass('drag-drop');
          $('#drag-drop-area').unbind('.wp-uploader');
        }
      });

      uploader.init();

      // a file was added in the queue
      uploader.bind('FilesAdded', function(up, files){
        var hundredmb = 100 * 1024 * 1024, max = parseInt(up.settings.max_file_size, 10);

        plupload.each(files, function(file){
          if (max > hundredmb && file.size > hundredmb && up.runtime != 'html5'){
            // file size error?

          }else{

            // a file was added, you may want to update your DOM here...
            console.log(file);
          }
        });

        up.refresh();
        up.start();
      });

      // a file was uploaded 
      uploader.bind('FileUploaded', function(up, file, response) {

        // this is your ajax response, update the DOM with it or something...
        console.log(response);

      });

    });   

  </script>
  <?php
}


// handle uploaded file here
add_action('wp_ajax_photo_gallery_upload', function(){

  check_ajax_referer('photo-upload');

  // you can use WP's wp_handle_upload() function:
  $file = $_FILES['async-upload'];
  $status = wp_handle_upload($file, array('test_form'=>true, 'action' => 'photo_gallery_upload'));

  // and output the results or something...
  echo 'Uploaded to: '.$status['url'];

  //Adds file as attachment to WordPress
  echo "n Attachment ID: " .wp_insert_attachment( array(
     'post_mime_type' => $status['type'],
     'post_title' => preg_replace('/.[^.]+$/', '', basename($file['name'])),
     'post_content' => '',
     'post_status' => 'inherit'
  ), $status['file']);

  exit;
});
?>

第四種方案

我一點點擴充套件了一個小怪物的答案。我建立了一個具有以下功能的上傳器:

  • 它可以在同一頁面中多次放置。
  • 它顯示上傳進度。
  • 它顯示使用者已上傳的影像 (和現有資料) 的縮圖。
  • 它允許使用者透過拖動縮圖來更改影像的順序。

http://www.krishnakantsharma.com/2012/01/image-uploads-on-wordpress-admin-screens-using-jquery-and-new-plupload/中檢視

參考文獻

注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。