<?

class fileman {

var $errorMsg;
var $slash;
var $available = array();
var $list = array();
var $tmpdir;

function fileman() {
	if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
		$this->slash = "\\";
		$this->available["chmod"] = false;
		$this->os = "win";
	} else {
		$this->slash = "/";
		$this->available["chmod"] = true;
		$this->os = "lin";
	}
}

function basename($path) {
	return $this->normalizePath(basename($path));
}
function dirname($path) {
	$s = $this->normalizePath(dirname($path));
	if ($s == ".") {$s = "/";}
	return $s;
}

function stripExtension($filename) {
	return substr($filename, 0 , strrpos($filename, "."));
}

function normalizePath($path) {
	$s = trim($path);
	//make all backslashes slashes
	$s = str_replace("\\", "/", $s);
	$s = preg_replace("/%2F/", "/", $s);
	//multiple slashes to single slahes
	//$s = preg_replace("/\/{2,}/", "/", $s);
	//strip trailing slash
	$s = rtrim($s, "/");
	return $s;
}

function loadFileTypesInfo() {
	global $db, $settings;
	foreach ($db->CacheGetAll(600,"SELECT * FROM ".$settings->config['filetypes_tablename']."",false) as $value) {
		$this->filetypes[$value['extension']] = $value;
	}
}

function createPath($path) {
		$path_array = explode("/", $path);
		$dir = "";
		if (is_dir($path)) {
			return true;
		} else {
		for ($i = 0 ; $i < sizeof($path_array)-1 ; $i++) {
			if (!$lastFolder) {
				$lastFolder = $path;
			}
			$lastFolder = $this->dirname($lastFolder);
			if (is_dir($lastFolder)) {
				$startFolder = $lastFolder;
				break;
			}
		}
		//echo "start from ".$startFolder."<br>";
		$toBeCreated = substr($path, strlen($startFolder), strlen($path));
		//echo $toBeCreated;
		$path_array = explode("/", $toBeCreated);
			$dir = false;
			for ($i = 0 ; $i < sizeof($path_array) ; $i++) {
				$val = $path_array[$i];
					if (!$dir) {
						$dir = gluePath($startFolder, $val);
					} else {
						$dir = gluePath($dir, $val);
					}
					if (!is_dir($dir)) {
						if (!mkdir($dir, 0777)){
							if (file_exists($dir)) {
								$this->errorMsg = "unable to create folder \"".$dir."\" (already exists)";
							} else {
								$this->errorMsg = "unable to create folder \"".$dir."\"";
							}
							return false;
						}
					}
			}
			clearstatcache();
			if (!is_dir($dir)) {
				$this->errorMsg = "unable to create folder \"".$dir."\"";
				return false;
			} else {
				return true;
			}
		}
}

function rename($oldPath, $newName) {
	$dir = $this->dirname($oldPath);
	if(file_exists($oldPath)) {
		if (!file_exists($dir."/".$newName)) {
			if (rename($oldPath, $dir."/".$newName)) {
				return true;
			} else {
				$this->errorMsg = "rename error: source ".$oldPath." could not be renamed to ". $newName;
				return false;
			}
		} else {
			$this->errorMsg = "rename error: destination ".$dir."/".$newName." already exist";
			return false;
		}
	} else {
		$this->errorMsg = "rename error: source ".$oldPath." doesn't exist";
		return false;
	}
}

function delete($path) {
	if(file_exists($path)) {
		if(is_dir($path)) {
			if ($this->deleteDir($path)) {
				return true;
			} else {
				$this->errorMsg = "delete error: ". $this->errorMsg;
				return false;
			}
		} else {
			if (unlink($path)) {
				return true;
			} else {
				$this->errorMsg = "delete error: file ".$path." could not be deleted";
				return false;
			}
		}
	} else {
		$this->errorMsg = "delete error: ".$path." doesn't exist";
		return false;
	}
}

function deleteDir($path) {
	if (is_dir($path)){
		$handle=opendir($path);
		while (($file = readdir($handle))!==false){
			if (($file != ".") && ($file != "..")){
				if (is_dir($path."/".$file)) {
					//do recursive stuff if the "file" is a dir
					$this->deleteDir($path."/".$file);
				}
				if (is_file($path."/".$file)){
					//delete all files in the dir
					if(!unlink($path."/".$file)) {
						$this->errorMsg = "deleteDir error: file " . $path."/".$file . " could not be deleted";
						return false;
					}
				}
			}
		}
		closedir($handle);//close dir
	}
	//replace the web path with the dir path and remove the now empty dir
	if (rmdir($path)) {
		return true;
	} else {
		$this->errorMsg = "deleteDir error: folder " . $path . " could not be deleted";
		return false;
	}
}

function move($oldPath, $newPath) {
	//copy to new location
	if ($this->copy($oldPath, $newPath)) {
		//delete from old location
		if ($this->delete($oldPath)) {
			return true;
		} else {
			$this->delete($newPath);
			$this->errorMsg = "move error: ".$this->errorMsg;
			return false;
		}
	} else {
		$this->errorMsg = "move error: ".$this->errorMsg;
		return false;
	}
}

function copy($oldPath, $newPath) {
	if (is_dir($oldPath)) {
		if ($this->copyDir($oldPath, $newPath)) {
			return true;
		} else {
			return false;
		}
	} elseif (is_file($oldPath)) {
		if($this->copyFile($oldPath, $newPath)) {
			return true;
		} else {
			return false;
		}
	} else {
		$this->errorMsg = "copy error: " . $oldPath . " is not a folder nor a file.";
		return false;
	}
}

function copyFile($oldPath, $newPath) {
	$destFolder = dirname($newPath);
	if(file_exists($oldPath)) {
		if (file_exists($newPath)) {
			$this->errorMsg = "copyFile error: destination file ".$newPath." already exist";
			return false;
		} elseif (!is_dir($destFolder)) {
			$this->errorMsg = "copyFile error: destination folder ".$destFolder." doesn't exist";
			return false;
		} else {
			if (@copy($oldPath, $newPath)) {
				return true;
			} else {
				$this->errorMsg = "copyFile error: ".$oldPath." could not be copied to ".$newPath;
				return false;
			}
		}
	} else {
		$this->errorMsg = "copyFile error: source file ".$oldPath." doesn't exist";
		return false;
	}
}

function copyDir($oldPath, $newPath) {
	$from_path = $oldPath;
	$to_path = $newPath;
	if (is_dir($to_path)) {
		$this->errorMsg = "copyDir error: ".$to_path . " already exist";
		return false;
	} else {
		if (!is_dir($this->dirname($to_path))) {
			if (!$this->createPath($to_path)) {
				$this->errorMsg = "copyDir error: ".$this->errorMsg;
				return false;
			}
		} else {
			mkdir($to_path);
		}
	}

	if (is_dir($from_path)) {
	@chdir($from_path);
	$handle = @opendir('.');
	while (($file = @readdir($handle)) !== false) {
		if (($file != ".") && ($file != "..")) {
			if (is_dir($file)) {
				$this->copyDir($from_path."/".$file,  $to_path."/".$file);
				chdir($from_path);
			}
			if (is_file($file)) {
				if (!$this->copyFile($from_path."/".$file, $to_path."/".$file)) {
					$this->errorMsg = "copyDir error: ".$this->errorMsg;
					return false;
				}
			}
		}
	}
	} else {
		$this->errorMsg = "copyDir error: ". $from_path . " doesn't exist";
		return false;
	}
	closedir($handle);
	return true;
}

function getExtension($filename) {
	$m = explode(".", $filename);
	$sizet = sizeof($m)-1;
	if ($sizet == "0") {
		$ext = "";
	} else {
		$ext = strtolower($m[$sizet]);
	}
	return $ext;
}

function formatFileSize($filesize, $precision = 2, $emptyStr = "empty") {
	
	if ($filesize > 0 && $filesize < 1024) {
		$filesize = $filesize;
		if ($filesize == 1) {
			$filesize .= " Byte";
		} else {
			$filesize .= " Bytes";
		}
	} elseif ($filesize >= 1024 && $filesize < 1048576) {
		$filesize = round($filesize/1024, $precision);
		$filesize .= " KB";
	} elseif ($filesize >= 1048576 && $filesize < 1073741824) {
		$filesize = round(($filesize/1024)/1024, $precision);
		$filesize .= " MB";
	} elseif ($filesize >= 1073741824) {
		$filesize = round((($filesize/1024)/1024)/1024, $precision);
		$filesize .= " GB";
	} else {
		$filesize = $emptyStr;
	}
	return $filesize;
}

function getFileSize($path) {
	if (file_exists($path)) {
		return filesize($path);
	} else {
		$this->errorMsg = "getFileSize error: ".$path." doesn't exist";
		return false;
	}
}

function sendHTTPFile($path, $filename = "") {
	if (!$filename) {
		$filename = $this->basename($path);
	}
	$filesize = $this->getFileSize($path);
	$browser = $_SERVER['HTTP_USER_AGENT'];
	if (strstr($browser, "MSIE") !== false) {
		header("Cache-Control: cache, must-revalidate");    
		header("Pragma: public");
	}
	header("Content-Type: application/download");
	header("Content-Length: ".$filesize);
	header("Content-Disposition: attachment; filename=\"".$filename."\"");
	
	@ini_set("max_execution_time", 300);
	@set_time_limit(0);
	@session_write_close();
	$handle = fopen($path, "rb");
	if (!$handle) {
		return false;
	}
	if ($offset) {
		fseek($handle, $offset);
	}
	$lastSentBytes = 0;
	while (!feof($handle)) {
		echo fread($handle, 8192);
		flush();
		@ob_flush();
	}
	fclose($handle);
}

function getDirSize($dir) {
    $size = 0;
    $dh = @opendir($dir);
    if ($dh) {
        while (($file = @readdir($dh)) !== false) {
            if ($file != "." && $file != "..") {
                $path = $dir."/".$file;
                if (is_dir($path)) {
                    $size += $this->getDirSize($path."/");
                } else {
                    $size += @filesize($path);
                }
            }
        }
        closedir($dh);
		return $size;
    } else {
		$this->errorMsg = "getDirSize error: could not open folder " . $dir;
		return false;
	}
}

function setChmod($path, $newChmod) {
	clearstatcache();
	if (file_exists($path)) {
		$code = "chmod(\"".$path."\", 0".$newChmod.");";
		@eval($code);
		if ($this->getChmod($path) != $newChmod) {
			$code = "chmod(\"".$path."\", ".$newChmod.");";
			@eval($code);
			if ($this->getChmod($path) != $newChmod) {
				$this->errorMsg = "setChmod error: ".$path." could not be chmoded ". $newChmod;
				return false;
			} else {
				return true;
			}
		} else {
			return true;
		}
	} else {
		$this->errorMsg = "setChmod error: ".$path." doesn't exist";
		return false;
	}
}

function getChmod($path) {
	clearstatcache();
	if (file_exists($path)) {
		return substr(sprintf("%o",@fileperms($path)),-3);
	} else {
		$this->errorMsg = "getChmod error: ".$path." doesn't exist";
		return false;
	}
}


function getDirList($path, $storedList = array()) {
	if (is_array($storedList)) {//reset the object's list if first time this function is called
		$this->list = array();
	}
	$d = @dir($path);
	while($entry = @$d->read()) {
		if ($entry != "." && $entry != "..") {
			$entryPath = gluePath($path,$entry);
			if (is_dir($entryPath) && !is_link($entryPath)) {
				$this->list[] = $entryPath;
				$this->getDirList($entryPath, "1");
			} elseif (is_file($entryPath)) {
				$this->list[] = $entryPath;
			}
		}
	}
	@$d->close();
	return $this->list;
}

function oneDirList($path) {
	$d = @dir($path);
	while($entry = @$d->read()) {
		if ($entry != "." && $entry != "..") {
				$list[] = $entry;
		}
	}
	@$d->close();
	return $list;
}

function appendData($path, $data, $where) {
	if (file_exists($path)) {
		//write data to top or bottom of file
		
		if ($where == "bottom") {
			$fp = fopen($path, "ab");
		} else {
			$fp = fopen($path, "rb+");
		}
		
		if ($fp) {
			if (fwrite($fp, $data)) {
				fclose($fp);
				return true;
			} else {
				$this->errorMsg = "unable to write to file";
				fclose($fp);
				return false;
			}
		} else {
			$this->errorMsg = "unable to open file for writing";
			return false;
		}
	} else {
		$this->errorMsg = "file \"".$path."\" doesn't exist";
		return false;
	}
}

function emptyFile($path) {
	if (file_exists($path)) {
		$fp = @fopen($path, "w");
		if ($fp) {
			if (@fputs($fp, "", 0)) {
				@fclose($fp);
				return true;
			} else {
				$this->errorMsg = "unable to write to file";
				@fclose($fp);
				return false;
			}
		}
	} else {
		$this->errorMsg = "file \"".$path."\" doesn't exists";
		return false;
	}
}

function newFile($path, $data, $gzip = false) {
	$dirname = $this->dirname($path);
	
	if (!file_exists($path)) {
		if ($this->createPath($dirname)) {
			if ($gzip) {
				$fp = @gzopen($path, "w9");
			} else {
				$fp = @fopen($path, "w");
			}
			if ($fp) {
				if ($gzip) {
					$rs = @gzwrite($fp, $data);
				} else {
					$rs = @fputs($fp, $data, strlen($data));
				}
				if ($gzip) {
					@gzclose($fp);
				} else {
					@fclose($fp);
				}
					if ($rs) {
						return true;
					} else {
						if (strlen($data) == 0) {
							return true;
						} else {
							$this->errorMsg = "unable to write to file";
							return false;
						}
					}
			} else {
				$this->errorMsg = "unable to open file for writing";
				return false;
			}
		} else {
			$this->errorMsg = "newFile error:" . $this->errorMsg;
			return false;
		}
	} else {
		$this->errorMsg = "file \"".$path."\" already exist";
		return false;
	}
}

function newFileContent($path, $data) {
	$fp = @fopen($path, "w");
	if ($fp) {
		if (@fputs($fp, $data) || strlen($data) == 0) {
			@fclose($fp);
			return true;
		} else {
			$this->errorMsg = "unable to write to file";
			@fclose($fp);
			return false;
		}
	} else {
		$this->errorMsg = "unable to open file for writing";
		return false;
	}
}

function fileTypeInfo($ext) {
	global $db;
		if ($this->filetypes[$ext]) {
			return $this->filetypes[$ext];
		} else {
			$this->error = "fileTypeInfo error: unknown file type (no record)";
			$return['extension'] = "";
			$return['type'] = "";
			$return['icon'] = "generic.gif";
			$return['description'] = "Unknown file type";
			return $return;
		}
}


}

?>