Created
July 28, 2013 10:29
-
-
Save iegik/6098162 to your computer and use it in GitHub Desktop.
Both: drag-n-drop and old-style upload form.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| "use strict"; | |
| /*\ | |
| |*| | |
| |*| :: XMLHttpRequest.prototype.sendAsBinary() Polifyll :: | |
| |*| | |
| |*| https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#sendAsBinary() | |
| \*/ | |
| if (!XMLHttpRequest.prototype.sendAsBinary) { | |
| XMLHttpRequest.prototype.sendAsBinary = function (sData) { | |
| var nBytes = sData.length, ui8Data = new Uint8Array(nBytes); | |
| for (var nIdx = 0; nIdx < nBytes; nIdx++) { | |
| ui8Data[nIdx] = sData.charCodeAt(nIdx) & 0xff; | |
| } | |
| /* send as ArrayBufferView...: */ | |
| this.send(ui8Data); | |
| /* ...or as ArrayBuffer (legacy)...: this.send(ui8Data.buffer); */ | |
| }; | |
| } | |
| /*\ | |
| |*| | |
| |*| :: AJAX Form Submit Framework :: | |
| |*| | |
| |*| https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest | |
| |*| | |
| |*| This framework is released under the GNU Public License, version 3 or later. | |
| |*| http://www.gnu.org/licenses/gpl-3.0-standalone.html | |
| |*| | |
| |*| Syntax: | |
| |*| | |
| |*| AJAXSubmit(HTMLFormElement); | |
| \*/ | |
| var AJAXSubmit = (function () { | |
| function ajaxSuccess (evn) { | |
| console.log(evn.target.responseText); | |
| //alert(this.responseText); | |
| /* you can get the serialized data through the "submittedData" custom property: */ | |
| /* alert(JSON.stringify(this.submittedData)); */ | |
| } | |
| function submitData (oData) { | |
| /* the AJAX request... */ | |
| var oAjaxReq = new XMLHttpRequest(); | |
| oAjaxReq.submittedData = oData; | |
| oAjaxReq.onload = ajaxSuccess; | |
| if (oData.technique === 0) { | |
| /* method is GET */ | |
| oAjaxReq.open("get", oData.receiver.replace(/(?:\?.*)?$/, oData.segments.length > 0 ? "?" + oData.segments.join("&") : ""), true); | |
| oAjaxReq.send(null); | |
| } else { | |
| /* method is POST */ | |
| oAjaxReq.open("post", oData.receiver, true); | |
| if (oData.technique === 3) { | |
| /* enctype is multipart/form-data */ | |
| var sBoundary = "---------------------------" + Date.now().toString(16); | |
| oAjaxReq.setRequestHeader("Content-Type", "multipart\/form-data; boundary=" + sBoundary); | |
| oAjaxReq.sendAsBinary("--" + sBoundary + "\r\n" + oData.segments.join("--" + sBoundary + "\r\n") + "--" + sBoundary + "--\r\n"); | |
| } else { | |
| /* enctype is application/x-www-form-urlencoded or text/plain */ | |
| oAjaxReq.setRequestHeader("Content-Type", oData.contentType); | |
| oAjaxReq.send(oData.segments.join(oData.technique === 2 ? "\r\n" : "&")); | |
| } | |
| } | |
| return oAjaxReq; | |
| } | |
| function processStatus (oData) { | |
| if (oData.status > 0) { return false; } | |
| /* the form is now totally serialized! do something before sending it to the server... */ | |
| /* doSomething(oData); */ | |
| /* console.log("AJAXSubmit - The form is now serialized. Submitting..."); */ | |
| return submitData (oData); | |
| } | |
| function pushSegment (oFREvt) { | |
| this.owner.segments[this.segmentIdx] += oFREvt.target.result + "\r\n"; | |
| this.owner.status--; | |
| processStatus(this.owner); | |
| } | |
| function plainEscape (sText) { | |
| /* how should I treat a text/plain form encoding? what characters are not allowed? this is what I suppose...: */ | |
| /* "4\3\7 - Einstein said E=mc2" ----> "4\\3\\7\ -\ Einstein\ said\ E\=mc2" */ | |
| return sText.replace(/[\s\=\\]/g, "\\$&"); | |
| } | |
| function SubmitRequest (oTarget) { | |
| var nFile, sFieldType, oField, oSegmReq, oFile, bIsPost = oTarget.method.toLowerCase() === "post"; | |
| /* console.log("AJAXSubmit - Serializing form..."); */ | |
| this.contentType = bIsPost && oTarget.enctype ? oTarget.enctype : "application\/x-www-form-urlencoded"; | |
| this.technique = bIsPost ? this.contentType === "multipart\/form-data" ? 3 : this.contentType === "text\/plain" ? 2 : 1 : 0; | |
| this.receiver = oTarget.action; | |
| this.status = 0; | |
| this.segments = []; | |
| var fFilter = this.technique === 2 ? plainEscape : escape; | |
| for (var nItem = 0; nItem < oTarget.elements.length; nItem++) { | |
| oField = oTarget.elements[nItem]; | |
| if (!oField.hasAttribute("name")) { continue; } | |
| sFieldType = oField.nodeName.toUpperCase() === "INPUT" ? oField.getAttribute("type").toUpperCase() : "TEXT"; | |
| if (sFieldType === "FILE" && oField.files.length > 0) { | |
| if (this.technique === 3) { | |
| /* enctype is multipart/form-data */ | |
| for (nFile = 0; nFile < oField.files.length; nFile++) { | |
| oFile = oField.files[nFile]; | |
| oSegmReq = new FileReader(); | |
| /* (custom properties:) */ | |
| oSegmReq.segmentIdx = this.segments.length; | |
| oSegmReq.owner = this; | |
| /* (end of custom properties) */ | |
| oSegmReq.onload = pushSegment; | |
| this.segments.push("Content-Disposition: form-data; name=\"" + oField.name + "\"; filename=\""+ oFile.name + "\"\r\nContent-Type: " + oFile.type + "\r\n\r\n"); | |
| this.status++; | |
| oSegmReq.readAsBinaryString(oFile); | |
| } | |
| } else { | |
| /* enctype is application/x-www-form-urlencoded or text/plain or method is GET: files will not be sent! */ | |
| for (nFile = 0; nFile < oField.files.length; this.segments.push(fFilter(oField.name) + "=" + fFilter(oField.files[nFile++].name))); | |
| } | |
| } else if ((sFieldType !== "RADIO" && sFieldType !== "CHECKBOX") || oField.checked) { | |
| /* field type is not FILE or is FILE but is empty */ | |
| !(oField.value || oField.defaultValue)||this.segments.push( | |
| this.technique === 3 ? /* enctype is multipart/form-data */ | |
| "Content-Disposition: form-data; name=\"" + oField.name + "\"\r\n\r\n" + (oField.value || oField.defaultValue) + "\r\n" | |
| : /* enctype is application/x-www-form-urlencoded or text/plain or method is GET */ | |
| fFilter(oField.name) + "=" + fFilter(oField.value) | |
| ); | |
| } | |
| console.log([oField,this.segments]); | |
| } | |
| return processStatus(this); | |
| } | |
| return function (oFormElement) { | |
| if (!oFormElement.action) { return; } | |
| return new SubmitRequest(oFormElement); | |
| }; | |
| })(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| class upload | |
| { | |
| var $directory_name; | |
| var $max_filesize = 2000000; | |
| var $error; | |
| var $mimetypes = array('image/cgm','image/example','image/fits','image/g3fax','image/gif','image/ief','image/jp2','image/jpeg','image/jpm','image/jpx','image/ktx','image/naplps','image/png','image/prs.btif','image/prs.pti','image/pwg-raster','image/svg+xml','image/t38','image/tiff','image/tiff-fx','image/vnd.adobe.photoshop','image/vnd.airzip.accelerator.azv','image/vnd.cns.inf2','image/vnd.dece.graphic','image/vnd.djvu','image/vnd.dwg','image/vnd.dxf','image/vnd.dvb.subtitle','image/vnd.fastbidsheet','image/vnd.fpx','image/vnd.fst','image/vnd.fujixerox.edmics-mmr','image/vnd.fujixerox.edmics-rlc','image/vnd.globalgraphics.pgb','image/vnd.microsoft.icon','image/vnd.mix','image/vnd.ms-modi','image/vnd.net-fpx','image/vnd.radiance','image/vnd.sealed.png','image/vnd.sealedmedia.softseal.gif','image/vnd.sealedmedia.softseal.jpg','image/vnd.svf','image/vnd.wap.wbmp','image/vnd.xiff'); | |
| var $user_tmp_name; | |
| var $user_file_name; | |
| var $user_file_size; | |
| var $user_file_type; | |
| var $user_full_name; | |
| function set_directory($dir_name =".") | |
| { | |
| $this->directory_name = $dir_name; | |
| } | |
| function set_max_size($max_file = 0) | |
| { | |
| $this->max_filesize = $max_file; | |
| //return $this->max_filesize; | |
| } | |
| function error() | |
| { | |
| return $this->error; | |
| } | |
| function is_ok() | |
| { | |
| if(isset($this->error)) | |
| return FALSE; | |
| else | |
| return TRUE; | |
| } | |
| function set_tmp_name($temp_name) | |
| { | |
| $this->user_tmp_name = $temp_name; | |
| } | |
| function set_file_size($file_size) | |
| { | |
| $this->user_file_size = $file_size; | |
| } | |
| function set_file_type($file_type) | |
| { | |
| $this->user_file_type = $file_type; | |
| } | |
| function set_file_name($file) | |
| { | |
| $this->user_file_name = $file; | |
| $this->user_full_name = $this->directory_name.DIRECTORY_SEPARATOR.$this->user_file_name; | |
| } | |
| function start_copy() | |
| { | |
| if(!isset($this->user_file_name)) | |
| $this->error = "You must define filename!"; | |
| if ($this->user_file_size <= 0) | |
| $this->error = 'File size error (0):' . $this->user_file_size . 'KB <br/>'; | |
| if ($this->user_file_size > $this->max_filesize) | |
| $this->error = 'File size error (1):' . $this->user_file_size . '/'.$this->max_filesize.'KB<br>'; | |
| if(@$mimetypes[$this->user_file_type]) | |
| $this->error = "File type error (2)"; | |
| $filename = basename($this->user_file_name); | |
| if (!empty($this->directory_name)) | |
| $destination = $this->user_full_name; | |
| else | |
| $destination = $filename; | |
| if(file_exists($destination)) | |
| $this->error = "File already exists (3): ".$this->user_file_name; | |
| if (!isset($this->error)) | |
| { | |
| if(!is_uploaded_file($this->user_tmp_name)) | |
| $this->error = "File " . $this->user_tmp_name . " is not uploaded correctly."; | |
| if (!move_uploaded_file ($this->user_tmp_name,$destination)) | |
| $this->error = "Impossible to copy " . $this->user_file_name . " from your folder to destination directory."; | |
| } | |
| } | |
| } | |
| if (isset($_FILES['file'])) { | |
| $uploaded = new upload; | |
| //set Max Size | |
| $uploaded->set_max_size(350000); | |
| //Set Directory | |
| $uploaded->set_directory(getcwd().DIRECTORY_SEPARATOR.'uploads'.DIRECTORY_SEPARATOR.'images'); // TODO: Change structure of the dyrectory | |
| //Set Temp Name for upload. | |
| $uploaded->set_tmp_name($_FILES['file']['tmp_name']); | |
| //Set file size | |
| $uploaded->set_file_size($_FILES['file']['size']); | |
| //set file type | |
| $uploaded->set_file_type($_FILES['file']['type']); | |
| //set file name | |
| $uploaded->set_file_name($_FILES['file']['name']); | |
| //start copy process | |
| $uploaded->start_copy(); | |
| if($uploaded->is_ok()){ | |
| echo "Upload of ".$_FILES['file']['name']." is complete"; | |
| }else{ | |
| echo $uploaded->error(); | |
| } | |
| }elseif(isset($_POST['files'])){ | |
| echo '(['.JSON_encode(array( | |
| 'post' => $_POST, | |
| 'get' => $_GET, | |
| 'files' => $_FILES | |
| )).",\n"; | |
| // file_put_contents('img.png', base64_decode($base64string)); | |
| echo "{\n"; | |
| foreach ( $_POST['files'] as $name => $file ){ | |
| list($type, $data) = explode(';', $file); | |
| list(,$data) = explode(',', $data); | |
| list(,$type) = explode(':', $type); | |
| echo '"name":"'.$name.'",'."\n"; | |
| echo '"type":"'.$type.'",'."\n"; | |
| //echo '"data":"'.$data.'",'."\n"; | |
| $data = base64_decode($data); | |
| $basepath = getcwd().DIRECTORY_SEPARATOR.'uploads'.DIRECTORY_SEPARATOR.'images'; | |
| $fullpath = $basepath.DIRECTORY_SEPARATOR.$name; | |
| if(!file_exists($fullpath)) | |
| file_put_contents($fullpath, $data); | |
| else | |
| echo '"error":"File exists"'; | |
| } | |
| echo "}]);\n"; | |
| /* | |
| $data = 'data:image/png;base64,AAAFBfj42Pj4'; | |
| list($type, $data) = explode(';', $data); | |
| list(, $data) = explode(',', $data); | |
| $data = base64_decode($data); | |
| file_put_contents('/tmp/image.png', $data); | |
| */ | |
| }else{ | |
| ?><!DOCTYPE html> | |
| <html> | |
| <head> | |
| <meta charset="utf-8"> | |
| <title>Upload form</title> | |
| <style> | |
| html,body{ | |
| width:100%; | |
| height:100%; | |
| margin:0; | |
| padding:0; | |
| } | |
| #dropzone { | |
| width:100%; | |
| height: 100%; | |
| } | |
| #dropzone img{ | |
| width: 100px; | |
| vertical-align: middle; | |
| padding: .2em; | |
| border: gainsboro solid 1px; | |
| border-radius: .2em; | |
| box-shadow: .1em .1em .2em rgba(128,128,128,.5); | |
| margin: .2em; | |
| } | |
| #dropzone.hover { | |
| background-color: rgba(128,128,128,.1); | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <form id="dropzone" action="/upload.php" enctype="multipart/form-data" method="POST" onsubmit="javascript:AJAXSubmit(this); return false;"> | |
| <input type="file" multiple name="files[]"/> | |
| <input type="submit"/> | |
| <hr/> | |
| </form> | |
| <script src="upload.js"></script> | |
| <script> | |
| //var doc = document.documentElement; | |
| var doc = document.getElementById('dropzone'); | |
| doc.ondragover = function () { | |
| this.className = 'hover'; | |
| return false; | |
| }; | |
| doc.ondragend = | |
| //doc.ondragleave = | |
| function () { | |
| doc.className = ''; | |
| return false; | |
| }; | |
| doc.ondrop = function (event) { | |
| maxFileSize = 2048000; // 10MB | |
| event.preventDefault && event.preventDefault(); | |
| this.className = ''; | |
| [].forEach.call(event.dataTransfer.files,function(file,n){ | |
| if (file.size > maxFileSize) { | |
| alert('Файл '+file.name+' слишком большой!'); | |
| return false; | |
| } | |
| if (typeof FileReader !== "undefined" && (/image/i).test(file.type)) { | |
| reader = new FileReader(); | |
| reader.onload = (function (d,f) { | |
| return function (evt) { | |
| //console.log([d,f,this,evt,doc,img]); | |
| var img = document.createElement('img'); | |
| img.src = evt.target.result; | |
| img.alt = f.name; | |
| doc.appendChild(img); | |
| var input = document.createElement('input'); | |
| input.setAttribute('type','hidden'); | |
| //input.setAttribute('type','file'); | |
| input.setAttribute('data-size',f.size); | |
| input.setAttribute('data-lastModifiedDate',f.lastModifiedDate); | |
| input.setAttribute('data-webkitRelativePath',f.webkitRelativePath); | |
| //input.setAttribute('name','images['+(n+1)+']'); | |
| input.setAttribute('name','files['+f.name+']'); | |
| //input.setAttribute('value',f.name); | |
| input.setAttribute('value', evt.target.result); | |
| doc.appendChild(input); | |
| }; | |
| }(this,file)); | |
| reader.readAsDataURL(file); | |
| } | |
| }); | |
| }; | |
| </script> | |
| </body> | |
| </html> | |
| <?php } ?> |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Known issues: When drag'n'drop files - file names with non-ascii symbols will be corrupted, need to fix that.