Jump to content


Photo

Support for drag & drop, multiple file selects and instant uploads in file field


  • Please log in to reply
132 replies to this topic

#21 apeisa

apeisa

    Hero Member

  • Moderators
  • 2,517 posts
  • 842

  • LocationVihti, Finland

Posted 29 August 2011 - 03:33 PM

There are security restrictions and it is impossible to do multipart/form-data posts in javascript. But it is possible to send files in File API and the backend side looks simple enough: http://www.sitepoint...ax-file-upload/

So not 100% sure about implementation yet, but I think we'll get there soon :) I try to fork myself and ask your help when needed.

#22 apeisa

apeisa

    Hero Member

  • Moderators
  • 2,517 posts
  • 842

  • LocationVihti, Finland

Posted 29 August 2011 - 03:54 PM

Ok, I got this working. Not sure how you manage saving files on pw when using admin. Do they got saved directly to assets/files/id/ folder or is there tmp somewhere?

I did just small if clause to your executeFields method:

<?php
public function ___executeFields() {
		
		// We check if it is image upload
		$filename = (isset($_SERVER['HTTP_X_FILENAME']) ? $_SERVER['HTTP_X_FILENAME'] : false);
		
		if ($filename) {
			$this->message("It is a file coming!");
			file_put_contents(  
				'C:/Temp/' . $filename,  
				file_get_contents('php://input')  
			);  
		} else {

			if(!$this->isAjaxPost) throw new WireException("This functionality may only be accessed from AJAX POST at present");
		
                        // etc etc...

		
	}

And now I am able to save my files to C:/Temp/. Not sure about the best way to handle this from this situation? Save it to temp folder and use regular pw API and save the file? Or save it right to assets/files/id/ folder and then use API? I can easily send more data (like field name) as a http headers.

If we save it directly to right place (probably safe since this is admin usage), how I get the right path? $config->paths->files->3242 or something like that?

#23 apeisa

apeisa

    Hero Member

  • Moderators
  • 2,517 posts
  • 842

  • LocationVihti, Finland

Posted 29 August 2011 - 04:30 PM

Ok, I added three more lines for my last code snippet, and it is now working:

<?php
if ($filename) {
			$fieldname = $_SERVER['HTTP_X_FIELDNAME'];
			$this->message("Should be file upload");
			// AJAX call  
			file_put_contents(  
				'C:/Temp/' . $filename,  
				file_get_contents('php://input')  
			);
			$this->page->$fieldname->add('C:/Temp/' . $filename);
			$this->page->save();
		}

Of course we don't wanna keep that C:/Temp/ hardcoded there, but waiting for Ryan's reply on that issue. I will finish details and test this on all browsers that supports these goodies (hehe, there are only two - easy job ;)). Gotta say that this makes image uploading fun and fast :) And because TinyMCE image inserting (or file linking) works through iFrame-modal, then images/files added with html5 browser are available right away, without first saving the page.

Some more details need to be considered, like what if I drop 10 files, but field allows only one? There seems to be now backend check, so through API it is possible to add more files than field allows. I'm not sure but it might be wiser to move that logic to backend (if there is no room for new images, just skip)? Not sure tough... it wouldn't be that hard to add restrictions on client side also, like the current solution has (no more input fields appear after you have enough images).

EDIT: And for all who are interested, this is the js-code that sends the image:
var xhr = new XMLHttpRequest();
// This allows us to track progress, nice little progressbar coming!
xhr.upload.addEventListener("progress", this.ProgressHandler); 
xhr.open("POST", "./fields?id=" + page_id, true);
xhr.setRequestHeader("X-FILENAME", f.fileName);
xhr.setRequestHeader("X-FIELDNAME", fieldName);
xhr.send(f);

Nice and simple. And here is the great tutorial which helped so much in the progress: http://www.sitepoint...-drag-and-drop/

#24 ryan

ryan

    Hero Member

  • Administrators
  • 5,753 posts
  • 3102

  • LocationAtlanta, GA

Posted 29 August 2011 - 04:43 PM

Glad that you got this working. Though admittedly, I still have no idea exactly what's happening on the front end or what it looks like. All I know is that it sounds good. :)

The ProcessPageEdit doesn't actually have any logic for saving custom fields, all that is delegated to the Inputfield modules. For instance, InputfieldFile. That module creates an instance of WireUpload (/wire/core/Upload.php) to retrieve the file and make sure all is good with the filename, file type, etc. I'm thinking that's probably where the logic should go (WireUpload class), because then it'll be available to all file upload fields.

The destination path for a given page's files can be found from the field it's going to, i.e.

$page->your_files_field->path;

You can also get it without knowing the fieldname like this:

$page->filesManager->path;



#25 apeisa

apeisa

    Hero Member

  • Moderators
  • 2,517 posts
  • 842

  • LocationVihti, Finland

Posted 29 August 2011 - 05:33 PM

Glad that you got this working. Though admittedly, I still have no idea exactly what's happening on the front end or what it looks like. All I know is that it sounds good. :)


I know ;) I have tried my best to keep myself away to screencast this until I have something what I consider solid enough. I don't know why, but for me usually things slow down after you get first amount of feedback. I think that the feelgood makes you think that it is good enough already and soon you lose interest to polish the little details.

The ProcessPageEdit doesn't actually have any logic for saving custom fields, all that is delegated to the Inputfield modules. For instance, InputfieldFile. That module creates an instance of WireUpload (/wire/core/Upload.php) to retrieve the file and make sure all is good with the filename, file type, etc. I'm thinking that's probably where the logic should go (WireUpload class), because then it'll be available to all file upload fields.


Sounds like a right place. I think we need to test and play a little and decide how much validation we need here.

$page->filesManager->path;


Thanks, that worked just fine!

I am now really finishing this (styling the upload bars etc). It's getting little late, so it might be tomorrow before I have something to show. Can't wait to share this one out.

#26 Pete

Pete

    Administrator

  • Administrators
  • 1,754 posts
  • 652

  • LocationChester, England

Posted 30 August 2011 - 03:17 AM

Really looking forward to this - keep up the good work, but yes - remember to sleep ;)

#27 apeisa

apeisa

    Hero Member

  • Moderators
  • 2,517 posts
  • 842

  • LocationVihti, Finland

Posted 30 August 2011 - 04:57 AM

Really looking forward to this - keep up the good work, but yes - remember to sleep ;)


Got 3 hours of solid sleep, paying for that today at work meetings... :)

#28 Pete

Pete

    Administrator

  • Administrators
  • 1,754 posts
  • 652

  • LocationChester, England

Posted 30 August 2011 - 07:53 AM

Bah, you don't have to stay awake through meetings do you? ;)

#29 ryan

ryan

    Hero Member

  • Administrators
  • 5,753 posts
  • 3102

  • LocationAtlanta, GA

Posted 30 August 2011 - 08:19 AM

Sounds like a right place. I think we need to test and play a little and decide how much validation we need here.


I'm thinking it should just go through the same exact validation as all the other uploaded files, if possible. This validation mainly consists of making sure it's the right file type (via extension) and renaming the file to be consistent with the characters PW allows for filenames. Though it also does some other stuff, like optionally unzipping zip files. The image Fieldtype also resizes the original image file if necessary (as you know). But don't worry too much about this stuff now– If you get a working example going, I'll be happy to place all the code where it needs to go. And of course, take your time… no rush. I just wanted to make sure I get you everything you need and all questions answered when you need it.




#30 apeisa

apeisa

    Hero Member

  • Moderators
  • 2,517 posts
  • 842

  • LocationVihti, Finland

Posted 30 August 2011 - 02:06 PM

Ok, here we go now. I didn't implement any validation (I let Ryan do that), so you are able to upload any files to image fields etc. Also it is possible to add more files than is allowed per image field.

I'm not sure if I remembered all the files needed, but should be. Just replace InputfieldFile folder from /wire/modules/inputfield and ProcessPageEdit goes to /wire/modules/process/processpageedit.

Will record little screencast soon (ready: http://screencast.com/t/IQk7U4Aewe). There are some things I would like to polish and rethink in the UI (bigger drop area and next to inputfield, not below), but overall it should be pretty usable. Please let me know what you think?


PS: There is image preview code commented out in the js-file - it did slow down the page very much if you added big images (even crashed my chrome dev inspector). You can try it if you want it.

PPS: Consider this "highly experimental" and try only on test environment :)

Attached Files



#31 ryan

ryan

    Hero Member

  • Administrators
  • 5,753 posts
  • 3102

  • LocationAtlanta, GA

Posted 30 August 2011 - 06:23 PM

Just watched the screencast and it's great! Now I understand what all the excitement is about. :) I haven't yet installed it–only a few minutes left before I have to go, but planning to install first thing tomorrow morning (or later this evening, if possible). Love the way you did the progress bars. This all seems like quite a fantastic UI option for uploading images or files. Well done!


#32 ryan

ryan

    Hero Member

  • Administrators
  • 5,753 posts
  • 3102

  • LocationAtlanta, GA

Posted 30 August 2011 - 10:12 PM

Finally got a moment here to install and test it out. What can I say, it's awesome. :) Love it! This is how I'll be uploading files from now on. I'm thinking this must go in the first version of 2.1. One question is if there needs to be a 'drop area'? Is it possible to just have the entire field be a drop area?

#33 Pete

Pete

    Administrator

  • Administrators
  • 1,754 posts
  • 652

  • LocationChester, England

Posted 31 August 2011 - 02:19 AM

I'd be ecstatic if this was in version 2.1 - so much better than the decade-old way of doing file uploads on the web :)

#34 apeisa

apeisa

    Hero Member

  • Moderators
  • 2,517 posts
  • 842

  • LocationVihti, Finland

Posted 31 August 2011 - 06:40 AM

Thanks guys. I have been demoing this today at the office, and it has nice sales effect also. It does look & feel cool :) Also gives as possibility to brand pw as "HTML5 CMS" :D

One question is if there needs to be a 'drop area'? Is it possible to just have the entire field be a drop area?


Great idea, I will implement this. I will leave some text indicator to tell editors that you can drop files, but use the whole field as "drop area".

#35 ryan

ryan

    Hero Member

  • Administrators
  • 5,753 posts
  • 3102

  • LocationAtlanta, GA

Posted 31 August 2011 - 08:55 AM

Definitely major marketing value in this. This is one of those things that will be great to show in the PW 2.1 "what's new" video.

#36 apeisa

apeisa

    Hero Member

  • Moderators
  • 2,517 posts
  • 842

  • LocationVihti, Finland

Posted 31 August 2011 - 03:51 PM

Ok, few small improvements:

  • No more "drop area", just throw your files to the field and that's it (I did leave small "or drop your files here" notification, so that people will know the possibility)
  • Added 5-99% percentages to progressbar
  • Cleaned and credited the code. Not sure where I should thank the guys (Robert Nyman and Craig Buckler) who provided initial code examples and tutorials, so I putted in to the comments with links.

EDIT: Added ProcessPageEdit.module to attachment, since if someone tests this from zip only it won't save the files...

Attached Files



#37 ryan

ryan

    Hero Member

  • Administrators
  • 5,753 posts
  • 3102

  • LocationAtlanta, GA

Posted 31 August 2011 - 05:20 PM

Awesome update! I just dragged in 6 files... beautiful! Even better now that I can just drag them anywhere in the field. Thank you for your fantastic work with this. I'm going to dig deeper into your code here soon so that I can figure out how to get this to be built-in to the WireUpload class.

#38 apeisa

apeisa

    Hero Member

  • Moderators
  • 2,517 posts
  • 842

  • LocationVihti, Finland

Posted 02 September 2011 - 03:23 AM

This has been causing issues on Soma's site and localhost. We did little debug session, and it seems that for some reason this:

$this->page->filesManager->path

returns nothing. So it tries to write the file to root and that gives (of course) permission issues:

<b>Warning</b>:  file_put_contents(/Koala.jpg) [<a href='function.file-put-contents'>function.file-put-contents</a>]: failed to open stream: Permission denied in <b>/path/to/pw/wire/modules/Process/ProcessPageEdit/ProcessPageEdit.module</b> on line <b>933</b>


We continue testing and report if $this->page->$fieldname->path works there.

But I am confused what might cause $this->page->filesManager->path to fail on Soma's server and localhost? He is using latest version of P21.

EDIT: This code works:

$this->page->$fieldname->path . "/" . $filename, 

One issue left: it saves files with the name it is saved (of course), like: Lighthouse.jpg, but on admin site it tries to get it with small first letter: getimagesize(/path/to/site/assets/files/1003/lighthouse.jpg) => this causes error. This seems to be something that will not be issue after ProcessPageEdit.module will use the wireupload class?

#39 Soma

Soma

    Hero Member

  • Moderators
  • 3,183 posts
  • 1733

  • LocationSH, Switzerland

Posted 02 September 2011 - 04:46 AM

Found the issue:

$page->filesManager->path - doesn't return anything, it should be:
$page->filesManager->path() - this works

I changed this in ProcessPageEdit.module to be $this->page->filesManager->path()
and now upload works.

@somartist | modules created | support me, flattr my work flattr.com


#40 apeisa

apeisa

    Hero Member

  • Moderators
  • 2,517 posts
  • 842

  • LocationVihti, Finland

Posted 02 September 2011 - 04:59 AM

Great stuff Soma, I will update my code once I get home.




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users