2015-05-05 03:00:01 +02:00
|
|
|
<?php defined('BLUDIT') or die('Bludit CMS.');
|
2015-03-08 18:02:59 +01:00
|
|
|
|
2015-05-31 03:06:55 +02:00
|
|
|
class Filesystem {
|
2015-03-08 18:02:59 +01:00
|
|
|
|
2015-09-20 23:46:50 +02:00
|
|
|
// Returns an array with the absolutes directories.
|
2017-06-26 22:50:56 +02:00
|
|
|
public static function listDirectories($path, $regex='*', $sortByDate=false)
|
2015-03-08 18:02:59 +01:00
|
|
|
{
|
2015-09-15 01:07:15 +02:00
|
|
|
$directories = glob($path.$regex, GLOB_ONLYDIR);
|
|
|
|
|
|
|
|
if(empty($directories)) {
|
|
|
|
return array();
|
|
|
|
}
|
|
|
|
|
2017-06-26 22:50:56 +02:00
|
|
|
if($sortByDate) {
|
2017-12-26 17:45:02 +01:00
|
|
|
usort($directories,
|
2017-12-06 19:14:33 +01:00
|
|
|
function($a, $b) {
|
|
|
|
return filemtime($b) - filemtime($a);
|
|
|
|
}
|
|
|
|
);
|
2017-06-26 22:50:56 +02:00
|
|
|
}
|
|
|
|
|
2015-09-15 01:07:15 +02:00
|
|
|
return $directories;
|
|
|
|
}
|
|
|
|
|
2017-12-26 17:45:02 +01:00
|
|
|
// Returns an array with the list of files with the absolute path
|
|
|
|
// $sortByDate = TRUE, the first file is the newer file
|
2018-04-04 23:46:36 +02:00
|
|
|
// $chunk = amount of chunks, FALSE if you don't want to chunk
|
|
|
|
public static function listFiles($path, $regex='*', $extension='*', $sortByDate=false, $chunk=false)
|
2015-09-15 01:07:15 +02:00
|
|
|
{
|
2020-03-14 12:03:43 +01:00
|
|
|
error_log($path.$regex.'.'.$extension);
|
2015-09-15 01:07:15 +02:00
|
|
|
$files = glob($path.$regex.'.'.$extension);
|
|
|
|
|
2017-11-16 23:22:55 +01:00
|
|
|
if (empty($files)) {
|
2015-09-15 01:07:15 +02:00
|
|
|
return array();
|
|
|
|
}
|
|
|
|
|
2017-11-16 23:22:55 +01:00
|
|
|
if ($sortByDate) {
|
2017-12-26 17:45:02 +01:00
|
|
|
usort($files,
|
2017-12-06 19:14:33 +01:00
|
|
|
function($a, $b) {
|
|
|
|
return filemtime($b) - filemtime($a);
|
|
|
|
}
|
|
|
|
);
|
2015-11-04 01:28:11 +01:00
|
|
|
}
|
|
|
|
|
2018-04-04 23:46:36 +02:00
|
|
|
// Split the list of files into chunks
|
|
|
|
// http://php.net/manual/en/function.array-chunk.php
|
|
|
|
if ($chunk) {
|
|
|
|
return array_chunk($files, $chunk);
|
|
|
|
}
|
|
|
|
|
2015-09-15 01:07:15 +02:00
|
|
|
return $files;
|
2015-03-08 18:02:59 +01:00
|
|
|
}
|
|
|
|
|
2015-05-05 03:00:01 +02:00
|
|
|
public static function mkdir($pathname, $recursive=false)
|
|
|
|
{
|
2018-10-06 19:39:34 +02:00
|
|
|
return mkdir($pathname, DIR_PERMISSIONS, $recursive);
|
2015-05-05 03:00:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public static function rmdir($pathname)
|
|
|
|
{
|
2019-05-27 19:07:53 +02:00
|
|
|
Log::set('rmdir = '.$pathname, LOG_TYPE_INFO);
|
2015-05-05 03:00:01 +02:00
|
|
|
return rmdir($pathname);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function mv($oldname, $newname)
|
|
|
|
{
|
2019-05-27 19:07:53 +02:00
|
|
|
Log::set('mv '.$oldname.' '.$newname, LOG_TYPE_INFO);
|
2015-05-05 03:00:01 +02:00
|
|
|
return rename($oldname, $newname);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function rmfile($filename)
|
|
|
|
{
|
2019-05-27 19:07:53 +02:00
|
|
|
Log::set('rmfile = '.$filename, LOG_TYPE_INFO);
|
2015-05-05 03:00:01 +02:00
|
|
|
return unlink($filename);
|
|
|
|
}
|
|
|
|
|
2017-06-29 22:13:25 +02:00
|
|
|
public static function fileExists($filename)
|
|
|
|
{
|
|
|
|
return file_exists($filename);
|
|
|
|
}
|
2017-07-02 18:55:27 +02:00
|
|
|
|
|
|
|
public static function directoryExists($path)
|
|
|
|
{
|
|
|
|
return file_exists($path);
|
|
|
|
}
|
|
|
|
|
2017-11-16 23:22:55 +01:00
|
|
|
// 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/
|
2018-03-07 15:43:41 +01:00
|
|
|
public static function copyRecursive($source, $destination, $skipDirectory=false)
|
2017-07-02 18:55:27 +02:00
|
|
|
{
|
2017-11-16 23:22:55 +01:00
|
|
|
$source = rtrim($source, DS);
|
|
|
|
$destination = rtrim($destination, DS);
|
|
|
|
|
|
|
|
// Check $source directory if exists
|
2017-10-02 23:17:32 +02:00
|
|
|
if (!self::directoryExists($source)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-11-16 23:22:55 +01:00
|
|
|
// Check $destionation directory if exists
|
|
|
|
if (!self::directoryExists($destination)) {
|
|
|
|
// Create the $destination directory
|
2018-10-06 19:39:34 +02:00
|
|
|
if (!mkdir($destination, DIR_PERMISSIONS, true)) {
|
2017-11-16 23:22:55 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2017-07-02 18:55:27 +02:00
|
|
|
|
2017-11-16 23:22:55 +01:00
|
|
|
foreach ($iterator = new RecursiveIteratorIterator(
|
2017-07-02 18:55:27 +02:00
|
|
|
new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS),
|
|
|
|
RecursiveIteratorIterator::SELF_FIRST) as $item) {
|
2018-03-07 15:43:41 +01:00
|
|
|
|
|
|
|
$currentDirectory = dirname($item->getPathName());
|
|
|
|
if ($skipDirectory !== $currentDirectory) {
|
|
|
|
if ($item->isDir()) {
|
|
|
|
@mkdir($destination.DS.$iterator->getSubPathName());
|
|
|
|
} else {
|
|
|
|
copy($item, $destination.DS.$iterator->getSubPathName());
|
|
|
|
}
|
|
|
|
}
|
2017-07-02 18:55:27 +02:00
|
|
|
}
|
2017-11-16 23:22:55 +01:00
|
|
|
|
2017-07-02 18:55:27 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-11-16 23:22:55 +01:00
|
|
|
// Delete a file or directory recursive
|
|
|
|
// The directory is delete
|
2018-09-26 17:55:19 +02:00
|
|
|
public static function deleteRecursive($source, $deleteDirectory=true)
|
2017-07-02 18:55:27 +02:00
|
|
|
{
|
2019-05-27 19:07:53 +02:00
|
|
|
Log::set('deleteRecursive = '.$source, LOG_TYPE_INFO);
|
|
|
|
|
2017-10-02 23:17:32 +02:00
|
|
|
if (!self::directoryExists($source)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-09-26 17:55:19 +02:00
|
|
|
foreach (new RecursiveIteratorIterator(
|
2017-07-02 18:55:27 +02:00
|
|
|
new RecursiveDirectoryIterator($source, FilesystemIterator::SKIP_DOTS),
|
|
|
|
RecursiveIteratorIterator::CHILD_FIRST) as $item) {
|
2019-05-27 19:07:53 +02:00
|
|
|
if ($item->isFile() || $item->isLink()) {
|
2017-07-02 18:55:27 +02:00
|
|
|
unlink($item);
|
|
|
|
} else {
|
|
|
|
rmdir($item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-26 17:55:19 +02:00
|
|
|
if ($deleteDirectory) {
|
|
|
|
return rmdir($source);
|
|
|
|
}
|
|
|
|
return true;
|
2017-07-02 18:55:27 +02:00
|
|
|
}
|
2017-10-29 20:27:52 +01:00
|
|
|
|
2017-11-16 23:22:55 +01:00
|
|
|
// Compress a file or directory
|
|
|
|
// $source = /home/diego/example
|
|
|
|
// $destionation = /tmp/example.zip
|
2017-10-29 20:27:52 +01:00
|
|
|
public static function zip($source, $destination)
|
|
|
|
{
|
2017-11-16 23:22:55 +01:00
|
|
|
if (!extension_loaded('zip')) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!file_exists($source)) {
|
2017-10-29 20:27:52 +01:00
|
|
|
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(str_replace($source, '', $file));
|
|
|
|
} elseif (is_file($file)) {
|
|
|
|
$zip->addFromString(str_replace($source, '', $file), file_get_contents($file));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} elseif (is_file($source)) {
|
|
|
|
$zip->addFromString(basename($source), file_get_contents($source));
|
|
|
|
}
|
|
|
|
|
|
|
|
return $zip->close();
|
|
|
|
}
|
|
|
|
|
2017-11-16 23:22:55 +01:00
|
|
|
// 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();
|
|
|
|
}
|
2018-04-13 23:32:29 +02:00
|
|
|
|
2019-04-07 20:43:42 +02:00
|
|
|
/*
|
|
|
|
| Returns the next filename if the filename already exist otherwise returns the original filename
|
|
|
|
|
|
|
|
|
| @path string Path
|
|
|
|
| @filename string Filename
|
|
|
|
|
|
|
|
|
| @return string
|
|
|
|
*/
|
2018-04-13 23:32:29 +02:00
|
|
|
public static function nextFilename($path=PATH_UPLOADS, $filename) {
|
|
|
|
// Clean filename and get extension
|
|
|
|
$fileExtension = pathinfo($filename, PATHINFO_EXTENSION);
|
2018-11-21 22:48:34 +01:00
|
|
|
$fileExtension = Text::lowercase($fileExtension);
|
2018-04-13 23:32:29 +02:00
|
|
|
$filename = pathinfo($filename, PATHINFO_FILENAME);
|
2019-01-15 19:53:04 +01:00
|
|
|
$filename = Text::removeSpaces($filename);
|
|
|
|
$filename = Text::removeQuotes($filename);
|
2018-04-13 23:32:29 +02:00
|
|
|
|
|
|
|
// Search for the next filename
|
|
|
|
$tmpName = $filename.'.'.$fileExtension;
|
|
|
|
if (Sanitize::pathFile($path.$tmpName)) {
|
|
|
|
$number = 0;
|
|
|
|
$tmpName = $filename.'_'.$number.'.'.$fileExtension;
|
|
|
|
while (Sanitize::pathFile($path.$tmpName)) {
|
2018-09-26 17:55:19 +02:00
|
|
|
$number = $number + 1;
|
2018-04-13 23:32:29 +02:00
|
|
|
$tmpName = $filename.'_'.$number.'.'.$fileExtension;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $tmpName;
|
|
|
|
}
|
2019-04-07 20:43:42 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
| 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);
|
|
|
|
}
|
2019-11-15 16:47:56 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get Size of file or directory in bytes
|
|
|
|
* @param [string] $fileOrDirectory
|
2020-02-26 22:28:05 +01:00
|
|
|
* @return [int|bool] [bytes or false on error]
|
2019-11-15 16:47:56 +01:00
|
|
|
*/
|
|
|
|
public static function getSize($fileOrDirectory) {
|
|
|
|
// Files
|
|
|
|
if (is_file($fileOrDirectory)) {
|
|
|
|
return filesize($fileOrDirectory);
|
|
|
|
}
|
|
|
|
// Directories
|
|
|
|
if (file_exists($fileOrDirectory)) {
|
|
|
|
$size = 0;
|
2020-02-26 22:28:05 +01:00
|
|
|
foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($fileOrDirectory, FilesystemIterator::SKIP_DOTS)) as $file){
|
2020-02-28 09:36:09 +01:00
|
|
|
try {
|
|
|
|
$size += $file->getSize();
|
|
|
|
} catch (Exception $e) {
|
|
|
|
// SplFileInfo::getSize RuntimeException will be thrown on broken symlinks/errors
|
|
|
|
}
|
2019-11-15 16:47:56 +01:00
|
|
|
}
|
|
|
|
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];
|
|
|
|
}
|
|
|
|
|
2020-03-14 12:03:43 +01:00
|
|
|
/*
|
|
|
|
| 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
|
|
|
|
*/
|
|
|
|
public static function mimeType($file) {
|
|
|
|
return mime_content_type($file);
|
|
|
|
}
|
|
|
|
|
2017-12-06 19:14:33 +01:00
|
|
|
}
|