umask = $umask; if (! $this->createPathIfNeeded($directory)) { throw new \Exception(sprintf( 'The directory "%s" does not exist and could not be created.', $directory )); } if (! is_writable($directory)) { throw new \Exception(sprintf( 'The directory "%s" is not writable.', $directory )); } // YES, this needs to be *after* createPathIfNeeded() $this->directory = realpath($directory); //$this->directoryStringLength = strlen($this->directory); //$this->isRunningOnWindows = defined('PHP_WINDOWS_VERSION_BUILD'); } /** * @description extract a zip file after it has been uploaded to the server * @param string $filename name of the zip file (abc.zip) * @param string $uploaded_zip_path path where it's uploaded to i.e /usr/.../tmp_upload/ * @param string $extract_target_path path where the zip files will be extracted to , if not provided the $uploaded_zip_path will be used * @return array [extracted_folder, test_folder_exist] */ public static function unzip(string $filename, string $uploaded_zip_path, string $extract_target_path = '') { $extract_path = $extract_target_path ?: $uploaded_zip_path; $zip = new \ZipArchive(); $x = $zip->open($uploaded_zip_path . DIRECTORY_SEPARATOR . $filename); if ($x === true) { $zip->extractTo($extract_path); // change this to the correct site path $zip->close(); } @unlink($uploaded_zip_path . DIRECTORY_SEPARATOR . $filename); $expected_result = $extract_path . DIRECTORY_SEPARATOR . str_replace(".zip", "", $filename); return array($expected_result, file_exists($expected_result)); } /** * @description scan a folder recursively and return all files with sub-path * @param string $folder full path /usr/local/.../ * @param array $file_list */ public static function scanDirRecursive(string $folder, array &$file_list = []) { $dir = opendir($folder); while(( $file = readdir($dir)) ) { if (( $file != '.' ) && ( $file != '..' )) { if ( is_dir($folder. '/' . $file) ) { FileSystem::scanDirRecursive($folder. '/' . $file, $file_list); } else { //$file_list[] = str_replace(PUBLIC_DIR . "/", "", $folder .'/'. $file); $file_list[] = $folder .'/'. $file; } } } closedir($dir); } //remove directory recursively public static function removeDir($dir) { if (is_dir($dir)) { $objects = scandir($dir); foreach ($objects as $object) { if ($object != "." && $object != "..") { if (is_dir($dir."/".$object)) { self::removeDir($dir."/".$object); } else { @unlink($dir."/".$object); } } } @rmdir($dir); } } public function getFile(string $filename) { $full_filepath = $this->getFilename($filename); if(file_exists($full_filepath)) { return file_get_contents($full_filepath); } return false; } public function getFileLastModifiedTime(string $filename) { $full_filepath = $this->getFilename($filename); if(file_exists($full_filepath)) { return filemtime($full_filepath); } return 0; } /** * Writes a string content to file in an atomic way. * * @param string $filename Path to the file where to write the data. * @param string $content The content to write * * @return bool TRUE on success, FALSE if path cannot be created, if path is not writable or an any other error. */ public function writeFile(string $filename, string $content) { $full_filepath = $this->getFilename($filename); $filepath = pathinfo($full_filepath, PATHINFO_DIRNAME); if (! $this->createPathIfNeeded($filepath)) { return false; } if (! is_writable($filepath)) { return false; } $tmpFile = tempnam($filepath, 'swap'); @chmod($tmpFile, 0666 & (~$this->umask)); if (file_put_contents($tmpFile, $content) !== false) { @chmod($tmpFile, 0666 & (~$this->umask)); if (@rename($tmpFile, $full_filepath)) { return true; } @unlink($tmpFile); } return false; } public function delete($filename) { $full_filepath = $this->getFilename($filename); return @unlink($full_filepath) || ! file_exists($full_filepath); } /** * @param string $filename * * @return string */ public function getFilename($filename) { return $this->directory . DIRECTORY_SEPARATOR . $filename ; } /** * Create path if needed. * * @return bool TRUE on success or if path already exists, FALSE if path cannot be created. */ private function createPathIfNeeded(string $path) { if (! is_dir($path)) { if (@mkdir($path, 0755 & (~$this->umask), true) === false && ! is_dir($path)) { return false; } } return true; } }