Last active
June 29, 2022 18:41
-
-
Save ProjectOrangeBox/43e9823f44d61e2e959056fb9c8a5ac7 to your computer and use it in GitHub Desktop.
File System Wrappers based on ROOT folder
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* File System Functions | |
* | |
* File System Abstraction which automatically | |
* works in a given root path | |
* | |
* Can be added with composer by adding a composer.json file with: | |
* | |
*"autoload": { | |
* "files": ["src/fs.php"] | |
* } | |
*/ | |
class fs | |
{ | |
const JSONFLAGS = JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE; | |
protected static $rootPath = ''; | |
protected static $rootLength = 0; | |
protected static $autoGenerateDirectories = true; | |
protected static $exceptionOnMissing = true; | |
/** | |
* set application root directory | |
* | |
* @param string $path | |
* @return void | |
*/ | |
public static function setRoot(string $path, bool $chdir = true): void | |
{ | |
/* Returns canonicalized absolute pathname */ | |
$realpath = \realpath($path); | |
if (!$realpath) { | |
throw new \FileSystemException(__METHOD__ . ' "' . $path . '" is not a valid directory.'); | |
} | |
self::$rootPath = $realpath; | |
/* calculate it once here */ | |
self::$rootLength = \strlen($realpath); | |
if ($chdir) { | |
\chdir(self::$rootPath); | |
} | |
} | |
/** | |
* returns the current root | |
* | |
* @return string | |
*/ | |
public static function getRoot(): string | |
{ | |
return self::$rootPath; | |
} | |
public static function exceptionOnMissing(bool $bool = null): bool | |
{ | |
if (\is_bool($bool)) { | |
self::$exceptionOnMissing = $bool; | |
} | |
return self::$exceptionOnMissing; | |
} | |
public static function autoGenerateDirectories(bool $bool = null): bool | |
{ | |
if (\is_bool($bool)) { | |
self::$autoGenerateDirectories = $bool; | |
} | |
return self::$autoGenerateDirectories; | |
} | |
/** | |
* Format a given path so it's based on the applications root folder __ROOT__. | |
* | |
* Either add or remove __ROOT__ from path | |
* | |
* @param string $path | |
* @param bool $remove true | |
* @return string | |
*/ | |
public static function resolve(string $path, bool $remove = false): string | |
{ | |
if (!self::$rootPath) { | |
throw new \FileSystemException(__METHOD__ . ' root path is not defined. Use fs::setRoot(...).'); | |
} | |
/* strip it if root path is already present */ | |
$pathFromRoot = (\substr($path, 0, self::$rootLength) == self::$rootPath) ? \substr($path, self::$rootLength) : $path; | |
/* now resolve - stripped or added? */ | |
return ($remove) ? \rtrim($pathFromRoot, DIRECTORY_SEPARATOR) : self::$rootPath . DIRECTORY_SEPARATOR . \trim($pathFromRoot, DIRECTORY_SEPARATOR); | |
} | |
/** | |
* Method required | |
* | |
* @param string $path [explicite description] | |
* | |
* @return bool | |
*/ | |
public static function required(string $path): bool | |
{ | |
$path = self::resolve($path); | |
$success = \file_exists($path); | |
if (self::$exceptionOnMissing && !$success) { | |
throw new \FileSystemException('No such file or directory. ' . $path); | |
} | |
return $success; | |
} | |
/** | |
* @param string $path | |
* @return mixed | |
* @throws Exception | |
*/ | |
public static function require(string $path) | |
{ | |
return (self::required($path)) ? require(self::resolve($path)) : false; | |
} | |
/** | |
* @param string $path | |
* @return mixed | |
* @throws Exception | |
*/ | |
public static function require_once(string $path) | |
{ | |
return (self::required($path)) ? require_once(self::resolve($path)) : false; | |
} | |
public static function requireOnce(string $path) | |
{ | |
return self::require_once($path); | |
} | |
/** | |
* @param string $path | |
* @return mixed | |
* @throws Exception | |
*/ | |
public static function include(string $path) | |
{ | |
return (self::required($path)) ? include(self::resolve($path)) : false; | |
} | |
/** | |
* @param string $path | |
* @return mixed | |
* @throws Exception | |
*/ | |
public static function include_once(string $path) | |
{ | |
return (self::required($path)) ? include_once(self::resolve($path)) : false; | |
} | |
public static function includeOnce(string $path) | |
{ | |
return self::include_once($path); | |
} | |
/** | |
* Find pathnames matching a pattern | |
* | |
* @param string $pattern | |
* @param int $flags | |
* @param bool $recursive false | |
* @return array | |
*/ | |
public static function glob(string $pattern, int $flags = 0, bool $recursive = false, bool $strip = true): array | |
{ | |
$pattern = self::resolve($pattern); | |
if ($recursive) { | |
$files = self::globr($pattern, $flags, $strip); | |
} else { | |
$files = \glob($pattern, $flags); | |
$files = ($strip) ? self::stripRootPath($files) : $files; | |
} | |
return $files; | |
} | |
/** | |
* internal recursive loop for globr | |
* | |
* @param string $pattern | |
* @param int $flags | |
* @return array | |
*/ | |
public static function globr(string $pattern, int $flags = 0, bool $strip = true): array | |
{ | |
$pattern = self::resolve($pattern); | |
$files = \glob($pattern, $flags); | |
foreach (\glob(\dirname($pattern) . DIRECTORY_SEPARATOR . '*', GLOB_ONLYDIR | GLOB_NOSORT) as $directory) { | |
/* recursive loop */ | |
$files = \array_merge($files, self::globr($directory . DIRECTORY_SEPARATOR . \basename($pattern), $flags, $strip)); | |
} | |
return ($strip) ? self::stripRootPath($files) : $files; | |
} | |
/** | |
* Reads entire file into a string | |
* | |
* @param string $path | |
* @return string | |
*/ | |
public static function file_get_contents(string $path): string | |
{ | |
return (self::required($path)) ? \file_get_contents(self::resolve($path)) : ''; | |
} | |
public static function fileGetContents(string $path): string | |
{ | |
return self::file_get_contents($path); | |
} | |
/** | |
* Returns trailing name component of path | |
* | |
* @param string $path | |
* @param string $suffix | |
* @return string | |
*/ | |
public static function basename(string $path, string $suffix = ''): string | |
{ | |
return (self::required($path)) ? \basename(self::resolve($path), $suffix) : ''; | |
} | |
/** | |
* Returns information about a file path | |
* | |
* @param string $path | |
* @param int $options | |
* @return mixed | |
*/ | |
public static function pathinfo(string $path, int $options = PATHINFO_DIRNAME | PATHINFO_BASENAME | PATHINFO_EXTENSION | PATHINFO_FILENAME) /* mixed */ | |
{ | |
$pathinfo = ($options > 0) ? [] : ''; | |
if (self::required($path)) { | |
$pathinfo = \pathinfo(self::resolve($path), $options); | |
/* resolve path */ | |
if (\is_array($pathinfo)) { | |
if (isset($pathinfo['dirname'])) { | |
$pathinfo['dirname'] = self::resolve($pathinfo['dirname'], true); | |
} | |
} elseif ($options == PATHINFO_DIRNAME) { | |
$pathinfo = self::resolve($pathinfo, true); | |
} | |
} | |
return $pathinfo; | |
} | |
/** | |
* Reads a file and writes it to the output buffer. | |
* | |
* @param string $path | |
* @return int | |
*/ | |
public static function readfile(string $path) /* int|false */ | |
{ | |
return (self::required($path)) ? \readfile(self::resolve($path)) : false; | |
} | |
/** | |
* dirname — Returns a parent directory's path | |
* | |
* @param string $path | |
* @param int $levels The number of parent directories to go up. | |
* @return string | |
*/ | |
public static function dirname(string $path, int $levels = 1): string | |
{ | |
return (self::required($path)) ? self::resolve(\dirname(self::resolve($path, true), $levels), true) : ''; | |
} | |
/** | |
* filesize — Gets file size | |
* | |
* @param string $path | |
* @return int | |
*/ | |
public static function filesize(string $path): int | |
{ | |
return (self::required($path)) ? \filesize(self::resolve($path)) : 0; | |
} | |
/** | |
* is_dir — Tells whether the filename is a directory | |
* | |
* @param string $path | |
* @return bool | |
*/ | |
public static function is_dir(string $path): bool | |
{ | |
return (self::required($path)) ? \is_dir(self::resolve($path)) : false; | |
} | |
public static function isDir(string $path): bool | |
{ | |
return self::is_dir($path); | |
} | |
/** | |
* is_writable — Tells whether the filename is writable | |
* | |
* @param string $path | |
* @return bool | |
*/ | |
public static function is_writable(string $path): bool | |
{ | |
return (self::required($path)) ? \is_writable(self::resolve($path)) : false; | |
} | |
/** | |
* Method is_writeable | |
* | |
* @param string $path [explicite description] | |
* | |
* @return bool | |
*/ | |
public static function is_writeable(string $path): bool | |
{ | |
return self::is_writable($path); | |
} | |
public static function isWriteable(string $path): bool | |
{ | |
return self::is_writable($path); | |
} | |
/** | |
* chgrp — Changes file group | |
* | |
* @param string $path | |
* @param mixed $group | |
* @return bool | |
*/ | |
public static function chgrp(string $path, $group): bool | |
{ | |
return (self::required($path)) ? \chgrp(self::resolve($path), $group) : false; | |
} | |
/** | |
* Method changeGroup | |
* | |
* @param string $path [explicite description] | |
* @param $group $group [explicite description] | |
* | |
* @return bool | |
*/ | |
public static function changeGroup(string $path, $group): bool | |
{ | |
return self::chgrp($path, $group); | |
} | |
/** | |
* chmod — Changes file mode | |
* | |
* @param string $path | |
* @param int $mode | |
* @return bool | |
*/ | |
public static function chmod(string $path, int $mode): bool | |
{ | |
return (self::required($path)) ? \chmod(self::resolve($path), $mode) : false; | |
} | |
/** | |
* Method changeModify | |
* | |
* @param string $path [explicite description] | |
* @param int $mode [explicite description] | |
* | |
* @return bool | |
*/ | |
public static function changeModify(string $path, int $mode): bool | |
{ | |
return self::chmod($path, $mode); | |
} | |
/** | |
* chown — Changes file owner | |
* | |
* @param string $path | |
* @param string $user | |
* @return bool | |
*/ | |
public static function chown(string $path, string $user): bool | |
{ | |
return (self::required($path)) ? \chown(self::resolve($path), $user) : false; | |
} | |
/* wrapper */ | |
public static function changeOwner(string $path, string $user): bool | |
{ | |
return self::chown($path, $user); | |
} | |
/** | |
* is_file — Tells whether the filename is a regular file | |
* | |
* @param string $path | |
* @return bool | |
*/ | |
public static function is_file(string $path): bool | |
{ | |
return (self::required($path)) ? \is_file(self::resolve($path)) : false; | |
} | |
public static function isFile(string $path): bool | |
{ | |
return self::is_file($path); | |
} | |
/** | |
* fileatime — Gets last access time of file | |
* | |
* @param string $path | |
* @return int | |
*/ | |
public static function fileatime(string $path): int | |
{ | |
return (self::required($path)) ? \fileatime(self::resolve($path)) : 0; | |
} | |
/** | |
* filectime — Gets inode change time of file | |
* | |
* @param string $path | |
* @return int | |
*/ | |
public static function filectime(string $path): int | |
{ | |
return (self::required($path)) ? \filectime(self::resolve($path)) : 0; | |
} | |
/** | |
* filemtime — Gets file modification time | |
* | |
* @param string $path | |
* @return int | |
*/ | |
public static function filemtime(string $path): int | |
{ | |
return (self::required($path)) ? \filemtime(self::resolve($path)) : 0; | |
} | |
/** | |
* filegroup — Gets file group | |
* | |
* @param string $path | |
* @return int | |
*/ | |
public static function filegroup(string $path): int | |
{ | |
return (self::required($path)) ? \filegroup(self::resolve($path)) : 0; | |
} | |
/** | |
* fileowner — Gets file owner | |
* | |
* @param string $path | |
* @return int | |
*/ | |
public static function fileowner(string $path): int | |
{ | |
return (self::required($path)) ? \fileowner(self::resolve($path)) : 0; | |
} | |
/** | |
* fileperms — Gets file permissions | |
* | |
* @param string $path | |
* @return int | |
*/ | |
public static function fileperms(string $path): int | |
{ | |
return (self::required($path)) ? \fileperms(self::resolve($path)) : 0; | |
} | |
/** | |
* fileinode — Gets file inode | |
* | |
* @param string $path | |
* @return int | |
*/ | |
public static function fileinode(string $path): int | |
{ | |
return (self::required($path)) ? \fileinode(self::resolve($path)) : 0; | |
} | |
/** | |
* filetype — Gets file type | |
* | |
* @param string $path | |
* @return string | |
*/ | |
public static function filetype(string $path): string | |
{ | |
return (self::required($path)) ? \filetype(self::resolve($path)) : 0; | |
} | |
/** | |
* stat — Gives information about a file | |
* | |
* @param string $path | |
* @return array | |
* @throws Exception | |
*/ | |
public static function stat(string $path): array | |
{ | |
return (self::required($path)) ? \stat(self::resolve($path)) : []; | |
} | |
/** | |
* file_exists — Checks whether a file or directory exists | |
* | |
* @param string $path | |
* @return bool | |
*/ | |
public static function file_exists(string $path): bool | |
{ | |
return \file_exists(self::resolve($path)); | |
} | |
public static function fileExists(string $path): bool | |
{ | |
return self::file_exists($path); | |
} | |
/** | |
* file — Reads entire file into an array | |
* | |
* @param string $path | |
* @param int $flags | |
* @return array | |
*/ | |
public static function file(string $path, int $flags = 0): array | |
{ | |
return (self::required($path)) ? \file(self::resolve($path), $flags) : []; | |
} | |
/** | |
* fopen — Opens file or URL | |
* | |
* @param string $path | |
* @param string $mode | |
* @return resource | |
*/ | |
public static function fopen(string $path, string $mode) /* resource */ | |
{ | |
/* after you get back the resource there is no other reason to not use PHPs regular fclose, fgets, fwrite */ | |
return (self::required($path)) ? \fopen(self::resolve($path), $mode) : false; | |
} | |
/* wrapper */ | |
public static function fclose($handle) | |
{ | |
return \fclose($handle); | |
} | |
/* wrapper */ | |
public static function fwrite($handle, string $string, int $length = null): int | |
{ | |
return \fwrite($handle, $string, $length); | |
} | |
/* wrapper */ | |
public static function feof($stream): bool | |
{ | |
return \feof($stream); | |
} | |
/* wrapper */ | |
public static function fgetc($stream) | |
{ | |
return \fgetc($stream); | |
} | |
/* wrapper */ | |
public static function fgetcsv($stream, int $length = 0, string $separator = ",", string $enclosure = '"', string $escape = "\\"): array | |
{ | |
return \fgetcsv($stream, $length, $separator, $enclosure, $escape); | |
} | |
/* wrapper */ | |
public static function fgets($handle, int $length = null) | |
{ | |
return \fgets($handle, $length); | |
} | |
/* wrapper */ | |
public static function flock($stream, int $operation, int &$wouldBlock = null): bool | |
{ | |
return \flock($stream, $operation, $wouldBlock); | |
} | |
/* wrapper */ | |
public static function is_readable(string $path): bool | |
{ | |
return (self::required($path)) ? \is_readable(self::resolve($path)) : false; | |
} | |
public static function isReadable(string $path): bool | |
{ | |
return self::is_readable($path); | |
} | |
/** | |
* file_put_contents — Write data to a file | |
* | |
* This should have thrown an error before not being able to write a file_exists | |
* This writes the file in a atomic fashion unless you use $flags | |
* | |
* @param string $path | |
* @param mixed $content | |
* @param int $flags | |
* @return mixed returns the number of bytes that were written to the file, or FALSE on failure. | |
*/ | |
public static function file_put_contents(string $path, $content, int $flags = 0) /* mixed */ | |
{ | |
$bytes = 0; | |
/* if they aren't using any special flags just make it atomic that way locks aren't needed or partially written files aren't read */ | |
if ($flags != 0) { | |
$path = self::resolve($path); | |
if (self::$autoGenerateDirectories) { | |
self::makeDir(dirname($path)); | |
} | |
$bytes = \file_put_contents($path, $content, $flags); | |
} else { | |
$bytes = self::atomic_file_put_contents($path, $content); | |
} | |
return $bytes; | |
} | |
public static function filePutContents(string $path, $content, int $flags = 0) /* mixed */ | |
{ | |
return self::file_put_contents($path, $content, $flags); | |
} | |
/** | |
* unlink — Deletes a file | |
* | |
* @param string $path | |
* @return bool | |
*/ | |
public static function unlink(string $path): bool | |
{ | |
self::remove_php_file_from_opcache($path); | |
return (self::required($path)) ? \unlink(self::resolve($path)) : false; | |
} | |
/* wrapper */ | |
public static function delete(string $path): bool | |
{ | |
return self::unlink($path); | |
} | |
/** | |
* rmdir — Removes directory | |
* | |
* @param string $path | |
* @return bool | |
*/ | |
public static function rmdir(string $path, bool $recursive = false): bool | |
{ | |
$success = false; | |
if (self::required($path)) { | |
$path = self::resolve($path); | |
$success = ($recursive) ? self::_rmdir($path) : \rmdir($path); | |
} | |
return $success; | |
} | |
/** | |
* Method removeDir | |
* | |
* @param string $path [explicite description] | |
* | |
* @return bool | |
*/ | |
public static function removeDir(string $path): bool | |
{ | |
return self::rmdir($path, true); | |
} | |
/** | |
* Method _rmdir | |
* | |
* @param string $path [explicite description] | |
* | |
* @return bool | |
*/ | |
protected static function _rmdir(string $path): bool | |
{ | |
$success = false; | |
if (self::required($path)) { | |
$files = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::CHILD_FIRST); | |
foreach ($files as $fileinfo) { | |
$function = ($fileinfo->isDir() ? '_rmdir' : 'unlink'); | |
$function($fileinfo->getRealPath()); | |
} | |
$success = \rmdir($path); | |
} | |
return $success; | |
} | |
/** | |
* mkdir — Makes directory | |
* | |
* @param string $path | |
* @param int $mode | |
* @param bool $recursive | |
* @return bool | |
*/ | |
public static function mkdir(string $path, int $mode = 0777, bool $recursive = false): bool | |
{ | |
$path = self::resolve($path); | |
if (!\file_exists($path)) { | |
$umask = \umask(0); | |
$bool = \mkdir($path, $mode, $recursive); | |
\umask($umask); | |
} else { | |
$bool = true; | |
} | |
return $bool; | |
} | |
/* wrapper */ | |
public static function makeDir(string $path, int $mode = 0777): bool | |
{ | |
return self::mkdir($path, $mode, true); | |
} | |
/** | |
* rename — Renames a file or directory | |
* | |
* @param string $oldname | |
* @param string $newname | |
* @return bool | |
*/ | |
public static function rename(string $oldname, string $newname): bool | |
{ | |
return (self::required($oldname)) ? \rename(self::resolve($oldname), self::resolve($newname)) : false; | |
} | |
/* wrapper */ | |
public static function move(string $oldname, string $newname): bool | |
{ | |
return self::rename($oldname, $newname); | |
} | |
/** | |
* copy — Copies file | |
* | |
* @param string $source | |
* @param string $dest | |
* @return bool | |
*/ | |
public static function copy(string $source, string $dest): bool | |
{ | |
return (self::required($source)) ? \copy(self::resolve($source), self::resolve($dest)) : false; | |
} | |
/** | |
* Method copyFile | |
* | |
* @param string $source [explicite description] | |
* @param string $dest [explicite description] | |
* | |
* @return bool | |
*/ | |
public static function copyFile(string $source, string $dest): bool | |
{ | |
return (self::required($source)) ? self::copy($source, $dest) : false; | |
} | |
/** | |
* Method copyFolder | |
* | |
* @param string $source [explicite description] | |
* @param string $dest [explicite description] | |
* | |
* @return bool | |
*/ | |
public static function copyFolder(string $source, string $dest): bool | |
{ | |
$success = false; | |
if (self::required($source)) { | |
$source = self::resolve($source); | |
$dest = self::resolve($dest); | |
$dir = \opendir($source); | |
self::makeDir($dest); | |
while (false !== ($file = \readdir($dir))) { | |
if (($file != '.') && ($file != '..')) { | |
if (\is_dir($source . '/' . $file)) { | |
self::copyFolder($source . '/' . $file, $dest . '/' . $file); | |
} else { | |
\copy($source . '/' . $file, $dest . '/' . $file); | |
} | |
} | |
} | |
\closedir($dir); | |
$success = true; | |
} | |
return $success; | |
} | |
/** | |
* New (but used automatically by unlink and atomic_file_put_contents) | |
* | |
* Invalidates a cached script | |
* | |
* @param string $path | |
* @return bool | |
*/ | |
public static function remove_php_file_from_opcache(string $path): bool | |
{ | |
$path = self::resolve($path); | |
/* return true if the function doesn't exist */ | |
$success = true; | |
/* flush from the cache */ | |
if (\function_exists('opcache_invalidate')) { | |
$success = \opcache_invalidate($path, true); | |
} | |
return $success; | |
} | |
public static function removePhpFileFromOpcache(string $path): bool | |
{ | |
return self::remove_php_file_from_opcache($path); | |
} | |
/** | |
* New (but used automatically by file_put_contents when no flags are used) | |
* | |
* atomic_file_put_contents - atomic file_put_contents | |
* | |
* @param string $path | |
* @param mixed $content | |
* @return int returns the number of bytes that were written to the file. | |
*/ | |
public static function atomic_file_put_contents(string $path, $content): int | |
{ | |
/* create absolute path */ | |
$path = self::resolve($path); | |
if (self::$autoGenerateDirectories) { | |
self::makeDir(dirname($path)); | |
} | |
/* get the path where you want to save this file so we can put our file in the same directory */ | |
$dirname = \dirname($path); | |
/* is this directory writeable */ | |
if (!is_writable($dirname)) { | |
throw new \FileSystemException($dirname . ' is not writable.'); | |
} | |
/* create a temporary file with unique file name and prefix */ | |
$tmpfname = \tempnam($dirname, 'afpc_'); | |
/* did we get a temporary filename */ | |
if ($tmpfname === false) { | |
throw new \FileSystemException('Could not create temporary file ' . $tmpfname . '.'); | |
} | |
/* write to the temporary file */ | |
$bytes = \file_put_contents($tmpfname, $content); | |
/* did we write anything? */ | |
if ($bytes === false) { | |
throw new \FileSystemException('No bytes written by file_put_contents'); | |
} | |
/* changes file permissions so php user can read/write and everyone else read */ | |
if (\chmod($tmpfname, 0644) === false) { | |
throw new \FileSystemException('Could not chmod temporary file ' . $tmpfname . '.'); | |
} | |
/* move it into place - this is the atomic function */ | |
if (\rename($tmpfname, $path) === false) { | |
throw new \FileSystemException('Could not rename temporary file ' . $tmpfname . ' ' . $path . '.'); | |
} | |
/* if it's cached we need to flush it out so the old one isn't loaded */ | |
self::remove_php_file_from_opcache($path); | |
/* return the number of bytes written */ | |
return $bytes; | |
} | |
public static function atomicFilePutContents(string $path, $content): int | |
{ | |
return self::atomic_file_put_contents($path, $content); | |
} | |
/** | |
* Method stripRootPath | |
* | |
* @param string|array $files [array of file pathes or single file path] | |
* | |
* @return string|array | |
*/ | |
public static function stripRootPath($files) | |
{ | |
/* strip the root path */ | |
if (is_array($files)) { | |
$files = array_map(function ($file) { | |
return self::resolve($file, true); | |
}, $files); | |
} else { | |
$files = self::resolve($files, true); | |
} | |
return $files; | |
} | |
/** Export Array|Object to String */ | |
public static function varPhp($input): string | |
{ | |
$string = ''; | |
if (\is_array($input) || \is_object($input)) { | |
$string = '<?php return ' . \str_replace(['Closure::__set_state', 'stdClass::__set_state'], '(object)', \var_export($input, true)) . ';'; | |
} elseif (\is_scalar($input)) { | |
$string = '<?php return "' . \str_replace('"', '\"', $input) . '";'; | |
} else { | |
throw new \FileSystemException('Unknown input type.'); | |
} | |
return $string; | |
} | |
public static function varJson($input, bool $pretty = false, ?int $flags = null, ?int $depth = 512): string | |
{ | |
$flags = ($flags) ?? self::JSONFLAGS; | |
$depth = ($depth) ?? 512; | |
if ($pretty) { | |
$flags = $flags | JSON_PRETTY_PRINT; | |
} | |
return json_encode($input, $flags, $depth); | |
} | |
public static function varIni(array $array, array $parent = []): string | |
{ | |
$ini = ''; | |
foreach ($array as $key => $value) { | |
if (\is_array($value)) { | |
//subsection case | |
//merge all the sections into one array... | |
$subsection = \array_merge((array) $parent, (array) $key); | |
//add section information to the output | |
$ini .= '[' . \join('.', $subsection) . ']' . PHP_EOL; | |
//recursively traverse deeper | |
$ini .= self::varIni($value, $subsection); | |
} else { | |
//plain key->value case | |
$ini .= "$key=$value" . PHP_EOL; | |
} | |
} | |
return $ini; | |
} | |
/* read different file types */ | |
/** | |
* New | |
* | |
* var_import_file — import a var_export_file(...) file | |
* | |
* @param string $path | |
* @return mixed | |
* @throws Exception | |
*/ | |
public static function getFilePhp(string $path) | |
{ | |
$return = null; | |
if (self::required($path)) { | |
$return = include self::resolve($path); | |
} | |
return $return; | |
} | |
public static function getFileJson(string $path) | |
{ | |
$json = false; | |
if (self::required($path)) { | |
$json = json_decode(\file_get_contents(self::resolve($path)), true); | |
if ($json === null) { | |
throw new \FileSystemException('JSON file "' . $path . '" is not valid JSON.'); | |
} | |
} | |
return $json; | |
} | |
public static function getFileIni(string $path, bool $processSections = false, int $scannerMode = INI_SCANNER_NORMAL) | |
{ | |
return self::parse_ini_file($path, $processSections, $scannerMode); | |
} | |
/** | |
* parse_ini_file — Parse a configuration file | |
* | |
* @param string $path | |
* @param bool $process_sections create a multidimensional array | |
* @param int $scanner_mode INI_SCANNER_NORMAL, INI_SCANNER_RAW, INI_SCANNER_TYPED | |
* @return mixed | |
*/ | |
public static function parse_ini_file(string $path, bool $processSections = false, int $scannerMode = INI_SCANNER_NORMAL) /* mixed */ | |
{ | |
$ini = false; | |
if (self::required($path)) { | |
$ini = \parse_ini_file(self::resolve($path), $processSections, $scannerMode); | |
if (!$ini) { | |
throw new \FileSystemException('INI file "' . $path . '" is not valid.'); | |
} | |
} | |
return $ini; | |
} | |
/* save files */ | |
public static function putFileJson(string $path, $jsonObj, bool $pretty = false, ?int $flags = null, ?int $depth = 512, ?int $chmod = null): int | |
{ | |
return self::chmodOnWrite(self::atomic_file_put_contents($path, self::varJson($jsonObj, $pretty, $flags, $depth)), $path, $chmod); | |
} | |
public static function putFilePhp(string $path, $data, ?int $chmod = null): int | |
{ | |
return self::chmodOnWrite(self::atomic_file_put_contents($path, self::varPhp($data)), $path, $chmod); | |
} | |
public static function putFileIni(string $path, array $array, ?int $chmod = null): int | |
{ | |
return self::chmodOnWrite(self::atomic_file_put_contents($path, self::varIni($array)), $path, $chmod); | |
} | |
protected static function chmodOnWrite(int $bytes, string $path, ?int $chmod): int | |
{ | |
if ($bytes > 0 && $chmod) { | |
self::chmod($path, $chmod); | |
} | |
return $bytes; | |
} | |
/* auto detect reads and writes */ | |
public static function getFile(string $path, $arg1 = null, $arg2 = null) /* mixed */ | |
{ | |
$output = null; | |
switch (\pathinfo($path, PATHINFO_EXTENSION)) { | |
case 'ini': | |
$arg1 = ($arg1) ?? true; | |
$arg2 = ($arg2) ?? INI_SCANNER_TYPED; | |
$output = self::getFileIni($path, $arg1, $arg2); | |
break; | |
case 'json': | |
$output = self::getFileJson($path); | |
break; | |
case 'php': | |
$output = self::getFilePhp($path); | |
break; | |
default: | |
throw new FileSystemException('Unknown Type'); | |
} | |
return $output; | |
} | |
public static function putFile(string $path, $input, int $chmod = null, $arg1 = null): int | |
{ | |
switch (\pathinfo($path, PATHINFO_EXTENSION)) { | |
case 'ini': | |
$bytes = self::putFileIni($path, $input, $chmod); | |
break; | |
case 'json': | |
$arg1 = ($arg1) ?? false; | |
$bytes = self::putFileJson($path, $input, $arg1, null, null, $chmod); | |
break; | |
case 'php': | |
$bytes = self::putFilePhp($path, $input, $chmod); | |
break; | |
default: | |
throw new FileSystemException('Unknown Type'); | |
} | |
return $bytes; | |
} | |
} /* end class */ | |
class FileSystemException extends \Exception | |
{ | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment