<?PHP

/**
* read, write, download, upload files
*/
class File{

	var $Files = array();
	var $FilesRecursive = array();
	var $Folders = array();
	var $FoldersRecursive = array();

	/**
	* read files from directory
	* @param String $dir AS from read files
	* @param String $like='' AS what file type
	* @param String $notlike='' AS not what file type
	* @param String $type='both'
	* @param Boolean $recursive=true
	*/
	function GetAllFiles($dir, $like='', $notlike='', $type='both', $recursive=true){

		/*
		loeme k�ik failid ja kataloogid arraysse $this -> Files[dir] v�i $this -> Files[file]
		*/
		$dir = str_replace ('//', '/', $dir);

		if(is_dir($dir)){

			$exp = explode('/', $dir);
			$file_dir = $exp[count($exp)-1];

			$dir_op = opendir($dir);
			while(false !== ($file = readdir($dir_op))){

				if(is_file($dir.'/'.$file) && !preg_match('/\.htaccess/i', $file)){

					if($like && ($type == 'file' || $type == 'both')){

						if(preg_match('/'.$like.'/i', $file)){

							$this -> FilesRecursive[][file] = $dir.'/'.$file;
							$this -> Files[][file] = $file;
						}
					}
					elseif($notlike && ($type == 'file' || $type == 'both')){

						if(!preg_match('/'.$notlike.'/i', $file)){

							$this -> FilesRecursive[][file] = $dir.'/'.$file;
							$this -> Files[][file] = $file;
						}
					}
					else {

						$this -> FilesRecursive[][file] = $dir.'/'.$file;
						$this -> Files[][file] = $file;
					}
				}
				if(is_dir($dir.'/'.$file) && $file != '.' && $file != '..'){

					if($like && ($type == 'dir' || $type == 'both')){

						if(preg_match('/'.$like.'/i', $dir.'/'.$file)){

							$this -> Folders[][dir] = $file;
							$this -> FoldersRecursive[]['dir'] = $dir.'/'.$file;
							if($recursive == true)
								$this -> GetAllFiles($dir.'/'.$file, $like, $notlike, $type, $recursive);
						}
					}
					elseif($notlike && ($type == 'dir' || $type == 'both')){

						if(!preg_match('/'.$notlike.'/i', $dir.'/'.$file)){

							$this -> Folders[][dir] = $file;
							$this -> FoldersRecursive[]['dir'] = $dir.'/'.$file;
							if($recursive == true)
								$this -> GetAllFiles($dir.'/'.$file, $like, $notlike, $type, $recursive);
						}
					}
					else {

						$this -> Folders[][dir] = $file;
						$this -> FoldersRecursive[]['dir'] = $dir.'/'.$file;
						if($recursive == true)
							$this -> GetAllFiles($dir.'/'.$file, $like, $notlike, $type, $recursive);
					}
				}
			}
			closedir($dir_op);
		}
	}

	/**
	* search current filename
	* @param String $dir AS directory search from
	* @param String $like AS filename to search
	*/
	function SearchFile($dir, $like){

		$this->GetAllFiles($dir);
		$latest_file = '';
		foreach($this->FilesRecursive as $v){

			if(preg_match('/'.$like.'/i', $v['file']) && (   ($latest_file && $latest_file < filemtime($v['file'])) || !$latest_file  )){

				$file = $v['file'];
				$latest_file = filemtime($v['file']);
			}
		}
		return $file;
	}

	/**
	* read file lines to array
	* @param String $file AS filename
	* @return Array
	*/
	function ReadFileToLines($file){

		if(file_exists($file)){

			$lines = array();

			$handle = @fopen($file, "r"); // Open file form read.

			if ($handle){

				while (!feof($handle)) {

					$lines[] = fgets($handle, 4096); // Read a line.
				}
				fclose($handle); // Close the file.
			}
		}
		return $lines;
	}

	/**
	* write file
	* @param String $file AS filename
	* @param String $content AS file content
	* @param Integer $chmod=0775 
	* @param String $basedir='' AS location to write
	*/
	function WriteFile($file, $content, $chmod=0775, $basedir=''){

		if(!$basedir){
			$basedir = dirname($file);
			$file = basename($file);
		}

		$this->WriteDirectorRecursive($basedir, 0775);

		if($basedir){

			$expdir = explode('/', $dir);
			$basedirrec = '';
			foreach ($expdir as $v){

				if($v){

					$basedirrec .= '/'.$v;
					if(preg_match('/'.$basedir.'/i', $basedirrec)){

						@chmod($basedirrec, 0777);
					}
				}
			}
		}
		@chmod($basedir.'/'.$file, 0777);
		//$this->WriteFileOldStyle($basedir.'/'.$file, $content);
		file_put_contents($basedir.'/'.$file, $content);
		@chmod($basedir.'/'.$file, $chmod);
	}

	/**
	* write director
	* @param String $dir AS direcotry name /var/www/new folder
	* @param Integer $chmod=0775
	*/
	function WriteDirector($dir, $chmod=0775){

		if(!is_dir($dir)){

			@mkdir($dir) or $error='Cannot make dir: '.$dir;
			@chmod($dir, $chmod);
			if($error){

				echo $error;
			}
		}
	}

	/**
	* write directorys recursively
	* @param String $dir AS full directory list
	* @param Integer $chmod=0775
	*/
	function WriteDirectorRecursive($dir, $chmod=0775){

		$dir_construct = '';
		$exp = explode('/', $dir);
		foreach($exp as $v){

			$v = trim($v);

			if(isset($v)){

				$dir_construct .= '/'.$v;
				$this->WriteDirector($dir_construct, $chmod);
			}
		}
	}
	/**
	* copy files recursively
	* @param String $from
	* @param String $dest
	*/
	function copyRecursive($from, $dest){

		shell_exec( " cp -r -a ".$from."/* ".$dest." 2>&1 " );
	}

	/**
	* filemtime
	* @param String $file
	*/
	function FileModificationTime($file){

		if(file_exists($file)){

			return filemtime($file);
		}
		return 0;
	}

	/**
	* upload <form enctype="multipart/form-data"> file to current location
	* @param String $upload_name AS input nama
	* @param String $dir AS upload location
	* @param String $new_filename AS filename if empty then original name
	* @param Array $allow_upload_file_types=array() AS array('jpg', 'png', 'etc')
	* @param Integer $max_file_size=0 AS file min size
	*/
	function UploadFile($upload_name, $dir, $new_filename, $allow_upload_file_types=array(), $max_file_size=0){

		if($_FILES[$upload_name] && $_FILES[$upload_name]['size'] > 0){

			$this->WriteDirectorRecursive($dir, 0775);
			$exp = explode('.', $_FILES[$upload_name]['name']);
			$filetype = strtolower(trim($exp[count($exp)-1]));

			if($_FILES[$upload_name]['size'] > $max_file_size && $max_file_size > 0){

				$this->error = 'not allowed filesize';
				return true;
			}

			$new_filename = !$new_filename ? str_replace('.'.$filetype, '', $_FILES[$upload_name]['name']) : $new_filename;

			if(empty($allow_upload_file_types) || in_array($filetype, $allow_upload_file_types)){

				move_uploaded_file($_FILES[$upload_name]['tmp_name'], $dir.'/'.$new_filename. (!preg_match('/.'.$filetype.'/i', $new_filename) ? '.'.$filetype : '') );
				$this->filetype = $filetype;
			}
			else{

				$this->error = 'not allowed filetype';
			}
			return $new_filename.'.'.$filetype;
		}
	}

	/**
	* same as UploadFile but multiple <input name="file[]">
	* @param String $upload_name AS input name
	* @param String $dir AS upload folder location
	* @param String $new_filename AS new file name
	* @param Array $allow_upload_file_types=array()
	* @param Integer $max_file_size=0 AS max file size
	*/
	function UploadMultipleFile($upload_name, $dir, $new_filename, $allow_upload_file_types=array(), $max_file_size=0){

		$tmpFiles = $_FILES[$upload_name];
		unset($_FILES);
		foreach($tmpFiles['name'] as $k => $v){

			$_FILES[$upload_name]['name'] = $tmpFiles['name'][$k];
			$_FILES[$upload_name]['type'] = $tmpFiles['type'][$k];
			$_FILES[$upload_name]['tmp_name'] = $tmpFiles['tmp_name'][$k];
			$_FILES[$upload_name]['error'] = $tmpFiles['error'][$k];
			$_FILES[$upload_name]['size'] = $tmpFiles['size'][$k];
			$this->UploadFile($upload_name, $dir, $new_filename, $allow_upload_file_types, $max_file_size);
		}
	}

	/**
	* download file from another domain
	* @param String $file AS full url based file http://domain/image.png
	*/
	function DownloadFile($file){

		//First, see if the file exists
		if (!is_file($file)) {

			die("<b>404 File not found! $file</b>");
		}

		//Gather relevent info about file
		$len = filesize($file);
		$filename = basename($file);
		$file_extension = strtolower(substr(strrchr($filename,"."),1));

		//This will set the Content-Type to the appropriate setting for the file
		switch( $file_extension ) {

			case "pdf": $ctype="application/pdf"; break;
			case "exe": $ctype="application/octet-stream"; break;
			case "zip": $ctype="application/zip"; break;
			case "doc": $ctype="application/msword"; break;
			case "xls": $ctype="application/vnd.ms-excel"; break;
			case "ppt": $ctype="application/vnd.ms-powerpoint"; break;
			case "gif": $ctype="image/gif"; break;
			case "png": $ctype="image/png"; break;
			case "jpeg":
			case "jpg": $ctype="image/jpg"; break;
			case "mp3": $ctype="audio/mpeg"; break;
			case "wav": $ctype="audio/x-wav"; break;
			case "mpeg":
			case "mpg":
			case "mpe": $ctype="video/mpeg"; break;
			case "mov": $ctype="video/quicktime"; break;
			case "avi": $ctype="video/x-msvideo"; break;

			//The following are for extensions that shouldn't be downloaded (sensitive stuff, like php files)
			case "php":
			case "htm":
			case "html":
			case "txt": die("<b>Cannot be used for ". $file_extension ." files!</b>"); break;

			default: $ctype="application/force-download";
		}

		//Begin writing headers
		header("Pragma: public");
		header("Expires: 0");
		header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
		header("Cache-Control: public");
		header("Content-Description: File Transfer");

		//Use the switch-generated Content-Type
		header("Content-Type: $ctype");

		//Force the download
		$header="Content-Disposition: attachment; filename=".$filename.";";
		header($header );
		header("Content-Transfer-Encoding: binary");
		header("Content-Length: ".$len);
		@readfile($file);
	}
}

?>