Javascript, JQuery, PHP, Web Development

PHP Upload Progress bar V2

This now has a Github home: Here!!

Updated: The new update can now handle stopping uploads as well and extra validation and more robust scripting.

Some of you will notice a long time ago I wrote a post on creating a upload progress bar in PHP. Well I have finally got round to recreating this script and I can thankfully say it is a lot better than my old script. It is, in fact, so different I am going to start anew here and describe from the beginning how I did it.

Ok so here we are, first thing you need to do is install uploadprogress extension for PHP. To do this simply run this command:

pecl install uploadprogress

If console tells you that pecl is not a valid command or that you need phpiz; just enter this into it:

apt-get install php5-pear
apt-get install php5-dev

Afterwards open up your php.ini and at the end put:

extension=uploadprogress.so

And restart your server like so (for Apache):

sudo /etc/init.d/apache2 restart

You must restart your server, reloading will not work.

Beleive it or not but you now have PHP upload progress identification installed. Now you just need to make a script that will upload a file and display its progress. Shall we move on?

The javascript

This is the backbone to the entire script. It is what allows the front to join with the back.

var upload_timer;
var timeout = 5000;
var u_ids = [];

$(document).ready(function(){

	// Add a new upload form
	add_upload();

	// When the "Add new upload" link is clicked add a new upload form
	$('#add_upload_form').click(function(){ add_upload(); return false; });

});

/**
 * Stops an upload
 *
 * @param id
 */
function stop_upload(id){

	var answer = confirm("Are you sure you wish to remove this upload?"), p_id = "#up_prog"+id;

	// Only remove the upload if it has not completed.
	if (answer && ($(p_id+" .uploadProgInner").css("width") != "100%") && ($("#container_outer"+id).length > 0)){

		// Form ids and write the cancelling message
		var message_id = "#up_message_prog"+id;
		$(message_id).html("<b style='color:red;'>Cancelling...</b>");

		// Make the upload go away peacefully showing the user it has been cancelled.
		setTimeout(function(){
			$("#container_outer"+id).remove();
			u_ids.splice(u_ids.indexOf(id), 1);
		}, "2000");
	}else{
		if(($(id+" .uploadProgInner").css("width") == "100%") || ($("#container_outer"+id).length == 0)){
			$("#general_error").show();
			$("#general_error span").html("<h2>File Upload Could Not Be Removed</h2><p>The file upload could not be removed. This is most likely due to the file having had already been completed or already removed by some other means.</p>");
		}
	}
}

/**
 * This function runs when a upload is submitted. It checks the
 * file field as best it can for a valid file. TBH there are some things
 * we just have to do AFTER the file has been uploaded to /temp
 *
 * @param id
 * @returns {Boolean}
 */
function check_upload(id){
	var file = $("#"+id).val(), end = file.length, start = end - 5;

	var ext = file.substring(start, end);

	// Is the file a divx extension?
	if(ext == ".divx"){
		$("#uploadForm-outer"+id).hide();
		$("#up_prog"+id).show();
	}else{
		$("#general_error").show();
		$("#general_error span").html("<h2>Wrong File Type</h2><p>You attempted to upload a file type that is not supported by this uploader. Pleae try again soon, we hope to have support for mkv, avi and other formats in their raw form.</p>");
		return false;
	}
}

/**
 * This adds a new upload form to the screen
 */
function add_upload(){

	var ts, count;

	// We make a ts as a cache buster for shit browsers cough-Opera-cough
	ts = Math.round(new Date().getTime() / 1000);

	// How many forms already exist?
	count = $(".uploadFormContainer").length;

	// So long as limit has not been reached (10)
	if(count < 10){

		// Generate the form
		$.get("/upload/add", {ts: ts}, function(data){

			// Add to the page
			$("#uploadForm_container-outer").append(data);

			// If this is the first form then add the updater iframe
			if(count == 0 && $('#uInfo_ifr').length == 0){
				$("#u_iframe_container").html("<a href="/upload/getInfo">/upload/getInfo</a>");
			}

			// Add the upload id to the list of IDs
			var e = $(".uploadFormContainer").last().find("input[name=UPLOAD_IDENTIFIER]").val();
			count_ids = u_ids.length;
			u_ids[count_ids] = e;
		});

	}else{

		// Show upload limit error
		$("#general_error").show();
		$("#general_error span").html("<h2>Upload Limit Reached</h2><p>This form has been limited to 10 uploads to protected internet connections. If you are sure you understand what your ISP allows you to upload you can open a new window and continue uploading there.</p>");
	}
}

/**
 * This gets the updated status of the uploads
 *
 * @param info
 */
function update_progress(info){

	// Scrolls through the IDs assigning the information.
	for(i = 0; i < info.length; i++){

		// Sometimes uploadprogress can return null for a upload
		if(info[i] != null){

			// Calculate how much has been uploaded
			var done = Math.floor(100 * parseInt(info[i].uploaded) / parseInt(info[i].total));

			// Ascertain the IDs for the elements needing change
			var id = "#up_prog"+info[i].id;
			var message_id = "#up_message_prog"+info[i].id;

			// Change the width of the progress bar to match done and set a message for the upload status
			$(id+" .uploadProgInner").css("width", done+"%");
			$(message_id+" span").html(done+"% Completed of "+info[i].file+" - Estimated Time Left: "+info[i].left+" at "+info[i].speed+"ps");
		}
	}

}

The Upload Form

Now we have the Javascript we need the upload form itself. This form will be gotten everytime add_upload() is called within the Javascript whilst the user is under the upload limit:

		global $session;

		$u_id = strval(new MongoId());
		?>

		<div class="uploadFormContainer" id="container_outer<?php echo $u_id ?>">
			<div class="uploadForm" id="uploadForm-outer<?php echo $u_id ?>">

				<h2>Please select a file to upload</h2>

				<form onsubmit='check_upload("<?php echo $u_id ?>")' action="/upload/to_server" target="u_ifr<?php echo $u_id ?>" method="post" enctype="multipart/form-data">
					<input type="hidden" name="UPLOAD_IDENTIFIER" value="<?php echo $u_id ?>" />
					<input type="file" name="<?php echo $u_id ?>" id="<?php echo $u_id ?>"/>

					<input type="submit" value="Upload" class="uploadFormSubmit"/>
				</form>

				
			</div>

			<div class="uploadBar" id="up_prog<?php echo $u_id ?>">
				<div class="uploadProgOuter">
					<div class="uploadProgInner">&nbsp;</div>
				</div>
				<div class="up_message_prog" id="up_message_prog<?php echo $u_id ?>">
					<span>Connecting to server...</span><a href="javascript:;" class="cancel_uploadForm" onclick='stop_upload("<?php echo $u_id ?>")'><b>Cancel</b></a>
				</div>
				<div id="up_err<?php echo $u_id ?>">

				</div>
			</div>
		</div>
		<?php

The Updater page

Now we have a form up and running (I will let you decipher the form :P) we just need the progress update page:

		// A nice little hack for telling IE we wont abuse iframe permissions
		header('P3P: CP="CAO PSA OUR"');

		global $session;

		?>
		<html>
			<head>
				<title>Upload Info Page</title>

			    <script type="text/javascript">

			    	// Get the u_ids from the parent window
					var u_ids = parent.u_ids, id_url = "";

			    	// Run the initial function
					refreshiframe();

				    function refreshiframe(){

				    	// Get the url formatted version of u_ids (upload IDs)
				    	if(u_ids != null && u_ids.length > 0){
				    		for(i = 0; i<u_ids.length; i++){
				    			// return an url of the current id
				    			if(i == 0){
				    				id_url = id_url + "ids[]="+u_ids[i];
				    			}else{
				    				id_url = id_url + "&ids[]="+u_ids[i];
				    			}
				    		}
				    	}else{
					    	id_url = "ids[]=0";
				    	}

				    	// if php detects the set $_GET then delay the refresh else do it now
				    	<?php if(empty($_GET['ids']) && !isset($_GET['ids'])){ ?>
				    		redirect();
				    	<?php }else{ ?>
				    		setTimeout("redirect()",5000);
				    	<?php } ?>

				    }

				    function redirect(){
					    // redirect with full url encoded u_ids
				    	parent.uInfo_ifr.location.href="/upload/getInfo?"+id_url;
				    }
			    </script>

			</head>

			<body>
				<script type="text/javascript">

					var info = [];

					<?php for($i = 0; $i<count($_GET['ids']); $i++){

						$upload_id = $_GET['ids'][$i];

						// This is our magic function. It gets our upload information
						$info = uploadprogress_get_info($upload_id);

						// We format the data to be printed into JS JSON arrays and echo it to screen
						if(!empty($info) && $info){ ?>
							info[<?php echo $i ?>] = {'id':'<?php echo $upload_id ?>', 'file':'<?php echo $info['filename'] ?>', 'uploaded':<?php echo $info['bytes_uploaded'] ?>, 'total':<?php echo $info['bytes_total'] ?>, 'left':'<?php echo gmdate("H:i:s", $info['est_sec']) ?>', 'speed':'<?php echo convert_size_human($info['speed_average']) ?>'};
						<?php }else{ ?>
							info[<?php echo $i ?>] = null;
						<?php } ?>

					<?php } ?>

					// Now lets update the upload progress
					parent.update_progress(info);

				</script>
			</body>
		</html>
		<?php

The Page

Now we need the other page this all goes into:

<div class="UIMessage error UIMessageConstrained UIUploadErrorMessage" id="general_error">
	<span></span>
</div>

<div class="upload_container">

<div id="uploadForm_container-outer"></div>

<div id="u_iframe_container" class="u_iframe_container"></div>

<a href="" id="add_upload_form">Add new upload</a>

</div>

Beleive it or not but that is it! You now know how to make a progress bar in PHP. Rmember this isn’t flash nor is it HTML 5 it will work on any browser with almost any settings so long as they don’t have JS turned off :P. All you need to do now is style it. Here is my style sheet to get you started:

.upload_container{
	width:600px;
	margin:auto;
}

.uploadFormContainer{
	padding:10px;
	border:1px solid #C9D7F1;
	margin-bottom:10px;
}

.uploadForm{
	border:1px solid #E1ECFE;
	background:none repeat scroll 0 0 #F0F6FF;
	padding:10px;
}

.uploadForm h2{
	margin-bottom:10px;
}

.uploadFormSubmit{
	float:right;
	font-weight:bold;
}

.uploadBar{
	display:none;
}

.uploadProgOuter{
	background:white;
	height:40px;
	padding:2px;
	border:1px solid #73A6FF;
}

.uploadProgInner{
	background:#73A6FF;
	width:10%;
	height:40px;
}

.up_message_prog{
	margin-top:7px;
}

.u_iframe_container{
	display:none;
}

.UIUploadErrorMessage{
	display:none;
	margin: 15px auto;
}

This style produces this result (or close anyway):

Any questions? If so just write a comment otherwise enjoy :).

PHP

PHP File Upload without Refresh (AJAX emulator)

I have created this tutorial as a mid-way between my Simple PHP Upload post and the Multiple Files with Progress Bar Upload post. This is designed to give all visitors of my site a chance to understand the more complex version.

Ok, we are building upon the material described within a previous post. The previous post is basically simple uploader and what I am going to explain here is how to up the coding so that the page does not need to refresh in order to upload the file.

All I did was rewrite the HTML to look more like:

<html>
<head>
<title>Upload Dat File!!</title>
</head>

<form action="upload.php" method="post" target="uploadFrame" enctype="multipart/form-data">

<input type="file" name="userfile" size="30"/>
<input type="submit" value=" Upload ">

</form>

<iframe name="uploadFrame" style="display:none;"></iframe>
</html>

So this HTML shows a new iframe named uploadFrame and the form target pointing to this iframe. The reason why this form will not need to refresh is because you are in fact making the form point to the iframe, meaning the upload will take place in the iframe now instead of on a new page; kool, huh?

So as the file uploads it sends all data to the iframe which then opens upload.php and runs the script we had before. That means that uploading without refresh is now covered, enjoy 🙂

MySQL, PHP

File Upload in PHP with Progress Bar

Even bigger note: This page is outdated See here for an updated version

Note: The bugs within this post have been fixed, however, this article is still old I will be updating with the fixed and perfect version as soon as I get my server running correctly again.

I see a lot of web developers asking the same question, “How do you make a PHP AJAX style file upload script with a progress bar?”. In the old days of PHP progress bars used to be unthinkable, the very thought of having a user friendly uploading interface seemed to scare PHP programmers. That is not the case any more! With being able to add a class that attaches to the lately concieved file upload progress hooks the uploadprogress class sure packs a punch for easy progress bar making.

Tutorial Note:

This tutorial was completed under Ubuntu 9.04 and likewise reflects Linux processes. If you wish for a Windows version I will do one.

I would recommend this tutorial only for advanced web developers. For new people it would be best to chew into something that won’t cause a chronic headache.

Bug #00: File upload progress for new files halts all previous upload progress bars despite the fact they are not completed. (being resolved now)

Introduction

This tutorial will show the user how to create an upload script very much like the new one found on YouTube (still in Beta I believe, so not instantly accessible). This tutorial was taken from a few websites I found. I have combined the knowledge with some of my own. This is going to look really messy at first but towards the end we will build it all into a script like the new upload script for YouTube and might have better validation than theirs as well.

I will begin with stating the websites/articles that helped me produce this upload script. These links are essential reading if you wish to succeed in this area:

1. JQuery CSS Documentation (Random but true)

2. pecl page for uploadprogress extension (required to understand so get reading :P)

3. Tips for Twits. A very nice tutorial for anyone who’s not a noob but not as good as the rest

4. Moki Systems. Another AJAX upload tutorial people will find useful.

5. Ajax F1. Another Ajax upload tutorial you should take a look at.

Prologue

The very first thing I did was to set-up my server. I have broken these down into easy steps:

1. install your LAMP server. This is covered in earlier posts.

2. Use the following command within terminal. This command will give you the extension which allows for php to monitor the progress of file uploads. The extension is called uploadprogress:

Sudo pecl install uploadprogress

Tutorial Note:

  • It might tell you that you need Phpiz or something. Just type in terminal “sudo apt-get install php5-dev”. If you do not use sudo (root) then you will not have permission to install.
  • Further edit: There are times when the computer might say you don’t have pecl installed. I will add solutions in a while since I also had that problem but forgot how I fixed it now.

3. After having installed the extension add it to the php.ini by entering into terminal:

sudo gedit /etc/php5/apache2/php.ini

and at the bottom adding:

extension=uploadprogress.so

After this you will need to restart Apache so key in terminal:

sudo /etc/init.d/apache2 restart

4. Now for the final part; installing JQuery. If you have never heard of JQuery before I strongly suggest you update yourself because you haven’t in the last 3 years. JQuery allows you to do many things but most commonly access quick JSON, AJAX and special effects for pages to make them more user friendly to the end-user.

It just so happens Tips for Twits has a nice download link for what we need right here. Once this has been downloaded I strongly recommend you only extract jquery.js to a folder within your website root directory called “js”.

And viola, it’s all set-up :).

The Dirty Part

Ok, we have the environment set-up. The original version of this tutorial used the Tip for Twits tutorial. When I actually tried to use the tutorial code it did not function all that well and kept freezing the browser periodically so I created my own from a base provided by the makers of the uploadprogress extension to PHP. There are three files involved within the script (not including user management etc, only the upload script):

  • videoUploadMain.htm (videoUpload.php as well if you are like me and use a template framework such as Smarty)
  • server.php
  • info.php
  • jxSV_VID.php
  • uploadIDMake.php

Now I should explain how each of them work and how it all comes together, it is rather confusing however. The main page that contains all the working and the form is videoUploadMain.htm/php. From this the info and server pages uses PHP echo’s in order to send Javascript messages back to the main page when they are called, it’s rather ingenious coding really gets around the need for AJAX. This makes the page much faster and no longer freezes for brief periods whilst uploading.

So hopefully I have explained that ok but most likely not. The main page calls the info.php for upload progress and the info.php responds by sending a Javascript call via an iframe which is then enacted within the main page to update the progress bar. After the upload is completed the form then feeds server.php through an iframe which then can bounce back a Javascript call to the main page meaning that you could do everything needed without ever needing to refresh the page or redirect. The two extra pages jxSV_VID.php and uploadIDMake.php allow for a new upload ID to be made (uploadIDMake.php) and for the video file details to be saved via AJAX post (jxSV_VID.php)

Ok, so I begin with the front end and specifically the HTML. Below you will see the html to the actual upload page itself:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style type="text/css">
@import url("styles/default/css/stylesheet.css");
@import url("../css/stylesheet.css"); /*CSS Imports*/

</style>
<script src="js/jquery.js"></script>
<script src="jquery.form.js"></script>
  
  {literal}
 
<script type="text/javascript">


//AJAX to add video file details
function AddDetails(uploadID){

	//gets the needed details about the video file from the form inputs
 	var title = "input#title"+uploadID;
 	var desc = "#description"+uploadID;
 	var tags = "input#tags"+uploadID;
 	var rate = "#rate"+uploadID;
 	var rate1 = "#rate1"+uploadID;
 	var sex = "#SEXOPT"+uploadID;
 	var upIDFirst = "input#uploadTI"+uploadID;

 	var titleFin = $(title).val();
 	var descFin = $(desc).val();
 	var tagsFin = $(tags).val();
 	
 	var upID = $(upIDFirst).val();

 	//this uses the check attribute on option boxes and check boxes to detect whether they are checked or not. This is the only (decent) way to do this in JQuery.
 	if($(sex).is(":checked")){
 		var sexFin = $(sex).val();
 	}else{
 	 	var sexFin = "";
 	}

 	if($(rate).is(":checked")){
 		var rateFin = $(rate).val();
 	}else{
		rateFin = "";
 	}

 	if($(rate1).is(":checked")){
 		var rate1Fin = $(rate1).val();
 	}else{
		rate1Fin = "";
 	}

 	//Build the string for use with AJAX
	  var dataString = 'title='+ titleFin + '&amp;amp;amp;amp;amp;description=' + descFin + '&amp;amp;amp;amp;amp;tags=' + tagsFin + '&amp;amp;amp;amp;amp;rate=' + rateFin + '&amp;amp;amp;amp;amp;rate1=' + rate1Fin + '&amp;amp;amp;amp;amp;Nud=' + sexFin + '&amp;amp;amp;amp;amp;id=' + uploadID + '&amp;amp;amp;amp;amp;upID=' + upID;
	  alert (dataString);
	  $.ajax({
		  //Post the formed AJAX string to jxSV_VID.php
	    type: "POST",
	    url: "jxSV_VID.php",
	    data: dataString,
	    success: function(msg) {
		    if(!msg) return;

		    var response;
		    eval("response = "+msg);
			
		    if(!response) return;

		    //Judge whether to respond with error or success. This is determined from a JSON string formed within the PHP file.
		    var DivInQ = "#eC_Err"+uploadID;
			var Error = parseInt(response['ErrorCode']);
			
			if(Error == 0){
				$(DivInQ).css({"display" : "block", "color" : "green", "text-align" : "center"});
		    	$(DivInQ).html("<span><b>Success:</b> "+response['Message']+"</span>");
			}else{
				$(DivInQ).css({"display" : "block", "color" : "red", "text-align" : "center"});
		    	$(DivInQ).html("<span><b>Error:</b> "+response['Message']+"</span>");
			}
	  	}
	  });
}

//Add our new upload
function addElement() {
	//determine if user has already made 5 uploads using the numi control
	var numi = document.getElementById('UploadTotal');
	numofupload = numi.value;
	if(numofupload>3){
		ShowMaxUpPanel();
	}else{
		$.ajax({
			//AJAX post to uploadIDMake.php to get the new upload id
		   type: "POST",
		   url: "uploadIDMake.php",
		   data: "",
		   success: function(msg){

			//Add our new upload
				   
			   var ni = document.getElementById('addFFRM');
			   var num = (document.getElementById('UploadTotal').value -1)+ 2;
					  
			   numi.value = num;
			   UID = msg;
					  
			   var newdiv = document.createElement('div');
			   var divIdName = UID;
					  
			   newdiv.setAttribute('id',divIdName);
			   newdiv.innerHTML = "<div id='upload_frmCon"+UID+"' style='margin:10px; border:1px solid #363636; background:#131313; padding:7px; padding-top:15px;'>"+
			   						"<form onsubmit='UP.start(\""+UID+"\")' target='ifr2" + UID + "' action='server.php?id="+UID+"' enctype='multipart/form-data' method='post'>"+
			   							"<input type='hidden' name='UPLOAD_IDENTIFIER' value='"+UID+"' /><span class='non-pText' style='font-weight:bold; font-size:15px;'>Select a video to upload</span>"+
			   							"<div style='padding-top:5px; padding-bottom:2px;'><input type='file' name='"+UID+"' size='30'/><input type='submit' value='Upload File' class='button7' style='right:0; margin-left:220px; margin-right:0;' />"+
			   							"</div>"+
			   						 "</form>"+
			   						 "<iframe id='ifr"+UID+"' src='info.php?ID="+UID+"' style='display:none;' name='ifr"+UID+"'></iframe>"+
			   						 "<iframe name='ifr2"+UID+"' style='display:none;' id='ifr2"+UID+"'></iframe>"+
			   					  "</div><div id='upload_prog"+UID+"' style='margin:10px; border:1px solid #363636; background:#131313; padding:7px; padding-top:15px; display:none;'>"+
								 	 "<span id='uploadTitle"+UID+"' class='non-pText' style='font-weight:bold; font-size:15px;'>Your video is being uploaded</span>"+
			   					  		"<div id='progressuploadouter"+UID+"' style='margin-top:5px; background:#000; border:1px solid #363636; padding:2px;'>"+
			   					  			"<div id='progressUpload"+UID+"' style='width:10%; background:url(styles/default/images/progressback.png); height:30px;'></div>"+
			   					  		"</div>"+
				   					  	"<div id='status"+UID+"' style='color:white; padding:3px;'>Connecting to Server...</div>"+
				   				  
				   				  "<div id='pst_UPActs"+UID+"' style='display:none; margin-top:5px;'>"+
				   				  	"<div align='right'>"+
				   				  		"<span class='non-pText'>"+
				   				  			"<a id='hypforenterdetails"+UID+"' class='normalHyp' href='javascript:Ent_UPDetails(\""+UID+"\");' style='cursor:pointer;'>You can add details about this video now</a> or </span>"+
				   				  			"<input type='submit' id='Cont_Profile' onclick='javascript:ShowExitConfirmPanel();' class='button7' value='Continue To Your Profile'/>"+
				   				  	"</div>"+
						   			"<div style='display:none; margin-top:5px;' id='entUpDetails"+UID+"'>"+
						   				"<div align='center'>"+
						   					"<div style='margin-left:5px; margin-right:5px;'>"+
					   							"<div style='text-align:left; background:url(styles/default/images/speachtop.png); height:10px;'>"+
				   								"</div>"+
			   									"<div style='text-align:left; background:black; border-bottom:1px solid #363636; border-left:1px solid #363636; border-right:1px solid #363636;'>"+
													 "<div style='padding:5px;'>"+
														 "<form id='adddetails'>"+
														 	"<div style='width:100%; padding:5px;'>"+
														 		"<span class='non-pText' style='font-size:15px;'>Video File Details</span>"+
														 		"<a href='javascript:Ent_UPDetails(\""+UID+"\");' class='normalHyp' style='border:0; margin-left:36em;'>Close X</a>"+
														 	"</div>"+
														 	"<div id='eC_Err"+UID+"' style='display:none;'>"+
														 	"</div>"+
														 	"<div style='width:100%;'>"+
															 	"<div id='detailsUploadCon'>"+
															 		"<div id='detailsUploadLeft'>"+
													                    "<fieldset class='fields6'>"+
														                    "<input type='hidden' name='uploadTI"+UID+"' id='uploadTI"+UID+"' value=''>"+ 
													                        "<dl>"+
													                        	"<dt style=''><label for='vidtitle'>Title:</label></dt>"+
													                        	"<dd style=''><input class='inputbox' type='text' id='title"+UID+"' name='title"+UID+"' style='width:100%;'/></dd>"+
													                        	"<dt><label for='videsc'>Description:</label></dt>"+
													                        	"<dd><textarea name='description"+UID+"' id='description"+UID+"' class='textarea' rows='10' cols='30'></textarea></dd>"+
													                        	"<dt style=''><label for='vidtags'>Tags:</label></dt>"+
													                        	"<dd style=''><input class='inputbox' type='text' id='tags"+UID+"' name='tags"+UID+"' style='width:100%;'/></dd>"+
													                        	"<dt></dt>"+
													                        	'<dd>Up to five tags seperated by a comma ",".</dd>'+
													                        "</dl>"+
													                    "</fieldset>"+
															 		"</div>"+
															 		"<div id='detailsUploadRight'>"+
													                    "<fieldset class='fields6'>"+
										                                    "<dl class='fields6' style='padding-left:10px;'>"+
										                                        "<dt id='dtradio' style='width:2em; text-align:left; color:white;'><input type='radio' id='rate"+UID+"' name='rate"+UID+"' value='0'/></dt>"+
										                                        "<dd id='dtradio' style='margin-left:2em; color:white;'><label>Video is appropiate for everyone</label></dd>"+
										                                        "<dt id='dtradio' style='width:2em; text-align:left; color:white;'><input type='radio' id='rate1"+UID+"' name='rate1"+UID+"' value='1'/></dt>"+
										                                        "<dd id='dtradio' style='margin-left:2em; color:white;'><label>Video is NOT appropiate for children</label></dd>"+
										                                        "<dl>"+
											                                        "<dt style='width:2em; text-align:left;'><input type='checkbox' id='SEXOPT"+UID+"' name='SEXOPT"+UID+"' value='1'></dt>"+ 
											                                        "<dd style='margin-left:2em;'>This video contains nudity and/or sexual situations</dd>"+
										                                        "</dl>"+
										                                        "<dt style='width:2em; text-align:left;'></dt>"+
										                                        "<dd style='margin-left:2em;'>Inappropiately marking content for everyone when it is not may ensure your account is subject to deletion</dd>"+
										                                    "</dl>"+
													                    "</fieldset>"+
															 		"</div>"+
															 	"</div>"+
														 	"</div>"+
														 "</form>"+
												 	"</div>"+
												 	"<div style='background:#131313; border-top:1px solid #363636; padding:5px; padding-top:7px; color:#fff; text-align:right;'>"+
												 		"<input type='submit' onclick='javascript:AddDetails(\""+UID+"\");' class='button7' value='Save Video Details' style='margin-right:1em;'/>"+
												 	"</div>"+
			   									"</div>"+
			   								"</div>"+
			   							"</div>"+
			   						"</div>"+
			   					"</div>"+
			   				"</div>";
			   ni.appendChild(newdiv);
		   }
		});	
	}
}

//retry uplod
function tryAgain(uploadID){

	//hides the upload progress and reshows the upload form
	prog = "upload_prog"+uploadID;
	upload = "upload_frmCon"+uploadID;
	
	document.getElementById(prog).style.display = "none";
	document.getElementById(upload).style.display = "block";
}

//this function still does not work, I am working on it. It works if you wanna stop the whole window but not a single form
function Abort(uploadID){
	//Needs to be redone. This will not work for multiple uploads
	if(navigator.appName == "Microsoft Internet Explorer"){
		UP.stop(true, 1);
		window.document.execCommand('Stop');
	}else{
		UP.stop(true, 1);
		window.stop();
	}	
}

//function to use JQuery to produce an effect when showing the enter video details form
function Ent_UPDetails(uploadID){
	var detailsDiv = "#entUpDetails"+uploadID;
	
	if ( $(detailsDiv).is(':hidden') ) {
		$(detailsDiv).slideDown("slow"); 
	}else{
		$(detailsDiv).slideUp("slow");  
	}	
}

//function to show an exit confirm message so the user has to confirm they wish to leave the upload page
function ShowExitConfirmPanel(){

	document.getElementById("darkBackgroundLayer").style.display = "block";
	document.getElementById("exitConfirm_D").style.display = "block";
	
	var newsletter_panel = document.getElementById("exitConfirm_D");
	
	w = 700;
	h = 346;
	
	xc = Math.round((document.body.clientWidth/2)-(w/2));
	yc = Math.round((document.body.clientHeight/2)-(h/2));
	
	var height = yc.toString();
	var temp = height.split("-");
	
	newsletter_panel.style.left = xc + "px";
	newsletter_panel.style.top = "10" + "em";

}

//error panel that tells the user they have reached the maximum uploads at that time
function ShowMaxUpPanel(){

	document.getElementById("darkBackgroundLayer").style.display = "block";
	document.getElementById("Max_UP_S").style.display = "block";
	
	var newsletter_panel = document.getElementById("Max_UP_S");
	
	w = 700;
	h = 346;
	
	xc = Math.round((document.body.clientWidth/2)-(w/2));
	yc = Math.round((document.body.clientHeight/2)-(h/2));
	
	var height = yc.toString();
	var temp = height.split("-");
	
	newsletter_panel.style.left = xc + "px";
	newsletter_panel.style.top = "10" + "em";

}

$(document).ready(function(){
	//continue to profile button
	$("#Cont_Profile").click(function(){
		ShowExitConfirmPanel();
	});

	//return to uploads button in the exit confirmation message
	$("#N_RtnUP").click(function(){
		document.getElementById("darkBackgroundLayer").style.display = "none";
		document.getElementById("exitConfirm_D").style.display = "none";		

	});

	//ok button to say the user understands they hagve reached their max uploads
	$("#UP_MAX_OK").click(function(){
		document.getElementById("darkBackgroundLayer").style.display = "none";
		document.getElementById("Max_UP_S").style.display = "none";		

	});	
});
	
function showUpload(uploadID){
	//stops showing the upload form and shows the upload progress bar.
	var uploadmain = "upload_frmCon"+uploadID;
	var progress = "upload_prog"+uploadID;
	
	document.getElementById(uploadmain).style.display = "none";
	document.getElementById(progress).style.display = "block";
	document.getElementById("add_UP").style.display = "block";
}


//this is where all the magic happens. This function does all the uploading
var UP = function() {
    
    /* private variables */
    
    var ifr = null;
    
    var startTime = null;
    var upload_max_filesize = {/literal}{$uploadmax}{literal};
    
    var infoUpdated = 0;

    //write the upload status whether progess or error message
    var writeStatus = function(text,color, uploadID) {
        var stat = "status"+uploadID;
        var title = "uploadTitle"+uploadID;
        
        var statDiv = document.getElementById(stat);
        var titleDiv = document.getElementById(title);
        
        statDiv.style.color = "white";
        titleDiv.innerHTML = "Your video is being uploaded";
        
        if(color == 3){
            titleDiv.innerHTML = "An error has occured";
            statDiv.style.color = "red";
			//statDiv.style.background = "#fbda54";
			//statDiv.style.border = "1px solid #f6cc24";
        }
        statDiv.innerHTML = text;
    }

    //function and tasks to do after successful completion of the upload
    var completeUpload = function(uploadID, UPID){
        progessupload = "progressUpload"+uploadID;
        stat = "status"+uploadID;
        postupac = "pst_UPActs"+uploadID;
        var title = "uploadTitle"+uploadID;
        var titleDiv = document.getElementById(title);

        titleDiv.innerHTML = "Your video has been uploaded";
    	document.getElementById(progessupload).style.width = "100%";
    	document.getElementById(stat).style.display = "none";	
    	document.getElementById(postupac).style.display = "block";

    	var UPIDField = "#uploadTI"+uploadID;
    	var UPID = UPID;
    	$(UPIDField).val(UPID);
    }

    //allows for a return string
    return {

        //starts the upload
        start: function(uploadID) {
           ifr = document.getElementById("ifr"+uploadID);
           startTime = new Date();
           infoUpdated = 0;
           showUpload(uploadID); 
           this.requestInfo(uploadID);
        },
        //stops the upload
        stop: function(files, error, uploadID, UPID) {
           if (typeof files == 'undefined' || files) {
               	if(error == 0){
				 completeUpload(uploadID, UPID);
               	}else{
                   	stat = "The upload did not succeed. Most likely the file was not a divx video file and failed the tests.<br><br><a class='normalHyp' style='cursor:pointer;' id='retryupload' href='javascript:tryAgain(\""+uploadID+"\");'>If you wish to try again then please click here</a> ";
					writeStatus(stat, 3, uploadID)
               	}
           } else {
               stat = "There was an unkown problem with the upload. This error is normally caused when you attempt to upload:<ul id='generalul'><li>A file which is too large. The max size is 2GB.</li><li>A file which has not got the .divx extension or is not a video file</li></ul><br><a href='javascript:tryAgain(\""+uploadID+"\");' id='retryupload' class='normalHyp' style='cursor:pointer; color:#22a76d;'>If you wish to try again then please click here</a>";
               writeStatus(stat,3, uploadID);
           }
           startTime = null;
        },
        //gets current progress of upload
        requestInfo: function(uploadID) {
            var src = "info.php?ID="+uploadID+"&amp;amp;amp;amp;amp;"+new Date();
                ifr.src= src;
        },
        //updates the status to track current progress
        updateInfo: function(uploadID, uploaded, total, estimatedSeconds) {
            if (startTime) {
                if (uploaded) {
                    infoUpdated++;
                    if (total > upload_max_filesize) {
                        writeStatus("The file is too large and won't be available for PHP after the upload<br/> Your file size is " + total + " bytes. Allowed is " + upload_max_filesize + " bytes. That's " + Math.round (total / upload_max_filesize * 100) + "% too large<br/> Download started since " + (new Date() - startTime)/1000 + " seconds. " + Math.floor(uploaded / total * 100) + "% done, " + estimatedSeconds + "  seconds to go",2, uploadID);
                    } else {
                        var percent = Math.floor(uploaded / total * 100);
                        writeStatus("Download started since " + (new Date() - startTime)/1000 + " seconds. " + Math.floor(uploaded / total * 100) + "% done, " + estimatedSeconds + "  seconds to go - <a href='javascript:Abort(\""+uploadID+"\");' class='normalHyp' style='cursor:pointer;' id='abortthisuploadnow'>Abort this Upload</a>",0,uploadID);
						//changes the upload bar to match the polled progress of the upload
                        document.getElementById("progressUpload"+uploadID).style.width = percent + "%";
                    }
                } else {
                    writeStatus("Download started since " + (new Date() - startTime)/1000 + " seconds. No progress info yet (Negotiating Connection to Server)",0,uploadID);
                }
                //sets a timer for the next poll for getting upload progress
                window.setTimeout('UP.requestInfo("'+uploadID+'")',750);
            }
        }        
    }
}()


</script>
{/literal}
</head>

<body>
{include file="newHeader.htm"}

<div id="darkBackgroundLayer" class="darkenBackground" style="display:none;"></div>

<div id="exitConfirm_D" class="loginboxhover" style="display:none;" align="center">
	<div id="uploadconfirmleave" style="width:712px; z-index:1;">
		 <div class="defaultContainerOuter">
	     	<h2 class="regTop" id="">Hey You! Yeah! You There!</h2>
		     <div class="defaultContainerInner" style="text-align:left; padding:0;">
			     <div style="padding-left:5px; padding-right:5px;">
				     <p>This page is attempting to redirect away from itself to another page. In order to stop my servers from exploding this action will stop any files you are currently uploading.</p>
				     <p>Are you sure you wish to navigate away from this page?</p>
			     </div>
			     <div style="background:#131313; border-top:1px solid #363636; padding:5px; padding-top:7px; color:#fff;">
				     <form action="usrcp.php?home">
					     <div align="right">
					     	<input type="submit" value="Yes, Take Me There" class="button7" style="margin-right:3px;"> Or <a id="N_RtnUP" class="normalHyp" style="cursor:pointer;">No, Take Me Back to The Uploads</a>
					     </div>
				     </form>
			     </div>
			 </div>
		</div>
	</div>
</div>

<div id="Max_UP_S" class="loginboxhover" style="display:none;" align="center">
	<div id="uploadconfirmleave" style="width:712px; z-index:1;">
		 <div class="defaultContainerOuter">
	     	<h2 class="regTop" id="">Maximum Uploads Reached</h2>
		     <div class="defaultContainerInner" style="text-align:left; padding:0;">
			     <div style="padding-left:5px; padding-right:5px;">
				     <p>You can only upload five video files at a time at the moment.</p>
			     </div>
			     <div style="background:#131313; border-top:1px solid #363636; padding:5px; padding-top:7px; color:#fff;">
			     	<div align="right">
					 	<input type="submit" value="OK" class="button7" id="UP_MAX_OK" style="margin-right:3px;">
					</div>
			     </div>
			 </div>
		</div>
	</div>
</div>

<div align="center">
	<div id="MainBody">
		<div class="MainBodyLower LoginBodyLower">
			<div id="vdUPCON">
				<div id="vdUPLeft">
					<div class="defaultContainerOuter">
		     			<h2 class="regTop">Upload Video(s) to StageX</h2>
			    	 <div class="defaultContainerInner" >
			    	 
			    	     <!-- Link to add more upload forms -->
			     		 <div id="add_UP" style="margin:10px; padding:7px; display: none;">
			 				<input type="hidden" value="0" id="UploadTotal" />
							<img src="styles/default/images/plusadd.png" style="vertical-align:middle; margin-right:5px;"/><a href="javascript:;" onclick="addElement();" class="normalHyp">Add More Files to the Queue</a>
		
						 </div>
								
					     <div id="upload_frmCon{$id}" style="margin:10px; border:1px solid #363636; background:#131313; padding:7px; padding-top:15px;">
					     
							 <form onsubmit='UP.start("{$id}")' target="ifr2{$id}" action="server.php?id={$id}" enctype="multipart/form-data" method="post">
								 <input type="hidden" name="UPLOAD_IDENTIFIER" value="{$id}" />
								 <span class="non-pText" style="font-weight:bold; font-size:15px;">Select a video to upload</span>
								 
								 <div style="padding-top:5px; padding-bottom:2px;">
								 	<input type="file" name="{$id}" size="30"/><input type="submit" value="Upload File" class="button7" style="right:0; margin-left:220px; margin-right:0;" />
							 	 </div>
							 </form>
							 
							 <iframe id="ifr{$id}" src="info.php?ID={$id}" style="display:none;" name="ifr{$id}"></iframe>
				  			 <iframe name="ifr2{$id}" style="display:none;" id="ifr2{$id}"></iframe>
				  			 
					 	 </div>
					 	 
					 	 <div id="upload_prog{$id}" style="margin:10px; border:1px solid #363636; background:#131313; padding:7px; padding-top:15px; display:none;">
						 	 <span id="uploadTitle{$id}" class="non-pText" style="font-weight:bold; font-size:15px;">Your video is being uploaded</span>
						 	 <!-- The actual progress bar HTML  -->
						 	 <div id="progressuploadouter{$id}" style="border:1px solid #363636; padding:2px; margin-top:5px; background:#000;">
						 	 <div id="progressUpload{$id}" style="width:10%; background:url(styles/default/images/progressback.png); height:30px;"></div>
						 	 </div>
						 	 
						 	 <!-- Status of the upload -->
						 	 <div id="status{$id}" style="color:white; padding:3px;">Connecting to Server...</div>
						 	 
							 <!-- Post Upload actions -->
							 <div id="pst_UPActs{$id}" style="display:none; margin-top:5px;">
							
								<!-- Post upload choices -->
							 	<div align="right">
									<span class="non-pText">
									<a id="hyp_entDetails" href='javascript:Ent_UPDetails("{$id}");' class="normalHyp" style="cursor:pointer;">You can add details about this video now</a> or </span>
									<input type="submit" id="Cont_Profile" class="button7" value="Continue To Your Profile"/>
								</div>
								
								 <!-- Speech bubble -->
								 <div style="background:transparent; display:none; margin-top:5px;" id="entUpDetails{$id}">
									 <div align="center">
									 	 <div style="margin-left:5px; margin-right:5px;">
											 <div style="text-align:left; background:url(styles/default/images/speachtop.png); height:10px; width:100%;"></div>
											 <div style="text-align:left; background:black; border-bottom:1px solid #363636; border-left:1px solid #363636; border-right:1px solid #363636; width:100%;">
												 <div style="padding:5px;">
													 <form id="adddetails{$id}">
													 	<div style="width:100%; padding:5px;">
													 	
													 		<span class="non-pText" style="font-size:15px;">Video File Details</span>
													 		
													 		<a href='javascript:Ent_UPDetails("{$id}");' class="normalHyp" style="border:0; margin-left:36em;">Close X</a>
													 		
													 	</div>
													 	<div id="eC_Err{$id}" style="display:none;">

													 	</div>
													 	<div style="width:100%;">
														 	<div id="detailsUploadCon">
														 		<div id="detailsUploadLeft">
												                    <fieldset class="fields6">
												                    <input type="hidden" name="uploadTI{$id}" id="uploadTI{$id}" value=""> 
												                        <dl>
												                        	<dt style=""><label for="vidtitle">Title:</label></dt>
												                        	<dd style=""><input class="inputbox" type="text" id="title{$id}" name="title{$id}" style="width:100%;"/></dd>
												                        	<dt><label for="videsc">Description:</label></dt>
												                        	<dd><textarea name="description{$id}" id="description{$id}" class="textarea" rows="10" cols="30"></textarea></dd>
												                        	<dt style=""><label for="vidtags">Tags:</label></dt>
												                        	<dd style=""><input class="inputbox" type="text" id="tags{$id}" name="tags{$id}" style="width:100%;"/></dd>
												                        	<dt></dt>
												                        	<dd>Up to five tags seperated by a comma ",".</dd>
												                        </dl>
												                    </fieldset>
														 		</div>
														 		<div id="detailsUploadRight">
												                    <fieldset class="fields6">
									                                    <dl class="fields6" style="padding-left:10px;">
									                                        <dt id="dtradio" style="width:2em; text-align:left; color:white;"><input type="radio" id="rate{$id}" name="rate{$id}" value="0"/></dt>
									                                        <dd id="dtradio" style="margin-left:2em; color:white;"><label>Video is appropiate for everyone</label></dd>
									                                        <dt id="dtradio" style="width:2em; text-align:left; color:white;"><input type="radio" id="rate1{$id}" name="rate1{$id}" value="1"/></dt>
									                                        <dd id="dtradio" style="margin-left:2em; color:white;"><label>Video is NOT appropiate for children</label></dd>
									                                        
									                                        <dl>
										                                        <dt style="width:2em; text-align:left;"><input type="checkbox" id="SEXOPT{$id}" name="SEXOPT{$id}" value="1"></dt> 
										                                        <dd style="margin-left:2em;">This video contains nudity and/or sexual situations</dd>
									                                        </dl>
									                                        
									                                        <dt style="width:2em; text-align:left;"></dt>
									                                        <dd style="margin-left:2em;">Inappropiately marking content for everyone when it is not may ensure your account is subject to deletion</dd>
									                                    </dl>
												                    </fieldset>
														 		</div>
														 	</div>
													 	</div>
													 </form>
												 </div>
											 	<div style="background:#131313; border-top:1px solid #363636; padding:5px; padding-top:7px; color:#fff; text-align:right;">
											 		<input type="submit" onclick='javascript:AddDetails("{$id}");' class="button7" value="Save Video Details" style="margin-right:1em;"/>
											 	</div>
											 </div>
										 </div>
									 </div>
								 </div>
						
							 </div>
						 </div>
						<div id="addFFRM"> </div>
						 
			  		 </div>
			  		</div>
		
					<h2 class="titlenomargin">Uploading a Video</h2> 
					<ul id="generalul" style="font-size:13px; margin-bottom:5px;">
					<li>Upload High Definition videos</li>
					<li>Upload up to 5 videos at a time</li>
					<li>Videos can be upto 2 GB in size each</li>
					<li>Video can be any length of time</li>
					</ul>
				
					<p style="font-size:13px;">Please respect all copyright laws for media.<br>This script is still in Beta so it may still have bugs in, please report any bugs</p>
				</div>
				<div id="vdUPRight">  
				</div>
			</div>  
		</div>
	</div>
</div>
{include file="footer.htm"}
</body>
</html>

I will now attempt to explain this code to you all, attempt. Firstly allow me to apologise for the crude coding and for certain redundant functions still existing, I have not yet cleaned the code up since as you know I still have a couple of bits to do.

All variables you see within {$} are template variables which are gained from a back-end PHP file. If you do not understand template variables there are articles on my blog that will show you this stuff. You can see I am using two iframes and controlling these iframes using a return Javascript function, UP. This UP function allows us to over come AJAX/JSON etc by displaying a page within an iframe and just "echo"ing back a Javascript response function (i.e. echo "UP.completeUpload({$id});").

JQuery is used at the top of this page to add styling to certain parts of the script. I should note that this script will not work off the mark. This is because it is set-up to work with my own individual server. If you are a regular follower of this site then this script will most likely work from copy and paste, however, if you are not then it won’t.

Ok now we need the initial back-end for this page:

<?php

require_once 'includes/header.php';

if($_SESSION['logged']){
	//makes new ID
  $randName = md5(rand() * time());

  //checks ID has not been used against the database
	$lookUPN = true;
	while ($lookUPN == true){
		$lookupSQL = "SELECT * FROM tblvideo where VideoFile = '$randName/'";
		$resultLookup = $user->db->getRow($lookupSQL);
								
		if(is_object($resultLookup)){
			$randName = md5(rand() * time());
		}else{
			$lookUPN = false;		
		}
	}

	$id = $randName;
  //return bytes of something
  function return_bytes($val) {
    $val = trim($val);
    $last = strtolower($val[strlen($val)-1]);
    switch($last) {
        // The 'G' modifier is available since PHP 5.1.0
        case 'g':
            $val *= 1024;
        case 'm':
            $val *= 1024;
        case 'k':
            $val *= 1024;
    }

    return $val;
  }

  //Basic checks to ensure things work (mainly used for debugging and such like)
  $templateini =  ini_get("uploadprogress.file.filename_template");
  $testid = "thisisjustatest";
  $template = sprintf($templateini,$testid);
  $templateerror = false;
  if ($template &amp;amp;amp;amp;&amp;amp;amp;amp; $template != $templateini &amp;amp;amp;amp;&amp;amp;amp;amp; @touch ($template) &amp;amp;amp;amp;&amp;amp;amp;amp; file_exists($template)) {
    //    print '('.$templateini.' is writable. The realpath is ' . str_replace($testid,"%s",realpath($template)) .')';  
        unlink($template);
  } else {
        $templateerror = true;   
  }

   if (function_exists("uploadprogress_get_info")) {  
       if ($templateerror) {
           $style= 'background-color: red;\">Urgh! Not a Problem! ';
           if ($template == $templateini) {
               $style = $style . " uploadprogress.file.filename_template ($templateini) doesn't have an %s in it for making unique temporary files. Please adjust.<br/>";
           } else {
               $style = $style . "$templateini is NOT writable. <br/>Please make sure the directory exists and is writable for the webserver. <br/>
               Or adjust the ini setting 'uploadprogress.file.filename_template' to a correct path.";
           }
       } else {
           $style = 'background-color: green;\">All Needed Checks have been completed you are clear for take off';
       }
   } else {
       $style = "background-color: red;\">The uploadprogress extension is not installed.";
   } 
   
   //assign template variables
   
   $smarty->assign('id', $id);
   $smarty->assign('uploadmax',return_bytes(ini_get('upload_max_filesize')));
   $smarty->assign('style', $style);
   $smarty->display('videoUploadMain.htm');
   
}else{
	header("Location: login.php");
}
?>

This just basically sets and makes the page and its contents.

Now that you have the initial front-end of the upload script we need to grab information about the upload progress. Fortunately this is easy as hell (this goes as info.php). This script, unlike the others, was pulled straight from the example of the PHP extension so it carries the authors copyright:

<?php
/*
  +----------------------------------------------------------------------+
  | Uploadprogress extension                                             |
  +----------------------------------------------------------------------+
  | Copyright (c) 2006-2008 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt.                                 |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | license@php.net so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: Christian Stocker (chregu@php.net)                           |
  +----------------------------------------------------------------------+
*/

require_once('includes/header.php');

if($_SESSION['logged']){

if (function_exists("uploadprogress_get_info")) {
    
    $info = uploadprogress_get_info($_GET['ID']);
} else {
    $info = false;
}

?>
<html>
<head>
<script type="text/javascript">
<?php


if ($info !== null) {
$print = 'parent.UP.updateInfo('.$info['bytes_uploaded'].','.$info['bytes_total'].','.$info['est_sec'].',"'.$_GET['ID'].'")';
    print 'parent.UP.updateInfo("'.$_GET['ID'].'",'.$info['bytes_uploaded'].','.$info['bytes_total'].','.$info['est_sec'].')';
} else {
    print 'parent.UP.updateInfo("'.$_GET['ID'].'")';
}
?>
</script>

</head>

<body>
<pre>
<?php
print "Date : " . date("c",time())."\n";
print "ID   : ". $_GET['ID'] ."\n";
print 'var_dump($info): '. "\n";
var_dump($info);
?>
</pre>
</body>
<?php 
}else{
	header('Location: login.php');
}
?>

Now you have the upload page and grabbing information about the upload progress. All you need now is the actual page that uploads. The information page uses uploadprogress_get_info to get the upload information for a specific $ID (or upload). All uploads are ID’d making it very easy to create multiple uploads.

Now you need the actual uploading page itself (server.php):

<?php
require_once 'includes/header.php';
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta name="generator" content="HTML Tidy for Linux/x86 (vers 1 September 2005), see www.w3.org" />
<script type="text/javascript">
<?php
if($_SESSION['logged']){
	if(isset($_GET['id'])){
		$id = $_GET['id'];
		function handleError() {
				//echo  'parent.UP.stop(true, 1, "'.$id.'");';   
		}
		
		if (count($_FILES) > 0) {
			
						$uploadedby = $_SESSION['uid'];
						$fileName = $_FILES[$id]['name'];
						$tmpName = $_FILES[$id]['tmp_name'];
						$fileSize = $_FILES[$id]['size'];
						$fileType = $_FILES[$id]['type'];
						$name = substr($fileName, 0, strrpos($fileName, '.'));
					    $ext = substr(strrchr($fileName, "."), 1);
					    if($ext == "divx"){        
			                
							$randName = md5(rand() * time());
							//check for folder existing
							$lookUPN = true;
							while ($lookUPN == true){
								$lookupSQL = "SELECT * FROM tblvideo where VideoFile = '$randName/'";
								$resultLookup = $user->db->getRow($lookupSQL);
								
								if(is_object($resultLookup)){
									$randName = md5(rand() * time());
								}else{
									$lookUPN = false;		
								}
							}
							
							$rs = @mkdir( "upload/".$randName , 0777 );
							@handleError();
							
							if( $rs ){
								$randThing = $randName;
								$randName = $randName . "/";
								
								$filePath = "upload/" . $randName . $fileName;
							
							 
								if(@move_uploaded_file($_FILES[$id]['tmp_name'], $filePath)){
				
									if(!get_magic_quotes_gpc()){
										$fileName = addslashes($fileName);
										$filePath = addslashes($filePath);
									}
			
									chmod($filePath, 0777 );
									
									
									$comm = 'ffmpeg -itsoffset -00:01:15 -i "/home/sam/inetpub/htdocs/the_stage/'.$filePath.'" -vcodec png -vframes 1 -an -f rawvideo -s 800x600 "/home/sam/inetpub/htdocs/the_stage/upload/'.$randThing.'.png"';
									system($comm);	
											    
									$command = sprintf('ffmpeg -i "/home/sam/inetpub/htdocs/the_stage/'.$filePath.'" 2>&amp;amp;amp;1');
									exec($command,$output);
										    
							    	$v = array();
							    		    
							    	// Now match output with options
									$text = implode("\r",$output);
									$v['file_ffmpeg_info_says'] = $text;
									        
							        if (preg_match('!Duration: ([0-9:.]*)[, ]!', $text, $matches)){
							        	list ($v_hours,$v_minutes,$v_seconds) = explode (":",$matches[1]);
							        	$v['file_duration'] = $v_hours . ":" . $v_minutes . ":" . $v_seconds;
							    	}		
							    		    
							    	$length = $v['file_duration'];
					                        
					                $actualLength = explode(".",$length);
					                        
					                $length = $actualLength[0];
					                        
									$imageurl = "upload/$randThing.png"; 
									
									$uploadedby = $user->db->quote($uploadedby);
									$name = $user->db->quote($name);
									$length = $user->db->quote($length);
									$fileSize = $user->db->quote($fileSize);
									$filePath = $user->db->quote($filePath);
									$randName = $user->db->quote($randName);
									$imageurl = $user->db->quote($imageurl);	 
									
									$newID = md5(((((rand() * time())/2) + ((rand() * time())/2)) * rand())/(time()-rand()));
									$newIDQ = $user->db->quote($newID);
									
										    //insert all data into the table
									$query = "INSERT INTO tblvideo (UserID, VideoTitle, VideoLength, VideoSize, VideoUrl, VideoFile, VideoThumbUrl, upID ) ".
									"VALUES ($uploadedby, $name, $length, $fileSize, $filePath, $randName, $imageurl, $newIDQ)";
										    
									$user->db->query($query);
									
									echo  'parent.UP.stop(true, 0, "'.$id.'", "'.$newID.'");';
				
								}else{
									echo  'parent.UP.stop(true, 1, "'.$id.'");';
								}
							}else{
								echo  'parent.UP.stop(true, 1, "'.$id.'");';
							}
						}else{
							echo  'parent.UP.stop(true, 2, "'.$id.'");';
						}
		  
		} else {
		  echo  'parent.UP.stop(true, 0, "'.$id.'");';
		}
	}else{
		header("Location: VideoUpload.php");
	}
}else{
	header("Location: login.php");
}
?>
</script>

<title></title>
</head>

<body>
  File uploaded:
  <pre>
<?php
var_dump($_FILES);
?>

</pre>
</body>
</html>

This page is specifically designed to upload a video however it is easy to change. If you are looking to do this kind of script exactly then I will explain:

This script uses checks to ensure that the video file is one I want. I then uses ffmpeg to not only take a thumbnail of the video but also get information such as the videos length (hrs:mins:secs) and then writes all this information to the database.

Now that we have the actual page the uploads the file to server we need to finish the touch up by adding the uploadIDMake.php (for new uploads) and jxSV_VID.php (for adding video file details). So lets begin with uploadIDMake.php:

<?php
	require_once('includes/header.php');

	$randName = md5(rand() * time());
	
	$lookUPN = true;
	while ($lookUPN == true){
		$lookupSQL = "SELECT * FROM tblvideo where VideoFile = '$randName/'";
		$resultLookup = $user->db->getRow($lookupSQL);
								
		if(is_object($resultLookup)){
			$randName = md5(rand() * time());
		}else{
			$lookUPN = false;		
		}
	}
  
	echo $randName;
  
?>

This script is pretty basic and it just echos the ID back to the JQuery AJAX in the Javascript of the main upload page.

jxSV_VID.php:

<?php
require_once 'includes/header.php';

header("Cache-Control: no-cache, must-revalidate");
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");

if($_SESSION['logged']){
	$req_fields = array("title"=>"Video Title", "description"=>"Video Description", "tags"=>"Video Tags");
	
	if(check_empty_fields()){
		if(($_POST['rate']=="") &amp;amp;amp;&amp;amp;amp; ($_POST['rate1']=="")){	
			$returnArray = array("ErrorCode"=>1, "Message"=>"You must confirm whether the video is suitable for children or not manually.");
			echo json_encode($returnArray);
			exit;			
		}
		
			if((isset($_POST['upID'])) &amp;amp;amp;&amp;amp;amp; (isset($_POST['id']))){
				
				$upID = $user->db->quote($_POST['upID']);
				
				$sql = "SELECT * FROM tblvideo WHERE upID = $upID";
				
				$result = $user->db->getRow($sql);
				
				$title = $user->db->quote($_POST['title']);
				$description = $user->db->quote($_POST['description']);
				$videotags = $user->db->quote($_POST['tags']);
				$videorating = $user->db->quote($_POST['rate']);
				
				if($_POST['rate1']=="1"){
					$videorating = $user->db->quote($_POST['rate1']);
				}
				
				$videoNudity = $user->db->quote($_POST['Nud']);
				
				$sql = "UPDATE tblvideo SET VideoTitle=$title, VideoDescription=$description, VideoTags=$videotags, AudienceRating=$videorating, Nudity=$videoNudity WHERE upID = $upID";
				
				$user->db->query($sql);
				
				$returnArray = array("ErrorCode"=>0, "Message"=>"The file details have been appended. For more detailed editing please visit your videos through your profile.");
				echo json_encode($returnArray);
				exit;
				
			}else{
				$returnArray = array("ErrorCode"=>1, "Message"=>"The script encountered an unokwn error. This has been reported and will be dealt with as soon as possible.");
				echo json_encode($returnArray);
				exit;
			}

	}else{
		$returnArray = array("ErrorCode"=>1, "Message"=>$msg);
		echo json_encode($returnArray);
		exit;		
	}
}else{
	header("Location: login.php");
}

?>

This script is not all that complex either. It just grabs the video details entered and puts them into database ensuring the user is logged in.

And thats it, you have the script check out the gallery for the pics of this thing in action.

As a word of warning I would suggest the use of either an infinite session (bad idea) or a cookie that expires on browser close in order to make this script work perfectly fine or you could just use no session (noob style).

Anyway if you have any questions feel free to post a comment, stay safe.