2013/11/19

Including additional data with the file in SimpleUploads

A question that many people have asked for a long time is how to include additional info (for example the state of a new checkbox in a dialog or some Anti-CSRF tokens) when a file is uploaded in CKEditor with the "Quick upload" option available in some of the dialogs.
Most of the time no one answered, or the answer involved modifying the core files of CKEditor. In any case, there isn't a simple solution available.
WIth SimpleUploads 4 that's a very simple task, just set a listener for the "simpleuploads.startUpload" event that it's fired and you can the modify the target URL if you want to change the Query parameters, or include an "extraFields" object to the event data and the properties of such object will be sent as additional fields in the POST request.
Let's see this with an example, for me it's the best way to understand things.
First, suppose that you have modified the image dialog to include a custom checkbox, and that in your page you have defined an object that provides some tokens that should be used on each upload to verify that it hasn't been tampered. That's not part of the exercise so I'm not gonna explain that here, the problem is how to add that data to the uploads, not the system that you're using.
You just need to write a listener for the editor, and you can even create a listener for any editor in the page.
// Let's add this to every editor on the page. You can instead add it only to a specific editor.
CKEDITOR.on('instanceReady', function(e) {
    // the real listener
    e.editor.on( 'simpleuploads.startUpload' , function(ev) {

// write code here...

    });
});
the inner event will be fired on each upload that it's started, we just have to check if it's fired while we are on the image dialog to add the checkbox, and always add the additional POST fields.
Remember that this is just a basic sample, you can decide to send all the info as POST, or include more fields, check other functions, this is just a sample about how to modify the URL and query String and include extra POST fields:
  var data = ev.data;
  // the context property provides info about where the upload is being used
  // var context = data.context;

  // Check if there's a dialog open:
  var dialog = CKEDITOR.dialog.getCurrent();
  if (dialog)
  {
   var name = dialog.getName();
   if (name=="image")
   {
    // Get the value of our new checkbox and if it's checked add it as a parameter to the URL
    var value = dialog.getValueOf("Upload", "chkCustom");
    if (value)
     ev.data.url += "&checked=on";
   }
  }

  // add CSRF tokens
  var extraFields = {
   // These is sample code, the CKEDITOR.config.action, CKEDITOR.config.formID and Core objects
   // are items specific to a custom implementation of CKEditor.
   // Fill the extraFields object with whatever you might need.
   "Action" : CKEDITOR.config.action,
   "FormID" : CKEDITOR.config.formID
  };
  extraFields[ Core.Get("SessionName") ] = Core.Get("SessionID");

  ev.data.extraFields = extraFields;
All of the code is up and running in a new demo.
As you can see customizing the uploads in CKEditor now it's a very simple task and you have full control about what happens.

PS: Although I've said that those POST fields are fictional, in fact they are based on the setup used by OTRS 3.2.9. In order to integrate CKEditor they are using a custom build to modify the file uploads, but with this plugin such custom patches are no longer needed.

No comments: