Jump to content

Module: Jquery File Upload


kongondo

Recommended Posts

JqueryFileUpload
 
This module is a ProcessWire implementation of the awesome Blueimp jQuery File Upload plugin.  Server-side, the module provides a custom uploads' handler enabling you to perform various tasks with ease. The module is an interface of the feature-rich Ajax File Uploads widget provided by the jQuery File Upload plugin.
 
The module is completely customisable and can be used both in the front- and backend (e.g. in a third-party module). 
 
Please read the README  carefully and completely before using the module
 
Release Status: Stable
Module Download: http://modules.processwire.com/modules/jquery-file-upload/
Issues tracker Project page: GitHub
 
Security
The module has been written with security in mind and makes no assumptions about any client-side validation. Instead, the module provides robust server-side validation of uploaded files. Server-side, no Ajax requests are honoured unless specifically set via configurable options server-side. This means that client-side requests to upload, delete and list files are not executed unless allowed server-side. By default, files are uploaded to a non-web-accessible (system) folder and files previously uploaded on the server are not sent back for display unless that setting is enabled. However, developers are still strongly advised to implement any other feasible measures to guard against malicious uploads, especially if allowing frontend uploading. For instance, developers can use native ProcessWire checks to limit access to the widget (e.g. only allowing uploads by registered/logged-in users).
 
Demo
A short video demo can be found here (and below :-))(CSS is WIP!  :-)). In the backend, you can see it in action within the (upcoming) module Media Manager
 
Features

  •  Fast Ajax uploads.
  •  Client and server-side validation.
  •  Client-side image resizing (highly configurable options).
  •  Beautiful touch-responsive image gallery preview.
  •  Audio and video previews pre-upload.
  • Chunked and resumable file uploads (currently client-side only; server-side handling planned).
  •  Drag and drop support.
  •  Copy and paste support (Google Chrome only).
  •  Progress bars.
  •  Cross-domain uploads.
  •  Single or multiple uploads.
  •  Delete uploaded files.

Documentation
On GitHub. Have a look at the long list of available options.
 
License
Released under the MIT license
 
@Credits: Sebastian Tschan
@Thanks: Pete and BernhardB for the idea.
 
Please test and provide feedback. Thanks!
 

  • Like 32
Link to comment
Share on other sites

Testing again on IIS with PW3. After upload I don't have access to uploaded files. I get HTTP 500.50 error along with 0x80070005 and that is (from my experience) permission issue. I'm assuming (didn't look at your sources) that files are uploaded to temp directory (PHP's upload_tmp_dir?) and then moved/renamed to the final destination at /site/assets/files/jqfu/files. In the process of moving the files, permissions of the files are inherited from the temp directory and those are not sufficient for the web server. Would you consider using $config->$uploadTmpDir instead of PHP's upload_tmp_dir?

Edit: I see you are using WireUpload class so I'll have to take a closer look into WireUpload.php...

Edited by matjazp
Link to comment
Share on other sites

PHP stores the uploaded file in the folder determined by upload_tmp_dir directive in php.ini. By default this is C:\Windows\Temp directory. After the uploaded file is stored to the upload_tmp_dir, ProcessWire will then move/rename the file to the final destination directory and that doesn’t inherit destination directory’s permissions. There are multiple options on how to make it work:
 
a.) Change the permissions on the windows temp folder giving IUSR and IIS_IUSRS  write/modify
b.) Change the path of the upload_tmp_dir in the php.ini file to a folder with appropriate permissions
c.) Change the way WireUpload works so that it copy the file, not rename/move it.
 
I didn't have upload problems in admin, because I used $config->$uploadTmpDir pointing to the /site/assets/uploads folder (created by me). This folder is used in WireUpload.php with ajax uploading (using $_SERVER['HTTP_X_FILENAME']). Since /site/assets/uploads folder inherits /site/assets folder permissions, moving/renaming the file is not the problem. When uploading using PHP's $_FILES global variable, $config->$uploadTmpDir is not used and files are uploaded to the folder set up by upload_tmp_dir directive.

As copying in slower than renaming, I'm not sure if this is the right solution (file WireUpload.php in function saveUpload):

$success = move_uploaded_file($tmp_name, $destination);

to:

$success = is_uploaded_file($tmp_name);
if($success) $success = @copy($tmp_name, $destination);
if(is_file($tmp_name)) @unlink($tmp_name);
Link to comment
Share on other sites

Good forensics. If it's a WireUpload.php issue then you can put in a request with @Ryan to hear his thoughts? Meanwhile, you can always use a custom uploads handler in conjunction with the other methods that come with the module, e.g. getResponse() which calls the crucial validation methods.

Link to comment
Share on other sites

I've written the issue on GitHub to hear Ryan's thoughts. I'm not good enough in PHP or PW internals and don't know when ajax upload is used. In "ajax mode" uploaded file is read from php://input and then created at the $config->$uploadTmpDir (if set) folder. In "nonajax mode" $config->$uploadTmpDir is not used - files are uploaded to the folder set up by upload_tmp_dir directive in php.ini It would be ideal if "nonajax upload" would store files in $config->$uploadTmpDir to... Is this possible? Sorry for dumb questions...

  • Like 1
Link to comment
Share on other sites

For a minute there I thought you were kidding. Never heard of this German GEMA & SME thing. I have just quickly read up about it. Well, I could try upload the video to Vimeo (would that work?) or you could do me a favour and watch the YT one behind a proxy :) ...that's not illegal, or is it?

Edit: There's also the 'original' demo at Blueimp

  • Like 1
Link to comment
Share on other sites

For a minute there I thought you were kidding. Never heard of this German GEMA & SME thing. I have just quickly read up about it. Well, I could try upload the video to Vimeo (would that work?) or you could do me a favour and watch the YT one behind a proxy :) ...that's not illegal, or is it?

I assume this will not work with a simple proxy as it is not that easy to trick google / youtube.

Link to comment
Share on other sites

  • 1 month later...

Firstly - Kongondo - thanks for another great module.

I have been working on this all day and I have the form working well on the frontend, I can upload images and other files and I can see the upload progress etc on screen which is great and exactly what I've been looking for.

Where I've hit a brick wall for the last 3-4 hours though is I can't work out how to attach this to a field on one of my templates.  I have a template where I want to have a field which will allow users to upload images or files via the frontend. I have some other fields in the template too (normal text fields for description etc) and I have had those working for a long time - what I can't work out is how do I take the files uploaded via this jQuery module and add them to the files field in my template???

Any help gratefully received..

Link to comment
Share on other sites

Hi @Hantsweb,

Glad you like the module.

Technically, you can't 'attach' the module to a field in one of your templates :-). But I think I get what you are saying. You want uploaded files to be added to a field on some page(s). Before I dive into an answer, I hope in your upload implementation you've remembered to...'never to trust your users',...especially those who are allowed to add things to pages and whether what they've uploaded is immediately viewable on the frontend :-). Yes, the module does very thorough validation and will only upload what you've allowed to be uploaded but its always good to double check.

Below are links to some code I've previously posted that will be of help. What is your workflow? Are user uploads immediately added to a page? Are there unique pages for each user? Are compressed files (zip) in play? Whatever the answer to these questions, the basics are the same:

  1. Upload files to your server to a specified temporary folder(s). During the process validate the files: JqueryFileUpload
  2. Iterate over the folder with the uploads: I always use PHP SPL class for this, e.g. RecursiveDirectoryIterator
  3. In each iteration, add valid files to specified pages (if those pages are not being created by the uploads): Use ProcessWire for this
  4. Delete uploads in the temporary folder

Example code:

https://processwire.com/talk/topic/10815-mass-create-pages-or-mass-upload-images-and-thus-create-pages/?p=101791

https://processwire.com/talk/topic/8416-importing-many-pictures-in-a-page/

If you are adding to files to pages directly after they've been uploaded, you will want to listen to Ajax requests sent by JqueryFileUpload like so:

if ($this->config->ajax) {
  // you code here for iteration, creating and/or adding files to pages

}

Let us know if you hit another brick wall :-)

  • Like 1
Link to comment
Share on other sites

hi kongondo,

if i get you right, this module is intended to be used on frontend, isn't it? in the demo, though, it is used in backend with your media manager. would it be hard to get some kind of replacement of a standard image field directly in the backend? :)

Link to comment
Share on other sites

hi kongondo,

if i get you right, this module is intended to be used on frontend, isn't it? in the demo, though, it is used in backend with your media manager. would it be hard to get some kind of replacement of a standard image field directly in the backend? :)

:huh:  :huh:   :o  :o  :undecided:   :undecided:  

The module is completely customisable and can be used both in the front- and backend (e.g. in a third-party module).

In the video 0.00 - 4.25 Frontend (check the URL); 4.25 to end Backend (MediaManager)

:-)

As for your question about image replacement: I think it would be easiest to either extend FieldtypeFile or modify FieldtypeImage as a new module (and/or their related Inputfields - am not sure). What exactly are you after? I ask because I know there are some cool changes coming to the 'standard image field' and those might just meet your needs.

Edited by kongondo
  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...