diff options
author | Yuchen Pei <hi@ypei.me> | 2021-10-14 15:16:42 +1100 |
---|---|---|
committer | Yuchen Pei <hi@ypei.me> | 2021-10-14 15:16:42 +1100 |
commit | 07f5140771388c9e0c8a99b0dd2e5d950bdb173b (patch) | |
tree | 323c00faef1edc7dea2e88ff581cc2258b2b6432 /Library/Files | |
parent | e119be145500700f3c465e12664403a07530a421 (diff) |
moving h-source subdir out.
Diffstat (limited to 'Library/Files')
-rw-r--r-- | Library/Files/Log.php | 114 | ||||
-rwxr-xr-x | Library/Files/Upload.php | 603 | ||||
-rw-r--r-- | Library/Files/index.html | 1 |
3 files changed, 718 insertions, 0 deletions
diff --git a/Library/Files/Log.php b/Library/Files/Log.php new file mode 100644 index 0000000..7eda7b7 --- /dev/null +++ b/Library/Files/Log.php @@ -0,0 +1,114 @@ +<?php + +// EasyGiant is a PHP framework for creating and managing dynamic content +// +// Copyright (C) 2009 - 2011 Antonio Gallo +// See COPYRIGHT.txt and LICENSE.txt. +// +// This file is part of EasyGiant +// +// EasyGiant is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// EasyGiant is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with EasyGiant. If not, see <http://www.gnu.org/licenses/>. + +if (!defined('EG')) die('Direct access not allowed!'); + +//class to manage a file di log +//this is a singleton class +class Files_Log +{ + + const DS = DIRECTORY_SEPARATOR; + + // array of instances of the class + //key: name of the instance, value:instance. The name of the instance is also the name of the log file to open + private static $instance = array(); + + public static $logFolder = './'; //the log folder + public static $logExtension = '.log'; //the extension of the log files + public static $logPermission = 0777; + + private $splFile; //SplFileObject + + //$fileName: the file to open + private function __construct($fileName) + { + $finalChar = self::$logFolder[strlen(self::$logFolder) - 1]; + if (strcmp($finalChar,self::DS) !== 0) self::$logFolder .= self::DS; + + $path = self::$logFolder . $fileName . self::$logExtension; + $this->splFile = new SplFileObject($path,'a+'); + //change the permission of the file + @chmod($path,self::$logPermission); + } + + // The singleton method + // $instanceName: name of the key of self::$instance. It is also the name of the log file to open + public static function getInstance($instanceName) + { + if (!isset(self::$instance[$instanceName])) { + $className = __CLASS__; + self::$instance[$instanceName] = new $className($instanceName); + } + + return self::$instance[$instanceName]; + } + + //write the string $string at the end of the file + public function writeString($string,$format = 'Y-m-d H:i:s') + { + $date = date($format); + $this->splFile->fwrite("[$date]\t".$string."\n"); + } + + //get the date string of the line $line + public function getDateString($line) + { + if (preg_match('/^[\[]{1}([a-zA-Z0-9:\-\s])*[\]]{1}/',$line,$match)) + { + $match[0] = str_replace('[',null,$match[0]); + $match[0] = str_replace(']',null,$match[0]); + return $match[0]; + } + else + { + return false; + } + } + + //delete all the lines older than a number of days equal to $days + public function clearBefore($days = 30) + { + $tempArray = array(); + $newTime = time() - (int)$days * 24 * 3600; + foreach ($this->splFile as $line) + { + $lineTime = strtotime($this->getDateString($line)); + if ($lineTime !== false and $lineTime > $newTime) + { + $tempArray[] = $line; + } + } + $this->splFile->ftruncate(0); + foreach ($tempArray as $row) + { + $this->splFile->fwrite($row); + } + } + + // Prevent users to clone the instance + public function __clone() + { + throw new Exception('error in '. __METHOD__.': clone is not allowed'); + } + +}
\ No newline at end of file diff --git a/Library/Files/Upload.php b/Library/Files/Upload.php new file mode 100755 index 0000000..7dbc7d1 --- /dev/null +++ b/Library/Files/Upload.php @@ -0,0 +1,603 @@ +<?php + +// EasyGiant is a PHP framework for creating and managing dynamic content +// +// Copyright (C) 2009 - 2011 Antonio Gallo +// See COPYRIGHT.txt and LICENSE.txt. +// +// This file is part of EasyGiant +// +// EasyGiant is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// EasyGiant is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with EasyGiant. If not, see <http://www.gnu.org/licenses/>. + +if (!defined('EG')) die('Direct access not allowed!'); + +//class to manage upload files +class Files_Upload +{ + + const DS = DIRECTORY_SEPARATOR; + + private $base = null; //root directory + private $directory = null; //current directory. Path relative to the base directory (Files_Upload::base) + private $parentDir = null; //parent folder + private $subDir = array(); //subdirectories of the current directory + private $relSubDir = array(); //subfolders of $this->directory. The path starts from the $base folder + private $files = array(); //files inside the current directory + private $relFiles = array(); //files inside $this->directory. The path starts from the $base directory + private $params; //class parameters + private $pattern = null; //the pattern for the preg_match function + + protected $_resultString; //reference to the class uploadStrings containing all the result strings + + public $fileName = null; //the name of the last file that has been uploaded + public $notice = null; //the result string of the operation + + public function __construct($base,$params = null, $directory = null) { + + $this->base = $this->addTrailingSlash($base); + + //set the match pattern + $tmp = str_replace(self::DS,'\\'.self::DS,$this->base); + $this->pattern = "/^(".$tmp.")/"; + + $defaultParams = array( + 'filesPermission' => 0777, + 'delFolderAction' => 'delFolderAction', + 'delFileAction' => 'delFileAction', + 'createFolderAction' => 'createFolderAction', + 'uploadFileAction' => 'uploadFileAction', + 'maxFileSize' => 3000000, + 'language' => 'En', + 'allowedExtensions' => 'jpg,jpeg,png,gif,txt', + 'allowedMimeTypes' => '', + 'fileUploadKey' => 'userfile', + 'fileUploadBehaviour' => 'add_token', //can be none or add_token + 'fileUploadBeforeTokenChar' => '_', + 'functionUponFileNane' => 'none', + 'createImage' => false, + ); + + //set the $this->scaffold->params array + if (is_array($params)) + { + foreach ($params as $key => $value) + { + $defaultParams[$key] = $value; + } + } + $this->params = $defaultParams; + + //instantiate the $_resultString object + $stringClass = 'Lang_'.$this->params['language'].'_UploadStrings'; + if (!class_exists($stringClass)) + { + $stringClass = 'Lang_En_UploadStrings'; + } + $this->_resultString = new $stringClass(); + + $this->setDirectory($directory); + + } + + //set a new value for one element of the $params array + public function setParam($key,$value) + { + if (array_key_exists($key,$this->params)) + { + $this->params[$key] = $value; + } + } + + //change a resulting string + public function setString($key,$value) + { + $this->_resultString->string[$key] = $value; + } + + //obtain the current directory + public function setDirectory($directory = null) + { + $relDir = (strcmp($directory,"") !== 0) ? $this->addTrailingSlash($directory) : null; + $absDir = $this->addTrailingSlash($this->base.$directory); + + if (is_dir($absDir)) + { + if ($this->isValidFolder($absDir)) + { + $this->directory = $relDir; + return true; + } + else + { + $this->notice = $this->_resultString->getString('not-child'); + } + } + else + { + $this->directory = null; + $this->notice = $this->_resultString->getString('not-dir'); + } + return false; + } + + //check if $folder is a folder and is subfolder of $this->base + protected function isValidFolder($folder) + { + if (is_dir($folder)) + { + $folder = $this->addTrailingSlash(realpath($folder)); + if ($this->isMatching($folder)) return true; + } + return false; + } + + protected function isMatching($path) + { + if (preg_match($this->pattern,$path)) + { + if (strstr($path,'..')) return false; + return true; + } + return false; + } + + public function getDirectory() { + return $this->directory; + } + + public function getBase() + { + return $this->base; + } + + public function setBase($path) + { + $this->base = $this->addTrailingSlash($path); + + //set the match pattern + $tmp = str_replace(self::DS,'\\'.self::DS,$this->base); + $this->pattern = "/^(".$tmp.")/"; + } + + public function getSubDir() { + return $this->subDir; + } + + public function getRelSubDir() + { + return $this->relSubDir; + } + + public function getFiles() { + return $this->files; + } + + public function getRelFiles() + { + return $this->relFiles; + } + + public function getParentDir() { + return $this->parentDir; + } + + //add the trailing slash to the string + protected function addTrailingSlash($string) + { + $finalChar = $string[strlen($string) - 1]; + if (strcmp($finalChar,self::DS) !== 0) + { + return $string.self::DS; + } + return $string; + } + + protected function urlDeep($dir) { #funzione per creare l'indirizzo completo della cartella all'interno della quale voglio entrare + #$dir:cartella all'interno della quale voglio entrare + return $this->base.$this->directory.$dir.self::DS; + } + + public function listFiles() { #creo la lista di file e cartelle all'interno della directory corrente + $items = scandir($this->base.$this->directory); + foreach( $items as $this_file ) { + if( strcmp($this_file,".") !== 0 && strcmp($this_file,"..") !== 0 ) { + if (is_dir($this->urlDeep($this_file))) { + $this->subDir[] = $this_file; + $this->relSubDir[] = $this->directory.$this_file; + } else { + $this->files[] = $this_file; + $this->relFiles[] = $this->directory.$this_file; + } + } + } + //get the parent dir + $this->parentDir(); + } + + //get the extension of the file + public function getFileExtension($file) + { + if (strstr($file,'.')) + { + return strtolower(end(explode('.', $file))); + } + return ''; + } + + //get the file name without the extension + public function getNameWithoutFileExtension($file) + { + if (strstr($file,'.')) + { + $copy = explode('.', $file); + array_pop($copy); + return implode('.',$copy); + } + return $file; + } + + //get a not existing file name if the one retrieved from the upload process already exists in the current directory + public function getUniqueName($file,$int = 0) + { + $fileNameWithoutExt = $this->getNameWithoutFileExtension($file); + $extension = $this->getFileExtension($file); + $token = $int === 0 ? null : $this->params['fileUploadBeforeTokenChar'].$int; + + $dotExt = strcmp($extension,'') !== 0 ? ".$extension" : null; + + $newName = $fileNameWithoutExt.$token.$dotExt; + if (!file_exists($this->base.$this->directory.$newName)) + { + return $newName; + } + else + { + return $this->getUniqueName($file,$int+1); + } + + } + + protected function parentDir() { #individuo la cartella madre + + $folders = explode(self::DS,$this->directory); + array_pop($folders); + array_pop($folders); + $parent = implode(self::DS,$folders); + $parent = (strcmp($parent,"") !== 0) ? $this->addTrailingSlash($parent) : null; + + if ($this->isValidFolder($this->base.$parent)) + { + $this->parentDir = $parent; + } + else + { + $this->parentDir = null; + } + } + + //create the $name subfolder of the $this->directory folder + public function createFolder($name) { #funzione per creare una cartella nella directory corrente + $name = basename($name); + if (strcmp(trim($name),'') !== 0) + { + if (is_writable($this->base.$this->directory)) + { + $path = $this->base.$this->directory.$name; + + if ($this->isMatching($path)) + { + if (!file_exists($path)) + { + if (@mkdir($path,$this->params['filesPermission'])) + { + @chmod($path, $this->params['filesPermission']); + $this->notice = $this->_resultString->getString('executed'); + return true; + } + else + { + $this->notice = $this->_resultString->getString('error'); + } + } + else + { + $this->notice = $this->_resultString->getString('dir-exists'); + } + } + else + { + $this->notice = $this->_resultString->getString('not-child'); + } + } + else + { + $this->notice = $this->_resultString->getString('not-writable'); + } + } + else + { + $this->notice = $this->_resultString->getString('no-folder-specified'); + } + return false; + } + + //check if the $name folder is empty or not + protected function isEmpty($name) + { + $items = scandir($name); + foreach( $items as $this_file ) { + if( strcmp($this_file,".") !== 0 && strcmp($this_file,"..") !== 0 ) { + return false; + } + } + return true; + } + + public function removeFile($name) + { + $name = basename($name); + if (strcmp(trim($name),'') !== 0) + { + $path = $this->base.$this->directory.$name; + if ($this->isMatching($path)) + { + if ($this->removeAbsFile($path)) return true; + } + else + { + $this->notice = $this->_resultString->getString('not-child'); + } + } + else + { + $this->notice = $this->_resultString->getString('no-file-specified'); + } + return false; + } + + //remove the $name file + protected function removeAbsFile($name) + { + if (strcmp(trim($name),'') !== 0) + { + if (is_writable($name)) + { + if (@unlink($name)) + { + $this->notice = $this->_resultString->getString('executed'); + return true; + } + else + { + $this->notice = $this->_resultString->getString('error'); + } + } + else + { + $this->notice = $this->_resultString->getString('not-writable-file'); + } + } + else + { + $this->notice = $this->_resultString->getString('no-file-specified'); + } + return false; + } + + public function removeFolder($name) + { + $name = basename($name); + if (strcmp(trim($name),'') !== 0) + { + $dir = $this->base.$this->directory.$name; + if ($this->isMatching($dir)) + { + if ($this->removeAbsFolder($dir)) return true; + } + else + { + $this->notice = $this->_resultString->getString('not-child'); + } + } + else + { + $this->notice = $this->_resultString->getString('no-folder-specified'); + } + return false; + } + + //remove the $name folder + protected function removeAbsFolder($name) { + if (strcmp(trim($name),'') !== 0) { + if (is_writable($name)) + { + if ($this->isEmpty($name)) + { + if (@rmdir($name)) + { + $this->notice = $this->_resultString->getString('executed'); + return true; + } + else + { + $this->notice = $this->_resultString->getString('error'); + } + } + else + { + $this->notice = $this->_resultString->getString('not-empty'); + } + } + else + { + $this->notice = $this->_resultString->getString('not-writable'); + } + } + else + { + $this->notice = $this->_resultString->getString('no-folder-specified'); + } + return false; + } + + //remove all the files that are not inside the $list argument + public function removeFilesNotInTheList($list = array()) + { + $this->listFiles(); + $files = $this->getFiles(); + foreach ($files as $file) + { + if (!in_array($file,$list)) + { + $this->removeFile($file); + } + } + } + + //upload a file in the current directory + //$fileName: name of the file + public function uploadFile($fileName = null) + { + $userfile = $this->params['fileUploadKey']; + + if(strcmp(trim($_FILES[$userfile]["name"]),"") !== 0) + { + $nameFromUpload = basename($_FILES[$userfile]["name"]); + + $ext = $this->getFileExtension($nameFromUpload); + $nameWithoutExtension = $this->getNameWithoutFileExtension($nameFromUpload); + + $dotExt = strcmp($ext,'') !== 0 ? ".$ext" : null; + + //check if the "functionUponFileNane" function exists + if (!function_exists($this->params['functionUponFileNane'])) { + throw new Exception('Error in <b>'.__METHOD__.'</b>: function <b>'.$this->params['functionUponFileNane']. '</b> does not exist'); + } + + //check if the fileinfo extension is loaded + if (strcmp($this->params['allowedMimeTypes'],'') !== 0 and !extension_loaded('fileinfo')) { + throw new Exception('Error in <b>'.__METHOD__.'</b>: no MIME type check is possible because the <b>fileinfo</b> extension is not loaded'); + } + + $nameWithoutExtension = call_user_func($this->params['functionUponFileNane'],$nameWithoutExtension); + + $fileName = isset($fileName) ? $fileName.$dotExt : $nameWithoutExtension.$dotExt; + + $this->fileName = $fileName; + + switch($this->params['fileUploadBehaviour']) + { + case 'none': + break; + case 'add_token': + $this->fileName = $this->getUniqueName($this->fileName); + $fileName = $this->fileName; + break; + } + + if(@is_uploaded_file($_FILES[$userfile]["tmp_name"])) { + if ($_FILES[$userfile]["size"] <= $this->params['maxFileSize']) + { + //check the extension of the file + $AllowedExtensionsArray = explode(',',$this->params['allowedExtensions']); + + if (strcmp($this->params['allowedExtensions'],'') === 0 or in_array($ext,$AllowedExtensionsArray)) + { + if (strcmp($this->params['allowedMimeTypes'],'') !== 0) + { + //get the MIME type of the file + $finfo = finfo_open(FILEINFO_MIME_TYPE); + $MIMEtype = finfo_file($finfo, $_FILES[$userfile]["tmp_name"]); + finfo_close($finfo); + } + + $AllowedMimeTypesArray = explode(',',$this->params['allowedMimeTypes']); + + if (strcmp($this->params['allowedMimeTypes'],'') === 0 or in_array($MIMEtype,$AllowedMimeTypesArray)) + { + //check if the file doesn't exist + if (!file_exists($this->base.$this->directory.$fileName)) + { + if (@move_uploaded_file($_FILES[$userfile]["tmp_name"],$this->base.$this->directory.$fileName)) + { + if ($this->params['createImage']) + { + //create the image + $basePath = $this->base.$this->directory; + $thumb = new Image_Gd_Thumbnail($basePath); + $thumb->render($fileName,$this->base.$this->directory.$fileName); + } + + @chmod($this->base.$this->directory.$fileName, $this->params['filesPermission']); + $this->notice = $this->_resultString->getString('executed'); + return true; + } + else + { + $this->notice = $this->_resultString->getString('error'); + } + } + else + { + $this->notice = $this->_resultString->getString('file-exists'); + } + } + else + { + $this->notice = $this->_resultString->getString('not-allowed-mime-type'); + } + } + else + { + $this->notice = $this->_resultString->getString('not-allowed-ext'); + } + } + else + { + $this->notice = $this->_resultString->getString('size-over'); + } + } + else + { + $this->notice = $this->_resultString->getString('no-upload-file'); + } + } + else + { + $this->notice = $this->_resultString->getString('no-upload-file'); + } + return false; + } + + //update the folder tree + public function updateTree() { + + if (isset($_POST[$this->params['delFolderAction']])) { + $this->removeFolder($_POST[$this->params['delFolderAction']]); + } + + if (isset($_POST[$this->params['delFileAction']])) { + $this->removeFile($_POST[$this->params['delFileAction']]); + } + + if (isset($_POST[$this->params['createFolderAction']])) { + $this->createFolder($_POST['folderName']); + } + + if (isset($_POST[$this->params['uploadFileAction']])) { + $this->uploadFile(); + } + + } +}
\ No newline at end of file diff --git a/Library/Files/index.html b/Library/Files/index.html new file mode 100644 index 0000000..8d1c8b6 --- /dev/null +++ b/Library/Files/index.html @@ -0,0 +1 @@ + |