Multiple File Uploads with XHR and PHP


So the jQuery / Flash multiple file uploader has not really been working when it comes to heavy duty stuff “Flash player has crashed” is a common scenario after some six < 2MB pictures, problem is, it needs to be able to handle up to 50 of them. Therefore I decided to check out the HTML5 alternatives and eventually found a really good one. I did have to make some modifications however, to make the solution fit with my own scenario and I detail them below.

First of all, we now use stream_copy_to_stream to upload the files, hence such things as max file upload size and so on will not be respected. Luckily Valums’ solution will do that for you, unluckily for me though I needed this stuff to be turned off in this case as only trusted people can upload stuff. Therefore I return right away in checkServerSettings() (qqfileupload.php), and set $this->ext = $ext in handleUpload() (more on the $this->ext part below).

I also changed the wording of the upload button in fileuploader.js to reflect the fact that we’re dealing with multiple files.

Below is the revamped code that deals with the image uploads and watermarking:

function uploadImages(){
	$gallery = $this->loadObject("SELECT * FROM jos_igallery WHERE id = {$this->getArr['gallery_id']}");
	
	$filename = uniqid();
	$big_folder = "images/stories/igallery/{$gallery->folder}/large/";
	$thumb_folder = "images/stories/igallery/{$gallery->folder}/thumbs/";
	
	chmod($big_folder, 0777);
	chmod($thumb_folder, 0777);
	
	$allowedExtensions = array('jpg', 'png', 'jpeg', 'JPG');
	
	$uploader = new qqFileUploader($allowedExtensions, 90485760);
	$result = $uploader->handleUpload($big_folder, $filename);
			
	$thumb_path = $thumb_folder."$filename.".$uploader->ext;
	$big_path = $big_folder."$filename.".$uploader->ext;
	
	chmod($big_path, 0777);
	
	if($result['success'] && copy($big_path, $thumb_path)){
		chmod($thumb_path, 0777);
		$big_width 						= $gallery->max_width < 600 ? 600 : $gallery->max_width;
		$big_height 					= $gallery->max_height < 400 ? 400 : $gallery->max_height;
		list($big_width, $big_height) 	= Common::constrainImage($big_path, $big_width, $big_height);
		$watermark_name 				= $big_height > $big_width ? 'logo_small' : 'logo';
		Common::resizeDiscardAspect($big_path, $big_width, $big_height);
		Common::watermark("images/$watermark_name.png", $big_path);
		Common::reScaleImage($thumb_path, $gallery->thumb_width, $gallery->thumb_height);
		$obj 				= new stdClass();
		$obj->gallery_id 	= $gallery->id;
		$obj->filename 		= $filename.".".$uploader->ext;
		$obj->published 	= 1;
		$this->insertObject('jos_igallery_img', $obj);
	}
	
	echo htmlspecialchars(json_encode($result), ENT_NOQUOTES);
}

Note how we make use of the $this->ext variable in the form of $uploader->ext above.

As opposed to the old Flash based uploader the above worked like a charm when I uploaded 12 really big images.


Related Posts

Tags: , ,