-
This commit is contained in:
@@ -0,0 +1,358 @@
|
||||
<?php defined('BLUDIT') or die('Bludit CMS.');
|
||||
|
||||
class Filesystem
|
||||
{
|
||||
|
||||
// Returns an array with the absolutes directories.
|
||||
public static function listDirectories($path, $regex = '*', $sortByDate = false)
|
||||
{
|
||||
$directories = glob($path . $regex, GLOB_ONLYDIR);
|
||||
|
||||
if (empty($directories)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
if ($sortByDate) {
|
||||
usort(
|
||||
$directories,
|
||||
function ($a, $b) {
|
||||
return filemtime($b) - filemtime($a);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return $directories;
|
||||
}
|
||||
|
||||
// Returns an array with the list of files with the absolute path
|
||||
// $sortByDate = TRUE, the first file is the newer file
|
||||
// $chunk = amount of chunks, FALSE if you don't want to chunk
|
||||
public static function listFiles($path, $regex = '*', $extension = '*', $sortByDate = false, $chunk = false)
|
||||
{
|
||||
$files = glob($path . $regex . '.' . $extension);
|
||||
|
||||
if (empty($files)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
if ($sortByDate) {
|
||||
usort(
|
||||
$files,
|
||||
function ($a, $b) {
|
||||
return filemtime($b) - filemtime($a);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Split the list of files into chunks
|
||||
// http://php.net/manual/en/function.array-chunk.php
|
||||
if ($chunk) {
|
||||
return array_chunk($files, $chunk);
|
||||
}
|
||||
|
||||
return $files;
|
||||
}
|
||||
|
||||
public static function mkdir($pathname, $recursive = false)
|
||||
{
|
||||
Log::set('mkdir ' . $pathname . ' recursive = ' . $recursive, LOG_TYPE_INFO);
|
||||
return mkdir($pathname, DIR_PERMISSIONS, $recursive);
|
||||
}
|
||||
|
||||
public static function rmdir($pathname)
|
||||
{
|
||||
Log::set('rmdir = ' . $pathname, LOG_TYPE_INFO);
|
||||
return rmdir($pathname);
|
||||
}
|
||||
|
||||
public static function mv($oldname, $newname)
|
||||
{
|
||||
Log::set('mv ' . $oldname . ' ' . $newname, LOG_TYPE_INFO);
|
||||
// Try renaming first (faster, works on same filesystem)
|
||||
if (@rename($oldname, $newname)) {
|
||||
return true;
|
||||
}
|
||||
// Fallback to copy+delete for cross-partition moves
|
||||
if (copy($oldname, $newname)) {
|
||||
if (unlink($oldname)) {
|
||||
return true;
|
||||
}
|
||||
// Copy succeeded but delete failed - remove the copy to avoid duplicates
|
||||
@unlink($newname);
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function rmfile($filename)
|
||||
{
|
||||
Log::set('rmfile = ' . $filename, LOG_TYPE_INFO);
|
||||
return unlink($filename);
|
||||
}
|
||||
|
||||
public static function fileExists($filename)
|
||||
{
|
||||
return file_exists($filename);
|
||||
}
|
||||
|
||||
public static function directoryExists($path)
|
||||
{
|
||||
return file_exists($path);
|
||||
}
|
||||
|
||||
// Copy recursive a directory to another
|
||||
// If the destination directory not exists is created
|
||||
// $source = /home/diego/example or /home/diego/example/
|
||||
// $destination = /home/diego/newplace or /home/diego/newplace/
|
||||
public static function copyRecursive($source, $destination, $skipDirectory = false)
|
||||
{
|
||||
$source = rtrim($source, DS);
|
||||
$destination = rtrim($destination, DS);
|
||||
|
||||
// Check $source directory if exists
|
||||
if (!self::directoryExists($source)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check $destionation directory if exists
|
||||
if (!self::directoryExists($destination)) {
|
||||
// Create the $destination directory
|
||||
if (!mkdir($destination, DIR_PERMISSIONS, true)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($iterator = new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS),
|
||||
RecursiveIteratorIterator::SELF_FIRST
|
||||
) as $item) {
|
||||
|
||||
$currentDirectory = dirname($item->getPathName());
|
||||
if ($skipDirectory !== $currentDirectory) {
|
||||
if ($item->isDir()) {
|
||||
@mkdir($destination . DS . $iterator->getSubPathName());
|
||||
} else {
|
||||
copy($item, $destination . DS . $iterator->getSubPathName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Delete a file or directory recursive
|
||||
// The directory is deleted
|
||||
public static function deleteRecursive($source, $deleteDirectory = true)
|
||||
{
|
||||
Log::set('deleteRecursive = ' . $source, LOG_TYPE_INFO);
|
||||
|
||||
if (!self::directoryExists($source)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($source, FilesystemIterator::SKIP_DOTS),
|
||||
RecursiveIteratorIterator::CHILD_FIRST
|
||||
) as $item) {
|
||||
if ($item->isFile() || $item->isLink()) {
|
||||
unlink($item);
|
||||
} else {
|
||||
rmdir($item);
|
||||
}
|
||||
}
|
||||
|
||||
if ($deleteDirectory) {
|
||||
return rmdir($source);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Compress a file or directory
|
||||
// $source = /home/diego/example
|
||||
// $destionation = /tmp/example.zip
|
||||
public static function zip($source, $destination)
|
||||
{
|
||||
if (!extension_loaded('zip')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!file_exists($source)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$zip = new ZipArchive();
|
||||
if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_dir($source) === true) {
|
||||
$iterator = new RecursiveDirectoryIterator($source);
|
||||
$iterator->setFlags(RecursiveDirectoryIterator::SKIP_DOTS);
|
||||
$files = new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::SELF_FIRST);
|
||||
|
||||
foreach ($files as $file) {
|
||||
$file = realpath($file);
|
||||
if (is_dir($file)) {
|
||||
$zip->addEmptyDir(ltrim(str_replace($source, '', $file), "/\\"));
|
||||
} elseif (is_file($file)) {
|
||||
$zip->addFromString(ltrim(str_replace($source, '', $file), "/\\"), file_get_contents($file));
|
||||
}
|
||||
}
|
||||
} elseif (is_file($source)) {
|
||||
$zip->addFromString(basename($source), file_get_contents($source));
|
||||
}
|
||||
|
||||
return $zip->close();
|
||||
}
|
||||
|
||||
// Uncompress a zip file
|
||||
// $source = /home/diego/example.zip
|
||||
// $destionation = /home/diego/content
|
||||
public static function unzip($source, $destination)
|
||||
{
|
||||
if (!extension_loaded('zip')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!file_exists($source)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$zip = new ZipArchive();
|
||||
if (!$zip->open($source)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$zip->extractTo($destination);
|
||||
return $zip->close();
|
||||
}
|
||||
|
||||
/*
|
||||
| Returns the next filename if the filename already exist otherwise returns the original filename
|
||||
|
|
||||
| @path string Path
|
||||
| @filename string Filename
|
||||
|
|
||||
| @return string
|
||||
*/
|
||||
public static function nextFilename($filename, $path = PATH_UPLOADS)
|
||||
{
|
||||
// Clean filename and get extension
|
||||
$fileExtension = pathinfo($filename, PATHINFO_EXTENSION);
|
||||
$fileExtension = Text::lowercase($fileExtension);
|
||||
$filename = pathinfo($filename, PATHINFO_FILENAME);
|
||||
$filename = Text::removeSpaces($filename);
|
||||
$filename = Text::removeQuotes($filename);
|
||||
|
||||
// Search for the next filename
|
||||
$tmpName = $filename . '.' . $fileExtension;
|
||||
if (Sanitize::pathFile($path . $tmpName)) {
|
||||
$number = 0;
|
||||
$tmpName = $filename . '_' . $number . '.' . $fileExtension;
|
||||
while (Sanitize::pathFile($path . $tmpName)) {
|
||||
$number = $number + 1;
|
||||
$tmpName = $filename . '_' . $number . '.' . $fileExtension;
|
||||
}
|
||||
}
|
||||
return $tmpName;
|
||||
}
|
||||
|
||||
/*
|
||||
| Returns the filename
|
||||
| Example:
|
||||
| @file /home/diego/dog.jpg
|
||||
| @return dog.jpg
|
||||
|
|
||||
| @file string Full path of the file
|
||||
|
|
||||
| @return string
|
||||
*/
|
||||
public static function filename($file)
|
||||
{
|
||||
return basename($file);
|
||||
}
|
||||
|
||||
/*
|
||||
| Returns the file extension
|
||||
| Example:
|
||||
| @file /home/diego/dog.jpg
|
||||
| @return jpg
|
||||
|
|
||||
| @file string Full path of the file
|
||||
|
|
||||
| @return string
|
||||
*/
|
||||
public static function extension($file)
|
||||
{
|
||||
return pathinfo($file, PATHINFO_EXTENSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Size of file or directory in bytes
|
||||
* @param [string] $fileOrDirectory
|
||||
* @return [int|bool] [bytes or false on error]
|
||||
*/
|
||||
public static function getSize($fileOrDirectory)
|
||||
{
|
||||
// Files
|
||||
if (is_file($fileOrDirectory)) {
|
||||
return filesize($fileOrDirectory);
|
||||
}
|
||||
// Directories
|
||||
if (file_exists($fileOrDirectory)) {
|
||||
$size = 0;
|
||||
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($fileOrDirectory, FilesystemIterator::SKIP_DOTS)) as $file) {
|
||||
try {
|
||||
$size += $file->getSize();
|
||||
} catch (Exception $e) {
|
||||
// SplFileInfo::getSize RuntimeException will be thrown on broken symlinks/errors
|
||||
}
|
||||
}
|
||||
return $size;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function bytesToHumanFileSize($bytes, $decimals = 2)
|
||||
{
|
||||
$size = array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
|
||||
$factor = floor((strlen($bytes) - 1) / 3);
|
||||
return sprintf("%.{$decimals}f ", $bytes / pow(1024, $factor)) . @$size[$factor];
|
||||
}
|
||||
|
||||
/*
|
||||
| Returns the mime type of the file
|
||||
| Example:
|
||||
| @file /home/diego/dog.jpg
|
||||
| @return image/jpeg
|
||||
|
|
||||
| @file [string] Full path of the file
|
||||
|
|
||||
| @return [string|bool] Mime type as string or FALSE if not possible to get the mime type
|
||||
*/
|
||||
public static function mimeType($file)
|
||||
{
|
||||
if (function_exists('mime_content_type')) {
|
||||
return mime_content_type($file);
|
||||
}
|
||||
|
||||
if (function_exists('finfo_file')) {
|
||||
$fileinfo = finfo_open(FILEINFO_MIME_TYPE);
|
||||
$mimeType = finfo_file($fileinfo, $file);
|
||||
finfo_close($fileinfo);
|
||||
return $mimeType;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function symlink($from, $to)
|
||||
{
|
||||
if (function_exists('symlink')) {
|
||||
Log::set('symlink from = ' . $from . ' to = ' . $to, LOG_TYPE_INFO);
|
||||
return symlink($from, $to);
|
||||
} else {
|
||||
return copy($from, $to);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user