Plupload Intergration in una meta-box?


32

So che plupload sarà il nuovo motore di upload per WordPress 3.3 ma mi chiedevo se ci fosse ancora documentazione su come si integra con WordPress.

Il mio in particolare come raccogliere una risposta dall'oggetto plUpload jQuery una volta che ha caricato il supporto desiderato e come si utilizza la stessa funzionalità in una meta-box per creare una galleria?

Qualcuno ci ha già giocato?


Grazie per la generosità, anche se ci sono buone possibilità che una risposta non arriverà fino a quando WordPress 3.3 non avrà un rilascio ufficiale
Manny Fleurmond,

3
C'è anche una buona possibilità che lo darò un'occhiata questo fine settimana :-) Sto usando 3.3 da mesi ormai, e ho bisogno di scrivere questa cosa esatta prima delle prime cadute RC ...
EAMann

Ecco un link al plugin jQuery utilizzato dal nuovo uploader, plupload ( plupload.com ). Ho un'idea di come la implementano ma non riesco a capire come la nuova implementazione riceva le risposte quando un file viene caricato con successo.
Manny Fleurmond,

Risposte:


18

Il mio in particolare come raccogliere una risposta dall'oggetto plUpload jQuery una volta che ha caricato il supporto desiderato e come si utilizza la stessa funzionalità in una meta-box per creare una galleria?

C'è un file specifico che gestisce questa funzionalità: /wp-includes/js/plupload/handlers.dev.js. Questo file contiene tutti gli hook e i trigger che collegano Plupload (il sistema multi-file di trascinamento / rilascio di terze parti) all'autore del caricamento.

Potresti voler esaminare due eventi: "FileUploaded" e "Upload Complete"

FileUploaded

Ricorda, il nuovo uploader è in grado di caricare più file contemporaneamente. Quindi, se c'è qualcosa che vuoi fare dopo che ogni file nella coda è stato caricato, userai jQuery per associare questo evento.

WordPress, ad esempio, lega quanto segue:

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

La uploadSuccessfunzione qui gestisce le miniature delle immagini, recupera i meta allegati dal server e associa i pulsanti di modifica / eliminazione all'oggetto giusto.

Caricamento completato

L'evento sarà UploadComplete fuoco dopo tutto nella coda è uploading finito. Se si desidera eseguire un'operazione di pulizia generale al termine dell'intero download, questo è ciò che si desidera associare.

WordPress, ad esempio, lega quanto segue:

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

La uploadCompletefunzione qui abilita semplicemente il pulsante "Inserisci galleria" sulla pagina.

Sfortunatamente ...

... non sembra esserci un modo per legarci a questi eventi. L' uploaderoggetto esiste all'interno di una chiusura nel handlers.jsfile e Plupload stesso non ha un modo per fare riferimento a istanze esistenti. Non puoi usare un semplice selettore jQuery per annusarlo e aggiungere un evento personalizzato ... quindi siamo sfortunati lì.

Da un lato, è possibile utilizzare questi eventi personalizzati a piacimento nei propri sistemi. Basta girare la tua versione del handlers.jsfile con i tuoi eventi e puoi fare quello che vuoi. Ma per l'uploader esistente, sei bloccato con l'API esistente.

Tieni presente che il nuovo Pluploader chiama gli stessi metodi contemporaneamente al vecchio uploader Flash. Quindi la mia ipotesi migliore è che eventuali hack o integrazioni esistenti che hai dovrebbero continuare a funzionare.

Testare tale presupposto

Ho un plug-in che utilizza l'uploader esistente per caricare file allegati e visualizzare l'URL in un meta campo personalizzato. Funzionava come per magia con il vecchio uploader, quindi l'ho acceso in WP 3.3 per vedere se funzionava anche con il nuovo uploader.

E lo fa!

Quindi, se ti stai già integrando con l'uploader multimediale, il tuo sistema dovrebbe comunque funzionare con il nuovo sistema senza alcuna modifica.


22

(questo è solo un esempio pratico basato sulla risposta di 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;
});

Ci sono più eventi di plupload che puoi usare, controlla la sua documentazione ....


Ho provato questo codice così com'è e finora non fa nulla. L'immagine sembra caricarsi ma non so dove e non ricevo risposta dalla console
Manny Fleurmond,

1
Ok, ho riscontrato il problema: per qualche motivo $ _FILES ['async-upload'] che hai inviato a wp_handle_upload non sembra passare un check in detta funzione. Se passi array ('test_form' => false) come secondo argomento in wp_handle_upload, carica il file senza problemi. Ci sono anche altre parentesi nella chiamata a add_meta_box. Ho aggiunto delle modifiche alla tua risposta che dovrebbero farlo funzionare.
Manny Fleurmond,

Come nota di implementazione - può impostare un'azione su upload-attachmentcui attivare il wp_ajax_upload_attachment()gestore nativo e con alcune modifiche non è necessario del tutto un gestore di caricamento personalizzato, ma solo le parti del modulo e dello script.
Rarst

13

Ecco un'espansione della risposta di @One Trick Pony. Questo, oltre a caricare il file nel modo corretto, salverà anche detto file come allegato:

<?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;
});
?>

1
Pensa che qui ci sia un piccolo errore: l'ultimo parametro della chiamata wp_insert_attachment dovrebbe essere $ status ['file'] anziché $ status ['url']. Abbastanza sicuro che deve essere il percorso locale.
MathSmath,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.