From 738f8385dc71b7de0b08247e11941b72bcebed23 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tim=20D=C3=BCsterhus?= Date: Thu, 18 Aug 2011 14:54:10 +0200 Subject: [PATCH] Improvements to DirectoryUtil - Adding missing namespaces to documentation - Moving FileUtil::unifyDirSeperator() into scanning to avoid duplicate work when fetching more than one list of file - Fixing indentation -> Now matching code guidelines - Some method moving -> More logical order - Removed destroy() in favor of clearCaches() --- .../files/lib/util/DirectoryUtil.class.php | 205 +++++++++--------- 1 file changed, 100 insertions(+), 105 deletions(-) diff --git a/wcfsetup/install/files/lib/util/DirectoryUtil.class.php b/wcfsetup/install/files/lib/util/DirectoryUtil.class.php index c0bf6813f8..5bad7831b4 100644 --- a/wcfsetup/install/files/lib/util/DirectoryUtil.class.php +++ b/wcfsetup/install/files/lib/util/DirectoryUtil.class.php @@ -4,7 +4,7 @@ use wcf\system\exception\SystemException; /** * Contains directory-related functions -* +* * @author Tim Düsterhus * @copyright 2011 Tim Düsterhus * @license GNU Lesser General Public License @@ -14,58 +14,89 @@ use wcf\system\exception\SystemException; */ class DirectoryUtil { /** - * @var DirectoryIterator | RecursiveDirectoryIterator + * @var \DirectoryIterator | \RecursiveDirectoryIterator */ protected $obj = null; - + /** * all files with full path + * * @var array */ protected $files = array(); - + /** * all files with filename as key and DirectoryIterator object as value - * @var array + * + * @var array<\DirectoryIterator> */ protected $filesObj = array(); - + /** * directory size in bytes + * * @var integer */ protected $size = 0; - + /** * directory path + * * @var string */ protected $directory = ''; - + /** * determines whether scan should be recursive + * * @var boolean */ protected $recursive = true; /** * indicates that files won't be sorted + * * @var integer */ const SORT_NONE = -1; - + /** * all recursive and non-recursive instances of DirectoryUtil - * @var array + * + * @var array */ protected static $instances = array( true => array(), // recursive instances false => array() // non-recursive instances ); - + + /** + * Returns an instance of DirectoryUtil (or child). + * + * @param string $directory path + * @param boolean $recursive walk through sub-directories too + * @return wcf\util\DirectoryUtil + */ + public static function getInstance($tmpDirectory, $recursive = true) { + $directory = realpath(FileUtil::unifyDirSeperator($tmpDirectory)); + // realpath returns false if the directory does not exist + if ($directory === false) { + throw new SystemException("Unknown directory '".$tmpDirectory."'"); + } + if (!is_dir($directory)) { + throw new SystemException("'".$tmpDirectory."' is no directory"); + } + + if (!isset(static::$instances[$recursive][$directory])) { + static::$instances[$recursive][$directory] = new static($directory, $recursive); + } + + return static::$instances[$recursive][$directory]; + } + /** * Creates a new instance of DirectoryUtil. - * + * * @param string $directory directory path * @param boolean $recursive created a recursive directory iterator * @see wcf\util\DirectoryUtil::getInstance() @@ -73,7 +104,7 @@ class DirectoryUtil { protected function __construct($directory, $recursive = true) { $this->directory = $directory; $this->recursive = $recursive; - + // handle iterator type if ($this->recursive) { $this->obj = new \RecursiveDirectoryIterator($directory); @@ -82,56 +113,15 @@ class DirectoryUtil { $this->obj = new \DirectoryIterator($directory); } } - + /** * @see wcf\util\DirectoryUtil::getInstance() */ private final function __clone() {} - - /** - * Clears an instance of DirectoryUtil. - * - * @param string $directory directory path - * @param boolean $recursive destroy a recursive instance - * @return boolean success - */ - public static function destroy($directory, $recursive = true) { - $directory = realpath(FileUtil::unifyDirSeperator($directory)); - if (!isset(static::$instances[$recursive][$directory])) { - return false; - } - - unset (static::$instances[$recursive][$directory]); - return true; - } - - /** - * Returns an instance of DirectoryUtil (or child). - * - * @param string $directory path - * @param boolean $recursive walk through sub-directories too - * @return static - */ - public static function getInstance($tmpDirectory, $recursive = true) { - $directory = realpath(FileUtil::unifyDirSeperator($tmpDirectory)); - // realpath returns false if the directory does not exist - if ($directory === false) { - throw new SystemException("Unknown directory '".$tmpDirectory."'"); - } - if (!is_dir($directory)) { - throw new SystemException("'".$tmpDirectory."' is no directory"); - } - - if (!isset(static::$instances[$recursive][$directory])) { - static::$instances[$recursive][$directory] = new static($directory, $recursive); - } - - return static::$instances[$recursive][$directory]; - } - + /** * Returns a sorted list of files. - * + * * @param integer $order sort-order * @param string $pattern pattern to match * @param boolean $negativeMatch true if the pattern should be inversed @@ -141,14 +131,14 @@ class DirectoryUtil { // scan the folder $this->scanFiles(); $files = $this->files; - + // sort out non matching files if (!empty($pattern)) { foreach ($files as $filename => $value) { - if (((bool) preg_match($pattern, FileUtil::unifyDirSeperator($filename))) == $negativeMatch) unset($files[$filename]); + if (((bool) preg_match($pattern, $filename)) == $negativeMatch) unset($files[$filename]); } } - + if ($order == SORT_DESC) { krsort($files, $order); } @@ -161,30 +151,30 @@ class DirectoryUtil { else { throw new SystemException('The given sorting is not supported'); } - + return $files; } - + /** * Returns a sorted list of files, with DirectoryIterator object as value - * + * * @param integer $order sort order * @param string $pattern pattern to match * @param boolean $negativeMatch should the pattern be inversed - * @return array + * @return array<\DirectoryIterator> */ public function getFilesObj($order = SORT_ASC, $pattern = '', $negativeMatch = false) { // scan the folder $this->scanFilesObj(); $objects = $this->filesObj; - + // sort out non matching files if (!empty($pattern)) { foreach ($objects as $filename => $value) { - if (((bool) preg_match($pattern, FileUtil::unifyDirSeperator($filename))) == $negativeMatch) unset($objects[$filename]); + if (((bool) preg_match($pattern, $filename)) == $negativeMatch) unset($objects[$filename]); } } - + if ($order == SORT_DESC) { krsort($objects, $order); } @@ -197,85 +187,85 @@ class DirectoryUtil { else { throw new SystemException('The given sorting is not supported'); } - + return $objects; } - + /** * Fills the list of available files */ protected function scanFiles() { // value is cached if (!empty($this->files)) return; - + if ($this->recursive) { $it = new \RecursiveIteratorIterator($this->obj, \RecursiveIteratorIterator::CHILD_FIRST); - + foreach ($it as $filename => $obj) { // ignore . and .. if ($it->isDot()) continue; - - $this->files[$filename] = $filename; + + $this->files[FileUtil::unifyDirSeperator($filename)] = FileUtil::unifyDirSeperator($filename); } } else { foreach ($this->obj as $obj) { // ignore . and .. if ($this->obj->isDot()) continue; - - $this->files[$obj->getFilename()] = $obj->getFilename(); + + $this->files[FileUtil::unifyDirSeperator($obj->getFilename())] = FileUtil::unifyDirSeperator($obj->getFilename()); } } - + // add the directory itself $this->filesObj[$this->directory] = $this->directory; } - + /** * Fills the list of available files, with DirectoryIterator object as value */ protected function scanFilesObj() { // value is cached if (!empty($this->filesObj)) return; - + if ($this->recursive) { $it = new \RecursiveIteratorIterator($this->obj, \RecursiveIteratorIterator::CHILD_FIRST); - + foreach ($it as $filename => $obj) { // ignore . and .. if ($it->isDot()) continue; - - $this->filesObj[$filename] = $obj; + + $this->filesObj[FileUtil::unifyDirSeperator($filename)] = $obj; } } else { foreach ($this->obj as $obj) { // ignore . and .. if ($this->obj->isDot()) continue; - - $this->filesObj[$obj->getFilename()] = $obj; + + $this->filesObj[FileUtil::unifyDirSeperator($obj->getFilename())] = $obj; } } - + // add the directory itself $this->filesObj[$this->directory] = new \SPLFileInfo($this->directory); } /** * Executes a callback on each file and returns false if callback is invalid. - * + * * @param callback $callback valid callback * @param string $pattern callback is only applied to files matching the given pattern * @return boolean */ public function executeCallback($callback, $pattern = '') { if (!is_callable($callback)) return false; - + $files = $this->getFilesObj(self::SORT_NONE, $pattern); foreach ($files as $filename => $obj) { call_user_func($callback, $filename, $obj); } - + return true; } @@ -288,22 +278,22 @@ class DirectoryUtil { // destroy cached instance unset(static::$instances[$this->recursive][$this->directory]); } - + /** * Removes all files that match the given pattern. - * + * * @param string $pattern pattern to match */ public function removePattern($pattern) { if (!$this->recursive) throw new SystemException('Removing of files only works in recursive mode'); - + $files = $this->getFilesObj(self::SORT_NONE, $pattern); - + foreach ($files as $filename => $obj) { if (!is_writable($obj->getPath())) { throw new SystemException("Could not remove directory: '".$obj->getPath()."' is not writable"); } - + if ($obj->isDir()) { rmdir($filename); } @@ -312,32 +302,37 @@ class DirectoryUtil { } } - // clear cache - $this->filesObj = array(); - $this->scanFilesObj(); - - $this->files = array(); - $this->scanFiles(); + $this->clearCaches(); } - + /** * Calculates the size of the directory. - * + * * @return integer directory size in bytes */ public function getSize() { - if (!$this->recursive) { - throw new SystemException('Calculating of size only works in recursive mode'); - } + if (!$this->recursive) throw new SystemException('Calculating of size only works in recursive mode'); // read cached value first if ($this->size) return $this->size; - + $files = $this->getFilesObj(self::SORT_NONE); foreach ($files as $obj) { $this->size += $obj->getSize(); } - + return $this->size; } + + /** + * Clears the caches of the current instance + */ + public function clearCaches() { + // clear cached list of files + $this->files = array(); + $this->filesObj = array(); + + // clear cached size + $this->size = 0; + } } -- 2.20.1