<?php

	$config = array(
		"upload" => array(
			"path" => "./uploadz",
			"real_filename" => false, // Files will be saved with original filenames instead of random generated ones. Lowers security.
			"size_limit" => 52428800, // Maximum size of files
			"replace" => false, // Replace the file if it exist

			"extension_check_mode" => "whitelist", // 'whitelist' is recommended for best security. Use 'blacklist' at your own risk. Disable using "disable"

			"whitelist" => array("xyz", "yxzz"),

			"blacklist" => array("html", "php", "svg")
		),

		"access" => array(
			"direct" => false, // Show direct links to files on files list. Lowers security.
			"force_download" => true, // Force download. Increase security.
			"allow_delete" => false
		),

		"view" => array(
			"date_format" => "Y-m-d h:i"
		)
	);

// ===============================================================
// 							  						Code
// ===============================================================

	function handleUpload(){

		global $config;

		if(!isset($_FILES["file"])){
			if(isset($_GET['upload'])){
				echo "Uploaded file exceeds the php max file size<br/>";
				die();
			}

			return "none";
		}

		$files = reArrayFiles($_FILES["file"]);
		$uploaded = array();

		foreach ($files as $file) {

			$filename = basename($file["name"]);

			if(!$config['upload']['real_filename']){
				$filename = $filename."##HIDDEN##".generateRandomString();
			}

			$target_file = $config['upload']['path']."/".$filename;

			if(!$config['upload']['replace']){
				if(file_exists($target_file) || !empty(getFileName($file['name']))){
					echo "<b>".$file['name']."</b>: File already exists<br/>";
					continue;
				}
			}else{
				$filenameremove = getFileName($file['name']);
				if(!empty($filenameremove)){
					$path = $config['upload']['path']."/".$filenameremove;
					unlink($path);
				}
			}

			if($file['size'] > $config['upload']['size_limit']){
				echo "<b>".$file['name']."</b>: File is too large<br/>";
				continue;
			}

			if($config['upload']['extension_check_mode'] != "disable"){
				if(!checkFormat($file)){
					echo "<b>".$file['name']."</b>: Invalid file format<br/>";
					continue;
				}
			}

			$result = move_uploaded_file($file['tmp_name'], $target_file);

			if($result){
				echo "<b>".$file['name']."</b>: File uploaded<br/>";
				$uploaded[] = $file['name'];
				continue;
			}

			return "Unknown error";
		}

		if(!empty($uploaded)){
			echo "<b>Uploaded: </b>".implode(",", $uploaded);
		}

	}

	$alerts = "";

	function handleView(){
		global $config;
		global $alerts;

		if(isset($_GET['file'])){

			$filename = basename($_GET['file']);

			if(!file_exists($config['upload']['path']."/".$filename)){

				$files = array();
				foreach(scandir($config['upload']['path'], SCANDIR_SORT_NONE) as $file) {
					$files[$file] = filemtime($config['upload']['path']."/".$file);
				}

				asort($files);
				$files = array_keys($files);
				foreach($files as $file) {
						if(startsWith($file, $filename."##HIDDEN##")){
							$filename = basename($file);
						}
				}

			}

			if(empty($filename)){
				return;
			}


			if(!file_exists($config['upload']['path'].'/'.$filename)){
				$alerts .= "<script>alert('File not found');</script>";
				return;
			}

			$mimetype = mime_content_type($config['upload']['path'].'/'.$filename);
			$filenameDownload = $filename;

			$hpos = strpos($filename, "##HIDDEN##");
			if($hpos){
				$filenameDownload = substr($filename, 0, $hpos);
			}

			if(empty($filenameDownload)){
				$alerts .=  "<script>alert('Invalid filename');</script>";
				return;
			}

			if($config['access']['force_download']){

				header('Content-Type: application/octet-stream');
				header('X-Content-Type-Options: nosniff');
				header("Content-Transfer-Encoding: Binary");
				header('Content-Disposition: attachment; filename="'.$filenameDownload.'"');

			}else{

				header('Content-Type: '.$mimetype);
				header('Content-Disposition: inline; filename="'.$filenameDownload.'"');

			}
			echo file_get_contents($config['upload']['path'].'/'.$filename);

			die();

		}
	}

	function handleDelete(){
		global $config;

		if(isset($_POST['delete'])){

				$filename = getFileName(basename($_POST['delete']));
				$path = $config['upload']['path']."/".$filename;

				if(empty($filename)){
					echo "File not found";
					die();
				}

				if(!unlink($path)){
					echo "Error";
				}else{
					echo "Deleted";
				}

				die();

		}
	}

	function orderBy($data, $field, $mode = "asc"){
		if($mode == "asc"){
			$code = "return strnatcmp(\$a['$field'], \$b['$field']);";
		}else{
			$code = "return -1 * strnatcmp(\$a['$field'], \$b['$field']);";
		}

    usort($data, @create_function('$a,$b', $code));
    return $data;
  }

	function printFiles(){
		global $config;
		global $orderCategory;
		global $orderDirection;

		$files = array();
		foreach(scandir($config['upload']['path'], SCANDIR_SORT_NONE) as $file) {
			$path = $config['upload']['path']."/".$file;
			$files[] = array("name" => $file, "date" => filemtime($path), "size" => filesize($path));
		}


		$modes = array(
			"N" => "name",
			"D" => "date",
			"S" => "size"
		);

		if($orderDirection == "A"){
			$files = orderBy($files, $modes[$orderCategory], "asc");
		}elseif($orderDirection == "D"){
			$files = orderBy($files, $modes[$orderCategory], "dsc");
		}


		foreach($files as $file) {
			if($file['name'][0] == ".") continue;

			if(startsWith($file['name'], "##HIDDEN##")){
				continue;
			}

			$path = $config['upload']['path']."/".$file['name'];

			$size = formatSizeUnits(filesize($path));
			$date = date($config['view']['date_format'], filemtime($path));

			$hpos = strpos($file['name'], "##HIDDEN##");
			if($hpos){
				$file['name'] = substr($file['name'], 0, $hpos);
			}

			if(!$config['access']['direct']){
				$path = '?file='.urlencode($file['name']);
			}

			echo sprintf('<tr id="%s">
							<td>
								<a href="%s"><span>%s</span></a>
							</td>
							<td>%s</td>
							<td>%s</td>
							'.($config['access']['allow_delete'] ? '<td>
								<a href="#" onclick="deleteFile(\'%s\');">Delete</a>
							</td>' : "").'

						</tr>',"file_".htmlspecialchars($file['name']) ,$path, htmlspecialchars($file['name']), $size, $date, urlencode($file['name']));
		}
	}

	function getFileName($filename){
		global $config;
		$found = true;

		if(!file_exists($config['upload']['path']."/".$filename)){
			$found = false;
			$files = array();
			foreach(scandir($config['upload']['path'], SCANDIR_SORT_NONE) as $file) {
				$files[$file] = filemtime($config['upload']['path']."/".$file);
			}

			asort($files);
			$files = array_keys($files);
			foreach($files as $file) {
					if(startsWith($file, $filename."##HIDDEN##")){
						$filename = basename($file);
						$found = true;
					}
			}
		}

		if(!$found){
			return "";
		}

		return $filename;
	}

	function checkFormat($file){
		global $config;

		$fileType = pathinfo($file["name"], PATHINFO_EXTENSION);

		if($config['upload']['extension_check_mode'] == "whitelist"){
			return in_array($fileType, $config['upload']['whitelist']);
		}else if($config['upload']['extension_check_mode'] == "blacklist"){
			return !in_array($fileType, $config['upload']['blacklist']);
		}

		return false;
	}

	function reArrayFiles(&$file_post) {
		$file_ary = array();
		$file_count = count($file_post['name']);
		$file_keys = array_keys($file_post);

		for ($i=0; $i<$file_count; $i++) {
				foreach ($file_keys as $key) {
						$file_ary[$i][$key] = $file_post[$key][$i];
				}
		}

		return $file_ary;
}

	function startsWith($haystack, $needle) {
			return $needle === "" || strrpos($haystack, $needle, -strlen($haystack)) !== false;
	}

	function formatSizeUnits($bytes){
				if ($bytes >= 1073741824){
						$bytes = number_format($bytes / 1073741824, 2) . ' GB';
				}elseif ($bytes >= 1048576){
						$bytes = number_format($bytes / 1048576, 2) . ' MB';
				}elseif ($bytes >= 1024){
						$bytes = number_format($bytes / 1024, 2) . ' kB';
				}elseif ($bytes > 1){
						$bytes = $bytes . ' bytes';
				}elseif ($bytes == 1){
						$bytes = $bytes . ' byte';
				}else{
						$bytes = '0 bytes';
				}

				return $bytes;
	}

	function generateRandomString($length = 30) {
				$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
				$charactersLength = strlen($characters);
				$randomString = '';
				for ($i = 0; $i < $length; $i++) {
						$randomString .= $characters[rand(0, $charactersLength - 1)];
				}
				return $randomString;
	}

	$uploadStatus = handleUpload();

	if($uploadStatus != "none"){
		die();
	}

	$orderCategory = "N";
	$orderDirection = "A";

	if(isset($_GET['C'])){
		$orderCategory = $_GET['C'];
	}

	if(isset($_GET['O'])){
		$orderDirection = $_GET['O'];
	}

	handleView();

	if($config['access']['allow_delete']){
		handleDelete();
	}

?>

<!DOCTYPE HTML>
<html lang="en">
	<head>
		<meta charset="utf-8">
		<meta name="author" content="Adam Zambrzycki (Adikso)">
		
		        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
  
  
</head>
        
        
		<title>if file type ^ ? </title>
	</head>
	<body>

<!--
	<div>
<pre style="font-size:1.1em">
text aboutwhat ever the lingo is<br>
<BR>
to change file types:
<br>
line - 18 and 444 + title + currently set for xyz and yxzz
<br>
chat stuff - /shout/data/shouts put data in 0ut folder?
<br>
clear 0master/uploadz
<br>
maybe even 0master.zip ??


</pre>
</div>
-->
<div>
<br>
<b>A few tech things:</b><br>
<br>
.<B>change file type (18, 444 )</b> and .xyz files can be downloaded and viewed in any text editor.<br>
People are welcome to make own .xyz (zqz, whatever is set..) files for uploading. (...and I hope one day this welcome note, in many ways, will not be required..)
</div>

<div>
<br>
More details about the practice?
general details about <a href="http://ifxyz.xyz">ifxyz.xyz</a><br>
for specific notes to do with if zqzness ^ ? - see links bellow, scroll past the chat bit..<br>
</div>

<!--
	<div>
	some text ect..)<br>
	how / what/ etc. (link 2 a similar file?
	<br>
	tech stuff
	<br>
	more<br>
	
	</div>
-->
		<div class="box" id="uploadSpace">
			<a href="#">
			<label>
			  <input type="file" id="fileSelector" style="display: none;" onchange="processUpload(this.files);" multiple/>
			  <span id="input-file-replacer">Select a <b>file types</B> file</span>
			</label></a> or drag it here.</div>

		<div class="box">
			<table id="filesList" class="customtable">
				<thead>
					<tr>
		<th><a href="?C=N&O=<?php echo ($orderDirection == "A" ? "D" : "A") ?>" class="sort">Name</a></th>
		<th><a href="?C=S&O=<?php echo ($orderDirection == "A" ? "D" : "A") ?>" class="sort">Size</th>
		<th><a href="?C=D&O=<?php echo ($orderDirection == "A" ? "D" : "A") ?>" class="sort">Date</th>
		<?php if($config['access']['allow_delete']){ ?>
		<th>Action</th>
		<?php } ?>
					</tr>
				</thead>

				<tbody>

				<?php
					printFiles();
				?>

				</tbody>
			</table>
		</div>
	

<div class="container">
<P>
<!--blahblahx-->

</p>
  <div class="embed-responsive embed-responsive-16by9">
    <iframe class="embed-responsive-item" src="https://artoot.xyz/@ahanon/99977435214559533/embed"></iframe>
  </div>
 
</div>

  <div>
  <!--
  
  shout/index.html
  
  
Notes??
  <br>
 <a href="https://my.pcloud.com/publink/show?code=kZjCBAZNsIk1JApMtpt1GobqX8Up44wpiIk" >THiS LINK</a> is for a general notes folder. <br>
  The folder contains videos and audio recordings in a bit of quick unsorted manner. after being on the road, i will look fwd to have both time and bandwidth for arranging the notes slightly clearer.
  -->
  </div>
 


<!-- bottom

// <?php
// $number = 11;
// include('/home/beso/public_html/uploads/shoutcode_3.1.2/show_posts.php');
// ?>

end-->


		<div id="errorBox" class="box" style="display: none;"></div>

		<?php
			echo $alerts;
		?>

		<script>

			var doc = document.documentElement;
			doc.ondragover = function() { return false; };
			doc.ondragend = function() { return false; };
			doc.ondrop = function(event) {
				event.preventDefault();

				var files = event.dataTransfer.files;
				processUpload(files);

				return false;
			};

			var processUpload = function(files){

				var formData = new FormData();
				for(var i = 0; i < files.length; i++){

					formData.append('file[]', files[i]);

					var table = document.getElementById("filesList");
					var fileInfo = document.createElement("tr");
					fileInfo.setAttribute("id", "file_" + files[i].name);

					var fileNameInfo = document.createElement("td");
						var fileNameURL = document.createElement("a");
						var url = "?file=" + files[i].name;

							fileNameURL.setAttribute("href", url);
							var fileNameURLName = document.createTextNode(files[i].name);
								fileNameURL.appendChild(fileNameURLName);

						fileNameInfo.appendChild(fileNameURL);


					var sizeInfo = document.createElement("td");
						var sizeInfoText = document.createTextNode(formatBytes(files[i].size, 1));
						sizeInfo.appendChild(sizeInfoText);


					var dateInfo = document.createElement("td");
						var dateInfoText = document.createTextNode("Uploading...");
							dateInfo.setAttribute("id", "uploading-" + files[i].name);
						dateInfo.appendChild(dateInfoText);


					var RemoveActionInfo = document.createElement("td");
						var RemoveActionURL = document.createElement("a");
							RemoveActionURL.setAttribute("href", "#");
							RemoveActionURL.setAttribute("onclick", "deleteFile('" + files[i].name + "');");
							var RemoveActionURLName = document.createTextNode("Delete");
								RemoveActionURL.appendChild(RemoveActionURLName);

						RemoveActionInfo.appendChild(RemoveActionURL);


					fileInfo.appendChild(fileNameInfo);
					fileInfo.appendChild(sizeInfo);
					fileInfo.appendChild(dateInfo);
					fileInfo.appendChild(RemoveActionInfo);

					table.appendChild(fileInfo);
				}


				var xhr = new XMLHttpRequest();

				xhr.open("POST", "?upload");
				xhr.upload.onprogress = function(event){
					if(event.lengthComputable){

						var complete = (event.loaded / event.total * 100 | 0);

						for(var i = 0; i < files.length; i++){
							document.getElementById("uploading-" + files[i].name).innerHTML = ("" + complete + "%");
						}

					}
				}

				xhr.onload = function(){

					if(xhr.status === 200){

						for(var i = 0; i < files.length; i++){
							document.getElementById("uploading-" + files[i].name).innerHTML = ("seconds ago");
						}

						var response = xhr.responseText;
						var currentErrors = document.getElementById("errorBox").innerHTML;

						document.getElementById("errorBox").style.display = "block";
						document.getElementById("errorBox").innerHTML = currentErrors + response + "<br/>";

						var successful = response.substr(response.indexOf("<b>Uploaded: </b>"));

						for(var i = 0; i < files.length; i++){
							if(successful.indexOf(files[i].name) == -1){
								document.getElementById("file_" + files[i].name).remove();
							}
						}

					}

				}

				xhr.send(formData);

			};

			function formatBytes(bytes,decimals) {
			   if(bytes == 0) return '0 byte';
			   var k = 1000;
			   var dm = decimals + 1 || 3;
			   var sizes = ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
			   var i = Math.floor(Math.log(bytes) / Math.log(k));
			   return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
			}

			function deleteFile(filename){

				if(!confirm("Are you sure you want to delete this file?")){
					return;
				}

				var http = new XMLHttpRequest();
				var url = "#";
				var params = "delete=" + filename;
				http.open("POST", url, true);
				http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

				http.onreadystatechange = function() {
				    if(http.readyState == 4 && http.status == 200) {
				        var response = http.responseText;

								document.getElementById("errorBox").style.display = "block";
								var currentErrors = document.getElementById("errorBox").innerHTML;
								document.getElementById("errorBox").innerHTML = currentErrors + "<b>" + urldecode(filename) + ": </b>" + response + "<br/>";

								if(response == "Deleted"){
									document.getElementById("file_" + urldecode(filename)).remove();
								}
				    }
				}
				http.send(params);
			}

			function urldecode (str) {
			  return decodeURIComponent((str + '')
			    .replace(/%(?![\da-f]{2})/gi, function () {
			      return '%25'
			    })
			    .replace(/\+/g, '%20'))
			}


		</script>

		<style>
			body{
				margin: 40px;
				font-size: 13px;
			}

			a{
				color: #337ab7;
				text-decoration: none;
			}

			a:hover{
				text-decoration: underline;
			}

			#input-file-replacer{
				color: #337ab7;
			}

			#errorBox{
				margin-top: 20px;
			}
			
			.textbox{
				color: #000099;
				background: #fff;
				padding: 30px;
				border: 1px solid #blue;
			}

			table{
				width: 90%;
				border-collapse: collapse;
    			border-spacing: 0;
    			background: #ccc;
    			text-align: center;
    			border: 1px solid #blue;
			}

			td{
				border-bottom: 1px solid #e3e3e3;
			}

			.box{
				color: #737373;
				background: #eee;
				padding: 30px;
				border: 1px solid #e3e3e3;
			}

			.customtable thead{
				border-bottom: 2px solid #e3e3e3;
			}

			.customtable thead th{
				background: #000033;
				color: #fe4902;
				padding: 8px;
			}

			#uploadSpace{
				margin-bottom: 20px;
				text-align: center;
			}

			.sort{
				color: #fe4902;
				text-decoration: underline;
			}
		</style>

	</body>
</html>
