I know that plupload is going to be the new upload engine for WordPress 3.3 but I was wondering if there is any documentation yet on how it integrates with WordPress.
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?
Has anyone played around with it, yet?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
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?
There’s a specific file that handles this functionality: /wp-includes/js/plupload/handlers.dev.js. This file contains all of the hooks and triggers that tie Plupload (the third-party drag/drop multi-file system) to the uploader.
There are two events you might want to look at: “FileUploaded” and “Upload Complete”
FileUploaded
Remember, the new uploader is capable of uploading multiple files at once. So if there’s something you want to do after each file in the queue is uploaded, you’ll use jQuery to bind to this event.
WordPress, for example, binds the following:
uploader.bind('FileUploaded', function(up, file, response) {
uploadSuccess(file, response.response);
});'
The uploadSuccess function here handles image thumbnails, fetches attachment meta from the server, and binds edit/delete buttons to the right object.
UploadComplete
The UploadComplete event will fire after everything in the queue is finished uploading. If you want to fire a general cleanup operation after the entire download is finished, this is what you’ll want to bind to.
WordPress, for example, binds the following:
uploader.bind('UploadComplete', function(up, files) {
uploadComplete();
});
The uploadComplete function here just enables the “Insert gallery” button on the page.
Unfortunately …
… there doesn’t seem to be a way for us to bind to these events. The uploader object exists within a closure in the handlers.js file, and Plupload itself doesn’t have a way to reference existing instances. You can’t use a simple jQuery selector to sniff it out and add a custom event … so we’re out of luck there.
On the one hand, you can use these custom events at-will in your own systems. Just spin up your own version of the handlers.js file with your own events and you can do whatever you want. But for the existing uploader, you’re stuck with the existing API.
Keep in mind, that the new Pluploader calls the same methods at the same times as the old Flash uploader did. So my best guess is that any existing hacks or integrations you have should continue to work.
Testing that assumption
I have a plugin that uses the existing uploader to upload file attachments and display the URL in a custom meta field. It worked like magic with the old uploader, so I fired it up in WP 3.3 to see if it worked with the new uploader as well.
And it does!
So if you’re already integrating with the media uploader, your system should still work with the new system without any changes.
Method 2
(this is just a practical example based on EAMann’s answer)
// 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;
});
There are more plupload events you can use, check out its documentation….
Method 3
Here is an expansion to @One Trick Pony’s answer. This, in addition to uploading the file to the proper, will also save said file as an attachment:
<?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;
});
?>
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0