From 0cf76ccb4736473a958d9fd36ed914e2d25d594a Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Wed, 21 Oct 2020 13:12:15 +0200 Subject: Feature: add a Server administration page It contains mostly read only information about the current Shaarli instance, PHP version, extensions, file and folder permissions, etc. Also action buttons to clear the cache or sync thumbnails. Part of the content of this page is also displayed on the install page, to check server requirement before installing Shaarli config file. Fixes #40 Fixes #185 --- application/FileUtils.php | 56 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'application/FileUtils.php') diff --git a/application/FileUtils.php b/application/FileUtils.php index 30560bfc..3f940751 100644 --- a/application/FileUtils.php +++ b/application/FileUtils.php @@ -81,4 +81,60 @@ class FileUtils ) ); } + + /** + * Recursively deletes a folder content, and deletes itself optionally. + * If an excluded file is found, folders won't be deleted. + * + * Additional security: raise an exception if it tries to delete a folder outside of Shaarli directory. + * + * @param string $path + * @param bool $selfDelete Delete the provided folder if true, only its content if false. + * @param array $exclude + */ + public static function clearFolder(string $path, bool $selfDelete, array $exclude = []): bool + { + $skipped = false; + + if (!is_dir($path)) { + throw new IOException(t('Provided path is not a directory.')); + } + + if (!static::isPathInShaarliFolder($path)) { + throw new IOException(t('Trying to delete a folder outside of Shaarli path.')); + } + + foreach (new \DirectoryIterator($path) as $file) { + if($file->isDot()) { + continue; + } + + if (in_array($file->getBasename(), $exclude, true)) { + $skipped = true; + continue; + } + + if ($file->isFile()) { + unlink($file->getPathname()); + } elseif($file->isDir()) { + $skipped = static::clearFolder($file->getRealPath(), true, $exclude) || $skipped; + } + } + + if ($selfDelete && !$skipped) { + rmdir($path); + } + + return $skipped; + } + + /** + * Checks that the given path is inside Shaarli directory. + */ + public static function isPathInShaarliFolder(string $path): bool + { + $rootDirectory = dirname(dirname(__FILE__)); + + return strpos(realpath($path), $rootDirectory) !== false; + } } -- cgit v1.2.3