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.

2013/11/18

Demo videos for the Google Maps plugin for CKEditor

I've realize that I haven't announced it here, but about a month ago I spent some time creating two videos showing most of the features available in the Google Maps plugin for CKEditor.

The idea behind the plugin is that although being able to play with the demo page and test the features by yourself, sometimes you might not be aware of all the available options, and despite my horrible pronunciation (I beg you pardon) i decided that it would be good to provide a video explaining the features available in the plugin.

Of course, creating such thorough explanation means that I found little issues, I used different browsers to test the features and record the video so in the end besides the videos I released a new version of the plugin with some improvements (and testing the dialogs was when I felt the need to improve the uploads in the CKEditor dialogs, it was a pity that some features like adding a KML file or a new icon couldn't been done by drag & drop from my computer)

The first video is available here:  Introduction to Google Maps plugin for CKEditor

It explain the main features of the two first tabs of the dialog, and how the map is rendered in the final page. Most of the options are just what you expect and you can see any change in the preview map of the dialog.

Some of the features that I added thanks to recording this video was the ability to start with the StreetView of a location or with a rotated map.

The second video is this one: Drawing shapes on Google Maps with CKEditor.

In order to record this video I finished an option that I've had in the works for some time but I never had the time to test it, drawing circles.

The video starts showing how to place markers, change the icon of the marker, how a simple CKEditor is embedded in the dialog to allow editing the popup that shows when you click on a marker, or how to insert a simple option so that the visitor can get driving directions from his location to that place.

Then it shows the other drawing options, lines, polygons and circles, all can be controlled to adjust the color, width, opacity; so you get the map that you want.

Please, keep the closed captions on and the volume low, but watch the videos and if you have some question about them or you think that I can explain something else that I've missed, then drop me a note.

2013/11/17

Finally, SimpleUploads 4 is here

After a long time working on this upgrade, I've reached the point where I think that it's better to release it and write all the documentation that I had in mind afterwards, so expect more updates about all the features in the following days.

Since quite a long time ago I felt that the name "ImagePaste" wasn't correct for a plugin that allows to also drop files and since version 3.0 offered two buttons to upload files or images with just two clicks and get them inserted into CKEditor.

So with along a new feature set, the main change (meaning the change that will cause more problems for existing users because instead of just replacing the files now you have to edit again your config file) is the rename of the old "imagepaste" to "simpleuploads"

That name tries to explain better what it does, it's not only about "images" and not only about "paste", it's a set of features to offer the users a way to "upload" files in a "simple" way.

The best way to check how it works is to test the demo.

Skipping the explanation about the existing features, the new ones are focused on the dialogs of CKEditor and improving the upload progress:

When you upload a file in the editor, now you get a progress indicator and the option to cancel the upload. The existing progress for images has been improved to also include the cancel option.

The plugin now integrates into the CKEditor dialogs, if it finds a "quickUpload" button it will be replaced with its own one to offer the same simple upload (click button, select a file and you're done instead of having to press the "upload to server"), as well as progress information, cancelation option and the full control on the upload (modify the upload URL, check file size, extension, automatica validation with a whitelist or blacklist...)

And besides modifying the QuickUpload button, the dialog itself now becomes a drop target, you can drop a file from your computer on those dialogs (even if there's only a browse server button is enough) and it will be uploaded and the url of the dialog filled with the new URL.

Another improvement in this version is the inclusion of optional parameters in the upload data, for example if you want to use some anti-CSRF token, modifying the QuickUpload system in CKEditor required some tricks, but now it's a piece of cake. Ditto if you want to add for example a checkbox to scale the image to a maximum, just before the upload begins there's an event where you can control many features.

I'll try to provide examples about how to customize CKEditor with this plugin so you can easily upload files and do whatever you want with them, so keep an eye on the blog because I'll try to write new posts explaining different ways to use the plugin. I've created now a main page here to provide a central point for all the information about SimpleUploads.

PS: currently I really dislike the comment system in Blogger because I don't get any notification when someone comments a post, so I might move to another platform if this bug persists. Meanwhile, have a little patience if I don't reply, it's usually better to send me a mail or direct message by + me.

2013/10/06

Cross domain file uploads in CKEditor

In version 3.4 of the SimpleUploads plugin I've added support to upload files across domains based on the CORS spec.

If you don't use multiple domains (one server for the uploaded files and another for the editing page) then this change shouldn't affect you. Otherwise you can enable this feature by modifying your uploader to send just two headers in response to an OPTIONS request.
Some simple PHP code:
if (isset($_SERVER["HTTP_ORIGIN"])) {
 // You must verify that the origin domain is on your white-list
 header('Access-Control-Allow-Origin: https://admin.example.com');
 header('Access-Control-Allow-Credentials: true');
}
if ($_SERVER['REQUEST_METHOD']=='OPTIONS')
 exit(0);
  • First: check if the browser has sent an Origin header. That means that it's a cross domain request. You can check that domain with the list of domains that you want to allow. The usual behavior is to send back a fixed origin header like
    header('Access-Control-Allow-Origin: https://admin.example.com');
  • Second: Send an Access-Control-Allow-Credentials header specifying that the browser is allowed to make a request that will use the credentials of the user at this domain. This means that if the user is logged in, the browser will send the cookies required to allow you check his/her identity.
  • Last: as the OPTIONS request doesn't require more data in the response you can stop any further processing here. After this first request the browser will upload the file and you must send back again the two Access-Control headers as shown in the sample code.
You must be careful if you want to allow this feature, after all it opens the possibility of another attack vector.
If you're hosting the files in the same physical server, you might be able to get the same functionality by modifying just the URL that it's returned after you upload a file and keeping all your code in the admin.example.com domain.

Updating some plugins

Today I've been working on some issues on plugins for CKEditor.

As I've stated previously, I don't like Github, but I'm forced to use it and when people uses things that they don't like it's obvious that things are slower than when they are happy.

I'm always afraid that if I try to do things I'll have to waste a lot of time recreating again the branch, it will spit out errors saying that it can't merge and that I have to use the command line. I've been using Beyond Compare for so long that merging things on the command line seems like an impossible task to me and I don't want to learn the github commands because that's not my daily job and even if I waste time to learn them for one task, by the time that I have to use them again I will have forgotten everything about them.

So if you see that "I'm ignoring" your patch, the reason might be simply that I don't have the time and energy to fight against Github.

The first patch was a simple one-liner by bfavors on the configuration helper plugin.

First of all, thank you.

But please, next time try to provide more info to quickly understand how I should test to check the bug, the browser, some simple code that shows how to load the editor. There are so many options that without more info my first thought is "Ok, now I have to guess out how to reproduce that bug!" :-(

If you provide such simple patch and also a simple testcase it's really easy to test that and verify that it was broken and now it works. Otherwise I might think that I'll have to spend a lot of time like it usually happens with bugs in CKEditor.

Then I've been reviewing the suggested changes to the "background image" plugin.

Some months ago OFark provided a patch to add support for background-repeat and background-position, but after merging those changes I faced some issues and moved to do other things, creating a branch so that the code doesn't get lost.

More recently LazyHammer did provide a new patch and this time things looked better, so I've been checking that a little and although it is still not perfect (for example it leaves garbage styles after removing the background image on the table) it worked well enough for most of the people, so I've uploaded version 1.4

If you are interested in a plugin and there's something that you want to improve, please create a patch and I'll try to review it.
The better it works and the more info about what's the original problem, the faster the review :-)

2013/08/14

I still hate GitHub for Windows

I've been trying to use a little GitHub for some time but it's clear that I won't ever be able to think as other developers do.
I just want to do simple things like I used to do previously keeping a local repository of CKEditor and the patches that aren't being added to the main code. Using TortoiseSVN that was a breeze, no need to remember anything, just go to the explorer right click and under the Tortoise everything was available right there. No matter if I didn't touch SVN for months and I forgot everything about CKEditor and SVN, it's just a matter of reading the name of the options and then click Update after finding it. If the changes were too complex then its merge editor showed the problems and I could easily adjust the conflicting code.

Now CKEditor works with GitHub and so many other people also live and die by GitHub that I've been trying to use it, but it's so different that I can't spend the time to forget everything that I know and start over as some of the books on GitHub suggest (hey man, it's so complex to use that you need to study a book in order to understand it and learn that divine "git workflow")

Of course there are two parts here:
Maybe SVN but itself is also ugly and I just enjoyed the easy of use of TortoiseSVN, but the fact is that I've been trying to use the GUI that they provided for windows, so maybe the problem isn't Git by itself and it's just GitHub for Windows.

The first (ugly) surprise is that instead of using the common controls and theme of my windows, it's using that flat look of windows 8 in "modern" mode.
Hint: If I'm using certain version of windows and I'm using a theme (just the classic one, nothing fancy), it might be because I enjoy it and I don't want to use Windows8 even if you pay me.

Everything is flat, there's no real hint about which elements are simple text and which ones are active ones that can be used for something.
The colors are white background, grey text and some highlights; it's sad, no distinctive elements to clearly show the different zones and possibilities that the UI offers.
Or maybe the problem is that so few things are possible, I'm always thinking that I must be doing something wrong because I can't understand how to change things.

Last week I created a repository for a new little project. Sounds easy right?
not so.
It showed up with a lock icon (instead of the book like the other ones) and despite my efforts I haven't managed to make it show the readme.md in local.

And it's better to not talk about the time that it takes to load that fugly UI...

2013/08/10

A basic upload script for CKEditor

A long time ago I published a basic example showing the skeleton of how an upload script for CKEditor should look like. Since the release of the imagepaste plugin I've received some requests to fill and explain all the details, and some people buy that plugin even before testing the free version and then they find that they don't know how to upload files.

So now I'm publishing that script with the missing part, a simple call to

move_uploaded_file($_FILES["upload"]["tmp_name"], $basePath . $name);

I've adjusted it a little so that the path to the upload folder and matching URL can be configured more easily, but it's still a very basic script. It doesn't perform any check on the uploaded files, you must take care of integrating it with your CMS (after all, that's something impossible for me to know how you're doing that part) and verify that the upload folder has the right permissions.

You can use it with CKEditor to enable the Upload tab in the Image and Link dialogs, and that way the user will be able to upload files (but not browse the existing ones). If you add the free version of the image paste plugin, then the user will be able to paste images from their clipboard into CKEditor, and the content will not be that huge mess of base64 encoded data, but a simple URL to your server with all the performance benefits that it means.

At this point, you can opt to buy the full version of the image paste plugin if you want to provide even more options for the users:

  • Drag and drop from the computer for every modern browser
  • Pasting images from the clipboard in Chrome (besides the basic pasting available in the free version for Firefox)
  • Copy and paste a file from your computer in Firefox
  • Two buttons to quickly upload a file or image for every browser. There's no way to make uploads simpler than this, other plugins still require the user to open a dialog, click browse, upload, etc... that's a huge mess and a big waste of time. Here you click and the file picker launches automatically, select the file that you want and then it's uploaded and inserted in a single step.

You can test all these features in the demo page for CKEditor 4 (the plugin also works with CKEditor 3)

Back to this upload script:

I've published it at GitHub so if other people wants to provide some suggestions for better compatibility or they take the time to improve it I will try to keep it updated, but I don't really want to spend too much time on it because if by a miracle it would be a success (in fact, I wouldn't like to see too many people using this because it's really basic) then attackers would love to exploit all the weakness that it has. Please, read the documentation, all the comments and try your best to secure it as much as you can. If you download it from GitHub, you can remove those extra .git* files that it has added automatically as well as the readme and the docs when you have read them.

You only need the upload.php file and to improve a little the security by obscurity you can opt to rename it anyway that you want, just put that same name and path in the configuration of your CKEditor.

The best option would be for you to take this script as a full example and then add your customizations, your own security options, make it unique so that a simple bot can't find and use it.

This is the link to download the current version from GitHub.