Intégration Plupload dans une méta-boîte?

32

Je sais que plupload sera le nouveau moteur de téléchargement pour WordPress 3.3, mais je me demandais s’il existait encore de la documentation sur la manière dont il s’intègre à WordPress.

Comment collecter une réponse à partir de l’ objet plUpload jQuery une fois qu’il a téléchargé le média souhaité et comment utiliser les mêmes fonctionnalités dans une méta-boîte pour créer une galerie?

Quelqu'un a-t-il déjà joué avec?

Manny Fleurmond
la source
Merci pour la prime, bien qu'il y ait de bonnes chances que la réponse ne soit pas donnée avant la sortie officielle de WordPress 3.3
Manny Fleurmond
3
Il y a aussi de bonnes chances que j'y jette un coup d'œil ce week-end :-) J'utilise la version 3.3 depuis des mois et j'ai besoin de l'écrire avant les premiers
lancements de
Voici un lien vers le plugin jQuery utilisé par le nouvel outil de téléchargement, plupload ( plupload.com ). J'ai l'essentiel de la façon dont ils l'implémentent, mais je ne peux pas dire comment la nouvelle implémentation reçoit les réponses lorsqu'un fichier est téléchargé avec succès.
Manny Fleurmond

Réponses:

18

Comment collecter une réponse à partir de l’objet plUpload jQuery une fois qu’il a téléchargé le média souhaité et comment utiliser les mêmes fonctionnalités dans une méta-boîte pour créer une galerie?

Il y a un fichier spécifique qui gère cette fonctionnalité: /wp-includes/js/plupload/handlers.dev.js. Ce fichier contient tous les points d'ancrage et les déclencheurs qui relient Plupload (le système de fichiers multiples glissé-déposé tiers) au programme de téléchargement.

Il y a deux événements que vous voudrez peut-être regarder: "FileUploaded" et "Upload Complete"

Fichier téléchargé

Rappelez-vous que le nouveau téléchargeur est capable de télécharger plusieurs fichiers à la fois. Ainsi, si vous souhaitez effectuer une opération après le téléchargement de chaque fichier de la file d'attente, vous utiliserez jQuery pour établir une liaison avec cet événement.

WordPress, par exemple, lie les éléments suivants:

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

La uploadSuccessfonction ici gère les vignettes d’image, récupère les méta de pièces jointes du serveur et lie les boutons de modification / suppression au bon objet.

Téléchargement complet

L'événement UploadComplete se déclenchera après tout le de la file d'attente est terminé. Si vous souhaitez déclencher une opération de nettoyage général une fois le téléchargement terminé, vous devez vous y reporter.

WordPress, par exemple, lie les éléments suivants:

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

La uploadCompletefonction active ici simplement le bouton "Insérer une galerie" sur la page.

Malheureusement ...

... il ne semble pas y avoir de moyen pour nous de nous lier à ces événements. L' uploaderobjet existe dans une fermeture du handlers.jsfichier et Plupload lui-même ne dispose pas d'un moyen de référencer des instances existantes. Vous ne pouvez pas utiliser un simple sélecteur jQuery pour le détecter et ajouter un événement personnalisé ... pour ne pas avoir de chance là-bas.

D'une part, vous pouvez utiliser ces événements personnalisés à volonté dans vos propres systèmes. Il suffit de lancer votre propre version duhandlers.js fichier avec vos propres événements et vous pouvez faire ce que vous voulez. Mais pour le programme de téléchargement existant, vous êtes coincé avec l'API existante.

N'oubliez pas que le nouveau Pluploader appelle les mêmes méthodes au même moment que l'ancien téléchargeur Flash. Donc, ma meilleure hypothèse est que toutes les intégrations ou intégrations existantes que vous avez devraient continuer à fonctionner.

Tester cette hypothèse

J'ai un plugin qui utilise le programme de téléchargement existant pour télécharger des pièces jointes et afficher l'URL dans un champ méta personnalisé. Cela fonctionnait comme par magie avec l'ancien téléchargeur. Je l'ai donc lancé dans le WP 3.3 pour voir si cela fonctionnait également avec le nouvel importateur.

Et ça le fait!

Par conséquent, si vous intégrez déjà le programme de téléchargement de média, votre système doit toujours fonctionner avec le nouveau système sans aucune modification.

EAMann
la source
22

(ceci est juste un exemple pratique basé sur la réponse d'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;
});

Il y a plus d'événements plupload que vous pouvez utiliser, consultez sa documentation ....

onetrickpony
la source
J'ai essayé ce code tel quel et jusqu'à présent, il ne fait rien. L'image semble avoir été téléchargée, mais je ne sais pas où et je n'ai pas de réponse de la console
Manny Fleurmond
1
Ok, a trouvé le problème: pour quelque raison que ce soit, le $ _FILES ['async-upload'] que vous avez envoyé à wp_handle_upload ne semble pas recevoir de contrôle de cette fonction. Si vous passez array ('test_form' => false) comme second argument dans wp_handle_upload, le fichier est téléchargé sans problème. Il y a aussi une parenthèse supplémentaire dans l'appel à add_meta_box. J'ai ajouté des modifications à votre réponse qui devraient le faire fonctionner.
Manny Fleurmond
En tant que note d'implémentation, vous pouvez définir une action upload-attachmentqui déclenchera un wp_ajax_upload_attachment()gestionnaire natif et, avec quelques ajustements, ne nécessite pas de gestionnaire de téléchargement personnalisé, mais uniquement les éléments de formulaire et de script.
Rarst
13

Voici une extension de la réponse de @One Trick Pony. Ceci, en plus de télécharger le fichier sur le bon, sauvegardera également ledit fichier en tant que pièce jointe:

<?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
la source
1
Pensez qu'il y a une petite erreur ici - le dernier paramètre de l'appel wp_insert_attachment devrait être $ status ['fichier'] plutôt que $ status ['url']. Je suis sûr que ça doit être le chemin local.
MathSmath