3 /** This file is part of KCFinder project
5 * @desc Directory helper class
8 * @author Pavel Tzonkov <pavelc@users.sourceforge.net>
9 * @copyright 2010, 2011 KCFinder Project
10 * @license http://www.opensource.org/licenses/gpl-2.0.php GPLv2
11 * @license http://www.opensource.org/licenses/lgpl-2.1.php LGPLv2
12 * @link http://kcfinder.sunhater.com
17 /** Checks if the given directory is really writable. The standard PHP
18 * function is_writable() does not work properly on Windows servers
22 static function isWritable($dir) {
23 $dir = path::normalize($dir);
28 $file = "$dir/is_writable_" . md5($i++);
29 } while (file_exists($file));
36 /** Recursively delete the given directory. Returns TRUE on success.
37 * If $firstFailExit parameter is true (default), the method returns the
38 * path to the first failed file or directory which cannot be deleted.
39 * If $firstFailExit is false, the method returns an array with failed
40 * files and directories which cannot be deleted. The third parameter
41 * $failed is used for internal use only.
43 * @param bool $firstFailExit
44 * @param array $failed
47 static function prune($dir, $firstFailExit=true, array $failed=null) {
48 if ($failed === null) $failed = array();
49 $files = self::content($dir);
50 if ($files === false) {
57 foreach ($files as $file) {
59 $failed_in = self::prune($file, $firstFailExit, $failed);
60 if ($failed_in !== true) {
63 if (is_array($failed_in))
64 $failed = array_merge($failed, $failed_in);
66 $failed[] = $failed_in;
68 } elseif (!@unlink($file)) {
81 return count($failed) ? $failed : true;
84 /** Get the content of the given directory. Returns an array with filenames
87 * @param array $options
90 static function content($dir, array $options=null) {
92 $defaultOptions = array(
93 'types' => "all", // Allowed: "all" or possible return values
94 // of filetype(), or an array with them
95 'addPath' => true, // Whether to add directory path to filenames
96 'pattern' => '/./', // Regular expression pattern for filename
100 if (!is_dir($dir) || !is_readable($dir))
103 if (strtoupper(substr(PHP_OS, 0, 3)) == "WIN")
104 $dir = str_replace("\\", "/", $dir);
105 $dir = rtrim($dir, "/");
107 $dh = @opendir($dir);
111 if ($options === null)
112 $options = $defaultOptions;
114 foreach ($defaultOptions as $key => $val)
115 if (!isset($options[$key]))
116 $options[$key] = $val;
119 while (($file = @readdir($dh)) !== false) {
120 $type = filetype("$dir/$file");
122 if ($options['followLinks'] && ($type === "link")) {
123 $lfile = "$dir/$file";
125 $ldir = dirname($lfile);
126 $lfile = @readlink($lfile);
127 if (substr($lfile, 0, 1) != "/")
128 $lfile = "$ldir/$lfile";
129 $type = filetype($lfile);
130 } while ($type == "link");
133 if ((($type === "dir") && (($file == ".") || ($file == ".."))) ||
134 !preg_match($options['pattern'], $file)
138 if (($options['types'] === "all") || ($type === $options['types']) ||
139 ((is_array($options['types'])) && in_array($type, $options['types']))
141 $files[] = $options['addPath'] ? "$dir/$file" : $file;
144 usort($files, "dir::fileSort");
148 static function fileSort($a, $b) {
149 if (function_exists("mb_strtolower")) {
150 $a = mb_strtolower($a);
151 $b = mb_strtolower($b);
156 if ($a == $b) return 0;
157 return ($a < $b) ? -1 : 1;