This commit is contained in:
2025-10-04 11:46:59 +07:00
commit 97427d7cff
498 changed files with 47596 additions and 0 deletions

View File

@@ -0,0 +1,212 @@
<?php
namespace Hura8\System;
class FileSystem
{
/**
* The cache directory.
*
* @var string
*/
protected $directory;
/** @var int */
private $umask;
/**
* @param string $directory The cache directory.
* @param int $umask
*
* @throws \Exception
*/
public function __construct($directory, $umask = 0002)
{
// YES, this needs to be *before* createPathIfNeeded()
if (! is_int($umask)) {
throw new \Exception(sprintf(
'The umask parameter is required to be integer, was: %s',
gettype($umask)
));
}
$this->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;
}
}