Plupload Intergration dalam meta-box?

32

Saya tahu bahwa plupload akan menjadi mesin unggah baru untuk WordPress 3.3 tetapi saya bertanya-tanya apakah ada dokumentasi tentang bagaimana ia terintegrasi dengan WordPress.

Khusus saya bagaimana mengumpulkan respons dari objek jQuery plUpload setelah ia mengunggah media yang Anda inginkan dan bagaimana orang akan menggunakan fungsi yang sama dalam kotak meta untuk membuat galeri?

Adakah yang bermain-main dengannya?

Manny Fleurmond
sumber
Terima kasih atas hadiahnya, meskipun ada peluang bagus jawaban tidak akan datang sampai WordPress 3.3 memiliki rilis resmi
Manny Fleurmond
3
Ada juga kesempatan baik saya akan melihatnya akhir pekan ini :-) Saya sudah menggunakan 3,3 selama berbulan-bulan sekarang, dan perlu menulis hal ini tepat sebelum RC pertama turun ...
EAMann
Berikut ini tautan ke plugin jQuery yang digunakan pengunggah baru, plupload ( plupload.com ). Saya memiliki inti tentang bagaimana mereka mengimplementasikannya tetapi tidak dapat mengetahui bagaimana implementasi baru menerima tanggapan ketika sebuah file berhasil diunggah.
Manny Fleurmond

Jawaban:

18

Khusus saya bagaimana mengumpulkan respons dari objek jQuery plUpload setelah ia mengunggah media yang Anda inginkan dan bagaimana orang akan menggunakan fungsi yang sama dalam kotak meta untuk membuat galeri?

Ada file tertentu yang menangani fungsi ini: /wp-includes/js/plupload/handlers.dev.js. File ini berisi semua kait dan pemicu yang mengikat Plupload (sistem multi-file drag / drop pihak ketiga) ke pengunggah.

Ada dua peristiwa yang mungkin ingin Anda lihat: "FileUploaded" dan "Upload Complete"

FileUploaded

Ingat, pengunggah baru mampu mengunggah banyak file sekaligus. Jadi, jika ada sesuatu yang ingin Anda lakukan setelah setiap file dalam antrian diunggah, Anda akan menggunakan jQuery untuk mengikat ke acara ini.

WordPress, misalnya, mengikat yang berikut ini:

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

The uploadSuccessFungsi disini menangani thumbnail image, mengambil lampiran meta dari server, dan mengikat mengedit / tombol hapus untuk objek yang tepat.

UploadComplete

Acara UploadComplete akan diaktifkan setelah semua yang ada dalam antrian selesai diunggah. Jika Anda ingin menjalankan operasi pembersihan umum setelah seluruh unduhan selesai, inilah yang ingin Anda ikat.

WordPress, misalnya, mengikat yang berikut ini:

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

The uploadCompleteFungsi sini hanya memungkinkan "Insert galeri" tombol pada halaman.

Sayangnya ...

... sepertinya tidak ada cara bagi kita untuk mengikat peristiwa ini. The uploaderobjek ada dalam penutupan di handlers.jsfile, dan Plupload sendiri tidak memiliki cara untuk referensi contoh yang ada. Anda tidak dapat menggunakan pemilih jQuery sederhana untuk mengendusnya dan menambahkan acara khusus ... jadi kami kurang beruntung di sana.

Di satu sisi, Anda dapat menggunakan acara khusus ini sesuka hati di sistem Anda sendiri. Putar saja versi handlers.jsfile Anda sendiri dengan acara Anda sendiri dan Anda dapat melakukan apa pun yang Anda inginkan. Tetapi untuk pengunggah yang ada, Anda terjebak dengan API yang ada.

Perlu diingat, bahwa Pluploader baru memanggil metode yang sama pada waktu yang sama seperti yang dilakukan pengunggah Flash lama. Jadi tebakan terbaik saya adalah setiap retas atau integrasi yang ada harus terus bekerja.

Menguji asumsi itu

Saya memiliki plugin yang menggunakan pengunggah yang ada untuk mengunggah lampiran file dan menampilkan URL di bidang meta khusus. Ini bekerja seperti sulap dengan pengunggah lama, jadi saya menyalakannya di WP 3.3 untuk melihat apakah itu bekerja dengan pengunggah baru juga.

Dan itu benar!

Jadi, jika Anda sudah berintegrasi dengan pengunggah media, sistem Anda harus tetap bekerja dengan sistem baru tanpa perubahan apa pun.

EAMann
sumber
22

(Ini hanya contoh praktis berdasarkan jawaban 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;
});

Ada lebih banyak acara plupload yang dapat Anda gunakan, lihat dokumentasinya ....

onetrickpony
sumber
Saya sudah mencoba kode ini apa adanya dan sejauh ini tidak melakukan apa-apa. Gambar tampaknya mengunggah tetapi saya tidak tahu di mana dan saya tidak mendapat tanggapan dari konsol
Manny Fleurmond
1
Oke, temukan masalahnya: karena suatu alasan $ _FILES ['async-unggah'] yang Anda kirim ke wp_handle_upload tampaknya tidak lulus pemeriksaan pada fungsi tersebut. Jika Anda meneruskan array ('test_form' => false) sebagai argumen kedua ke wp_handle_upload, itu mengunggah file tanpa masalah. Ada juga tanda kurung tambahan dalam panggilan ke add_meta_box. Saya menambahkan suntingan ke jawaban Anda yang seharusnya membuatnya berfungsi.
Manny Fleurmond
Sebagai catatan implementasi - dapat mengatur tindakan upload-attachmentyang akan memicu wp_ajax_upload_attachment()penangan asli dan dengan beberapa penyesuaian tidak perlu penangan pengunggahan kustom sama sekali, hanya bagian formulir dan skrip.
Paling lambat
13

Ini adalah perluasan jawaban @One Trick Pony. Ini, selain mengunggah file ke kanan, juga akan menyimpan file tersebut sebagai lampiran:

<?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;
});
?>
Manny Fleurmond
sumber
1
Pikirkan ada kesalahan kecil di sini - param terakhir dari panggilan wp_insert_attachment haruslah $ status ['file'] daripada $ status ['url']. Cukup yakin itu harus menjadi jalur lokal.
MathSmath