2013/12/11

Validation of files with SimpleUploads

As a user is frustrating to upload a file and then after waiting a long time for it to finish get a message stating that your file isn't valid. That's why the SimpleUploads plugin for CKEditor allows to perform most of the validations before the upload starts and that way you'll have happier users.

In this post I will explain how to configure the most common options and you can test them in a demo page for validation of uploads.

Allowed extensions

This is the most basic check, a whitelist of extensions that the users can upload to the server

config.simpleuploads_acceptedExtensions = "jpg|png|zip";

By default the value is empty so no check is performed. You can add the the list of extensions separated by the pipe "|" and that will be used to check the filename. If the extension isn't allowed the nonAcceptedExtension message will be shown to the user (you can customize it in the lang file).

All the editors in the demo only allow to upload the files with a list matching the settings on the server, except the first inline demo. In that demo the list is set to an empty string so any file is uploaded and then you get the error message from the server (in this case an un-friendly "202 upload failed")

Denied extensions

This is the opposite of allowed, if the extension matches this list the file will be rejected. I only added this configuration option for parity, but everybody knows that a blacklist approach is not good for security. The demo page doesn't include this option.

Image extensions

This setting has two purposes.

The first one is that when you drop a file the plugin must decide if it should create an <img> or an <a> with the upload. The user can opt to press the Shift key while dropping the file to generate a link even if he adds an image file, but as a general rule you might want to allow only png and jpg files for example, or include .bmp and .tiff and then convert those files to other format at the server.

The second purpose is to restrict the accepted files when the user presses the "Add image" button as well as the uploads in the image dialog. If the selected file doesn't match this filter it will be rejected and the nonImageExtension message will be shown to the user (this feature will be included in version 4.1.1, the current one is 4.1.0).

config.simpleuploads_imageExtensions = 'jpe?g|gif|png|bmp';

The bottom editor in the middle is configured to only allow png files as images. You can check that if you drop a jpg is inserted as a link, and the toolbar buttons and image dialogs will reject anything that isn't a png.

File size

Obviously uploading a 100Mb file is usually a bad idea, but the users don't realize that and that's why you can easily set the maximum size that you allow them to use with simpleuploads_maxFileSize. The default value is empty so no check is performed, but you can set here the value that you want to limit (as an integer with the bytes, so 10Mb => 10*1024*1024

The inline editor at the top middle uses a limit of 100Kb, if the selected file is bigger, the fileTooBig message is shown to the user.

config.simpleuploads_maxFileSize = 102400;

As a side note, file size is a common problem and even if you don't bother to adjust this setting, the server might return a "413 Request Entity Too Large" status error, in that case the plugin handles that error and shows again the fileTooBig message to the user instead of just stating that the upload failed.

Custom validation

Maybe you think that you still want to do some other check like forcing the user to select a file with a custom pattern and a minimum file size, or whatever, ok, you can do that also.

The last editor at the bottom right only allows to upload files that start with "wall" by listening to the  "simpleuploads.startUpload" event.

The code in this example is quite simple

editor.on('simpleuploads.startUpload', function (ev) {
 // File name
 var name = ev.data.name;
 if (name.substr(0,4).toLowerCase() != "wall")
 {
  alert( "You must add here only wallpapers" );
  ev.cancel();
 }
});

We set the listener on the editor instance that we want and use the ev.data.name property to check the file name that the user has selected, if it doesn't pass our test we cancel the event and show a message to the user.

In fact most of the previous validations (except for identifying images) are performed using this event, the plugin adds a listener like that for each editor and uses the configuration values to verify if the file is valid or it should be rejected using the file name as well as the file object to check its size.

Server messages

Even after all these checks, there might be some other issues that can't be handled at the client side, in that case remember that in the response that you send from the server you can set an empty Url and the third parameter is a message that will be shown to the user.

2 comments:

Brec Carson said...

I would love to be able to do something asynchronous inside the simpleuploads.startUpload handler. Is there anyway to include a callback in addition to the event parameter?

Alfonso Martínez de Lizarrondo said...

If you want to work with images then you should use the new 'simpleuploads.localImageReady' event that provides an Image object and you can work with it.
http://www.martinezdelizarrondo.com/ckplugins/simpleuploads.demo4/resize.html

If that's not enough, you could copy the code that generates it and adjust it to your needs: I added an API that allows to insert a file that has been processed asynchronously and you can reuse it.