Jump to content
kongondo

Module: Jquery File Upload

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 30

Share this post


Link to post
Share on other sites

Man - you aren't just on fire at the moment, you are ablaze :)

Nice work - I have used Blueimp on some other projects pre-PW and loved it, so thank you!

  • Like 1

Share this post


Link to post
Share on other sites

Your timing is impeccable - just what I need today! :)

Share this post


Link to post
Share on other sites

Man - you aren't just on fire at the moment, you are ablaze :)

Nice work - I have used Blueimp on some other projects pre-PW and loved it, so thank you!

3 AM blues!

  • Like 1

Share this post


Link to post
Share on other sites

I finally made it to work on frontend - didn't notice 'disableUploads' => true in the example ... should read more carefully

Share this post


Link to post
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

Share this post


Link to post
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);

Share this post


Link to post
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.

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

Do you have the demo without/or different music? The German GEMA and SME had YouTube blocking the video for Germany.  :'(

  • Like 1

Share this post


Link to post
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

Share this post


Link to post
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.

Share this post


Link to post
Share on other sites

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

:ph34r:

...I have started the 'slow' upload to vimeo... :'(.... :lol:

  • Like 1

Share this post


Link to post
Share on other sites

Here's the vimeo version. Cannot get 1080p quality unless you are on the paid plans, but its viewable. I don't think am uploading to vimeo again...this was the first and last time. It takes forever and they restrict the quality, tsk.  :-)

  • Like 1

Share this post


Link to post
Share on other sites

It is an awesome video, so, also with music. Have had a nice looking. Thanks man!

Will also try the module in the next time.

  • Like 1

Share this post


Link to post
Share on other sites

Will also try the module in the next time.

Thanks. Will appreciate your professional opinion especially regarding the client-side-image resizing

  • Like 1

Share this post


Link to post
Share on other sites

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..

Share this post


Link to post
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

Share this post


Link to post
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? :)

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Robin S
      A community member raised a question and I thought a new sanitizer method for the purpose would be useful, hence...
      Sanitizer Transliterate
      Adds a transliterate method to $sanitizer that performs character replacements as defined in the module config. The default character replacements are based on the defaults from InputfieldPageName, but with uppercase characters included too.
      Usage
      Install the Sanitizer Transliterate module.
      Customise the character replacements in the module config as needed.
      Use the sanitizer on strings like so:
      $transliterated_string = $sanitizer->transliterate($string);
       
      https://github.com/Toutouwai/SanitizerTransliterate
      https://modules.processwire.com/modules/sanitizer-transliterate/
       
    • By dimitrios
      Hello,
      this module can publish content of a Processwire page on a Facebook page, triggered by saving the Processwire page.
      To set it up, configure the module with a Facebook app ID, secret and a Page ID. Following is additional configuration on Facebook for developers:
      Minimum Required Facebook App configuration:
      on Settings -> Basics, provide the App Domains, provide the Site URL, on Settings -> Advanced, set the API version to 2.10, add Product: Facebook Login, on Facebook Login -> Settings, set Client OAuth Login: Yes, set Web OAuth Login: Yes, set Enforce HTTPS: Yes, add "http://www.example.com/processwire/page/" to field Valid OAuth Redirect URIs. This module is configurable as follows:
      Templates: posts can take place only for pages with the defined templates. On/Off switch: specify a checkbox field that will not allow the post if checked. Specify a message and/or an image for the post.
      Usage
      edit the desired PW page and save; it will post right after the initial Facebook log in and permission granting. After that, an access token is kept.
       
      Download
      PW module directory: http://modules.processwire.com/modules/auto-fb-post/ Github: https://github.com/kastrind/AutoFbPost   Note: Facebook SDK for PHP is utilized.


    • By thomasaull
      I created a little helper module to trigger a CI pipeline when your website has been changed. It's quite simple and works like this: As soon as you save a page the module sets a Boolean via a pages save after hook. Once a day via LazyCron the module checks if the Boolean is set and sends a POST Request to a configurable Webhook URL.
      Some ideas to extend this:
      make request type configurable (GET, POST) make the module trigger at a specified time (probably only possible with a server cronjob) trigger manually Anything else? If there's interest, I might put in some more functionality. Let me know what you're interested in. Until then, maybe it is useful for a couple of people 🙂
      Github Repo: https://github.com/thomasaull/CiTrigger
    • By Robin S
      I created this module a while ago and never got around to publicising it, but it has been outed in the latest PW Weekly so here goes the support thread...
      Unique Image Variations
      Ensures that all ImageSizer options and focus settings affect image variation filenames.

      Background
      When using methods that produce image variations such as Pageimage::size(), ProcessWire includes some of the ImageSizer settings (height, width, cropping location, etc) in the variation filename. This is useful so that if you change these settings in your size() call a new variation is generated and you see this variation on the front-end.
      However, ProcessWire does not include several of the other ImageSizer settings in the variation filename:
      upscaling cropping, when set to false or a blank string interlace sharpening quality hidpi quality focus (whether any saved focus area for an image should affect cropping) focus data (the top/left/zoom data for the focus area) This means that if you change any of these settings, either in $config->imageSizerOptions or in an $options array passed to a method like size(), and you already have variations at the requested size/crop, then ProcessWire will not create new variations and will continue to serve the old variations. In other words you won't see the effect of your changed ImageSizer options on the front-end until you delete the old variations.
      Features
      The Unique Image Variations module ensures that any changes to ImageSizer options and any changes to the focus area made in Page Edit are reflected in the variation filename, so new variations will always be generated and displayed on the front-end.
      Installation
      Install the Unique Image Variations module.
      In the module config, set the ImageSizer options that you want to include in image variation filenames.
      Warnings
      Installing the module (and keeping one or more of the options selected in the module config) will cause all existing image variations to be regenerated the next time they are requested. If you have an existing website with a large number of images you may not want the performance impact of that. The module is perhaps best suited to new sites where image variations have not yet been generated.
      Similarly, if you change the module config settings on an existing site then all image variations will be regenerated the next time they are requested.
      If you think you might want to change an ImageSizer option in the future (I'm thinking here primarily of options such as interlace that are typically set in $config->imageSizerOptions) and would not want that change to cause existing image variations to be regenerated then best to not include that option in the module config after you first install the module.
       
      https://github.com/Toutouwai/UniqueImageVariations
      https://modules.processwire.com/modules/unique-image-variations/
    • By Sebi
      I've created a small module which lets you define a timestamp after which a page should be accessible. In addition you can define a timestamp when the release should end and the page should not be accessable any more.
      ProcessWire-Module: http://modules.processwire.com/modules/page-access-releasetime/
      Github: https://github.com/Sebiworld/PageAccessReleasetime
      Usage
      PageAccessReleasetime can be installed like every other module in ProcessWire. Check the following guide for detailed information: How-To Install or Uninstall Modules
      After that, you will find checkboxes for activating the releasetime-fields at the settings-tab of each page. You don't need to add the fields to your templates manually.
      Check e.g. the checkbox "Activate Releasetime from?" and fill in a date in the future. The page will not be accessable for your users until the given date is reached.
      If you have $config->pagefileSecure = true, the module will protect files of unreleased pages as well.
      How it works
      This module hooks into Page::viewable to prevent users to access unreleased pages:
      public function hookPageViewable($event) { $page = $event->object; $viewable = $event->return; if($viewable){ // If the page would be viewable, additionally check Releasetime and User-Permission $viewable = $this->canUserSee($page); } $event->return = $viewable; } To prevent access to the files of unreleased pages, we hook into Page::isPublic and ProcessPageView::sendFile.
      public function hookPageIsPublic($e) { $page = $e->object; if($e->return && $this->isReleaseTimeSet($page)) { $e->return = false; } } The site/assets/files/ directory of pages, which isPublic() returns false, will get a '-' as prefix. This indicates ProcessWire (with activated $config->pagefileSecure) to check the file's permissions via PHP before delivering it to the client.
      The check wether a not-public file should be accessable happens in ProcessPageView::sendFile. We throw an 404 Exception if the current user must not see the file.
      public function hookProcessPageViewSendFile($e) { $page = $e->arguments[0]; if(!$this->canUserSee($page)) { throw new Wire404Exception('File not found'); } } Additionally we hook into ProcessPageEdit::buildForm to add the PageAccessReleasetime fields to each page and move them to the settings tab.
      Limitations
      In the current version, releasetime-protected pages will appear in wire('pages')->find() queries. If you want to display a list of pages, where pages could be releasetime-protected, you should double-check with $page->viewable() wether the page can be accessed. $page->viewable() returns false, if the page is not released yet.
      If you have an idea how unreleased pages can be filtered out of ProcessWire selector queries, feel free to write an issue, comment or make a pull request!
×
×
  • Create New...