7

I need to run some code as soon as new images get uploaded in WordPress 3.5 uploader. Here is the code of wp-includes/js/media-views.js (line 529-540)

    uploading: function( attachment ) {
        var content = this.frame.content;

        // If the uploader was selected, navigate to the browser.
        if ( 'upload' === content.mode() ) 
            this.frame.content.mode('browse');

        // If we're in a workflow that supports multiple attachments,
        // automatically select any uploading attachments.
        if ( this.get('multiple') )
            this.get('selection').add( attachment );
    },

I added alert('New image uploaded!') at the bottom of this uploading function, and the browser alert 'New image uploaded!' when new image was uploaded. However I don't want to hack the core of WordPress, so I'm wondering if there is a way that I can write some code in my theme that can do the same thing? Sorry for my English. Thank you for you attention guys!

NoBugs
  • 9,310
  • 13
  • 80
  • 146
Alvin
  • 125
  • 2
  • 8

5 Answers5

11

This line of wp-plupload.js shows that the uploader queue will reset on complete. So you can do this:

wp.Uploader.queue.on('reset', function() { 
    alert('Upload Complete!');
});

I've tested it and it works on WP 3.5 sites.

So, here is the full version including support for both the regular uploader on "Upload New Media" Page and the new plupload uploader on "Insert Media" Dialog.

Create a javascript file named: wp-admin-extender.js and save it under your /custom/js/ folder or whatever within your template directory.

// Hack for "Upload New Media" Page (old uploader)

// Overriding the uploadSuccess function:
if (typeof uploadSuccess !== 'undefined') {
    // First backup the function into a new variable.
    var uploadSuccess_original = uploadSuccess;
    // The original uploadSuccess function with has two arguments: fileObj, serverData
    // So we globally declare and override the function with two arguments (argument names shouldn't matter)
    uploadSuccess = function(fileObj, serverData) 
    {
        // Fire the original procedure with the same arguments
        uploadSuccess_original(fileObj, serverData);
        // Execute whatever you want here:
        alert('Upload Complete!');
    }
}

// Hack for "Insert Media" Dialog (new plupload uploader)

// Hooking on the uploader queue (on reset):
if (typeof wp.Uploader !== 'undefined' && typeof wp.Uploader.queue !== 'undefined') {
    wp.Uploader.queue.on('reset', function() { 
        alert('Upload Complete!');
    });
}

And finally; add this into your theme's functions.php to get this functionality in WP Admin:

//You can also use other techniques to add/register the script for WP Admin.
function extend_admin_js() {
    wp_enqueue_script('wp-admin-extender.js', get_template_directory_uri().'/custom/js/wp-admin-extender.js', array('media-upload', 'swfupload', 'plupload'), false, true);
}
add_action('admin_enqueue_scripts', 'extend_admin_js');

This might not be the legitimate solution but it's a workaround at least.

Onur Yıldırım
  • 32,327
  • 12
  • 84
  • 98
  • Nice. I'm not sure reset is the correct event, you could try `on('all',function(e){console.log(e)})` to see what works best for each situation. This workaround is for ALL on the page, I was looking for adding action to a custom `wp.media` uploader, but this may actually work, turning this on and off on `wp.media`'s open and close events. – NoBugs Jan 25 '13 at 15:19
  • `on('all', fucntion(){...})` will be fired whenever an attachment/file is selected/added for uploading. So 'reset' is the best way to go I believe. And sure it works. The point is that the queue will only reset when upload is complete. – Onur Yıldırım Jan 25 '13 at 15:45
  • Thanks for the help - to clarify, when I said this is for all on the page, I meant that your code should fire for every uploader on the page. What if we want to only do this to one custom `wp.media` window? – NoBugs Jan 26 '13 at 01:33
0

Answer by Onur Yıldırım is suggesting hooking to the completion of all uploads. But according to your question, you need to hook to each successful upload. Which you can do by extending wp.Uploader.prototype. For proper instructions for jQuery follow the link to stackexchange: https://wordpress.stackexchange.com/a/131295

I've tested, it really allows you to hook to "success" response (and others, including init, error, added, progress, complete), which symbolises the plupload "FileUploaded" self-fired event for each file individually, getting the async-upload.php json string.

Community
  • 1
  • 1
-1

In Javascript, this may help:

wp.media.view.Attachments.prototype.on('ready',function(){console.log('your code here');});

There may also be an action in the php code that could work, I noticed there's echo apply_filters("async_upload_{$type}", $id); at the end of async-upload.php.

NoBugs
  • 9,310
  • 13
  • 80
  • 146
  • Thanks for that. But it runs every time you open up the media library, not just right after new image is uploaded. – Alvin Jan 12 '13 at 08:17
-1

Maybe you could hook in to the add_attachement action?

function do_my_attachment_manipulation($attachment_ID)
{          
    $attachment = get_attached_file($attachment_ID); // Gets path to attachment
    // Javascript alert:
    ?>
         <script>
               alert('Media uploaded!');
         </script>
    <?php

}

add_action("add_attachment", 'do_my_attachment_manipulation');
billerby
  • 1,977
  • 12
  • 22
  • How would you send Javascript to the browser in this action? – NoBugs Jan 24 '13 at 15:24
  • Code breaks the upload process: ***`An error occurred in the upload. Please try again later.`*** – brasofilo Jan 24 '13 at 15:55
  • Well, I tested it on my 3.5 installation and it worked for me. – billerby Jan 24 '13 at 15:58
  • How would you know which mode the uploader dialog is in, or even which wp.media uploader is calling it? I think the right way to do this would be a Backbone.js hook, if there is such hook. – NoBugs Jan 24 '13 at 16:01
-1

Олег, thanks a lot for the link https://wordpress.stackexchange.com/a/131295.

This is a great solution that really works!

This is how I used this solutions for myself:

$.extend(wp.Uploader.prototype,{
    success: function(file_attachment){
        console.log(file_attachment);
        if(wp.media.frame.content.get() !== null){
            setTimeout(function(){
                wp.media.frame.content.get().collection.props.set({ignore: (+ new Date())});
            },100);
        }
    }
});
Al Foиce ѫ
  • 4,195
  • 12
  • 39
  • 49