helper_dir.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. <?php
  2. /** This file is part of KCFinder project
  3. *
  4. * @desc Directory helper class
  5. * @package KCFinder
  6. * @version 3.12
  7. * @author Pavel Tzonkov <sunhater@sunhater.com>
  8. * @copyright 2010-2014 KCFinder Project
  9. * @license http://opensource.org/licenses/GPL-3.0 GPLv3
  10. * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3
  11. * @link http://kcfinder.sunhater.com
  12. */
  13. namespace kcfinder;
  14. class dir {
  15. /** Checks if the given directory is really writable. The standard PHP
  16. * function is_writable() does not work properly on Windows servers
  17. * @param string $dir
  18. * @return bool */
  19. static function isWritable($dir) {
  20. $dir = path::normalize($dir);
  21. if (!is_dir($dir))
  22. return false;
  23. $i = 0;
  24. do {
  25. $file = "$dir/is_writable_" . md5($i++);
  26. } while (file_exists($file));
  27. if (!@touch($file))
  28. return false;
  29. unlink($file);
  30. return true;
  31. }
  32. /** Recursively delete the given directory. Returns TRUE on success.
  33. * If $firstFailExit parameter is true (default), the method returns the
  34. * path to the first failed file or directory which cannot be deleted.
  35. * If $firstFailExit is false, the method returns an array with failed
  36. * files and directories which cannot be deleted. The third parameter
  37. * $failed is used for internal use only.
  38. * @param string $dir
  39. * @param bool $firstFailExit
  40. * @param array $failed
  41. * @return mixed */
  42. static function prune($dir, $firstFailExit=true, array $failed=null) {
  43. if ($failed === null) $failed = array();
  44. $files = self::content($dir);
  45. if ($files === false) {
  46. if ($firstFailExit)
  47. return $dir;
  48. $failed[] = $dir;
  49. return $failed;
  50. }
  51. foreach ($files as $file) {
  52. if (is_dir($file)) {
  53. $failed_in = self::prune($file, $firstFailExit, $failed);
  54. if ($failed_in !== true) {
  55. if ($firstFailExit)
  56. return $failed_in;
  57. if (is_array($failed_in))
  58. $failed = array_merge($failed, $failed_in);
  59. else
  60. $failed[] = $failed_in;
  61. }
  62. } elseif (!@unlink($file)) {
  63. if ($firstFailExit)
  64. return $file;
  65. $failed[] = $file;
  66. }
  67. }
  68. if (!@rmdir($dir)) {
  69. if ($firstFailExit)
  70. return $dir;
  71. $failed[] = $dir;
  72. }
  73. return count($failed) ? $failed : true;
  74. }
  75. /** Get the content of the given directory. Returns an array with filenames
  76. * or FALSE on failure
  77. * @param string $dir
  78. * @param array $options
  79. * @return mixed */
  80. static function content($dir, array $options=null) {
  81. $defaultOptions = array(
  82. 'types' => "all", // Allowed: "all" or possible return values
  83. // of filetype(), or an array with them
  84. 'addPath' => true, // Whether to add directory path to filenames
  85. 'pattern' => '/./', // Regular expression pattern for filename
  86. 'followLinks' => true
  87. );
  88. if (!is_dir($dir) || !is_readable($dir))
  89. return false;
  90. if (strtoupper(substr(PHP_OS, 0, 3)) == "WIN")
  91. $dir = str_replace("\\", "/", $dir);
  92. $dir = rtrim($dir, "/");
  93. $dh = @opendir($dir);
  94. if ($dh === false)
  95. return false;
  96. if ($options === null)
  97. $options = $defaultOptions;
  98. foreach ($defaultOptions as $key => $val)
  99. if (!isset($options[$key]))
  100. $options[$key] = $val;
  101. $files = array();
  102. while (($file = @readdir($dh)) !== false) {
  103. if (($file == '.') || ($file == '..') ||
  104. !preg_match($options['pattern'], $file)
  105. )
  106. continue;
  107. $fullpath = "$dir/$file";
  108. $type = filetype($fullpath);
  109. // If file is a symlink, get the true type of its destination
  110. if ($options['followLinks'] && ($type == "link"))
  111. $type = filetype(realpath($fullpath));
  112. if (($options['types'] === "all") || ($type === $options['types']) ||
  113. (is_array($options['types']) && in_array($type, $options['types']))
  114. )
  115. $files[] = $options['addPath'] ? $fullpath : $file;
  116. }
  117. closedir($dh);
  118. usort($files, array(__NAMESPACE__ . "\\dir", "fileSort"));
  119. return $files;
  120. }
  121. static function fileSort($a, $b) {
  122. if (function_exists("mb_strtolower")) {
  123. $a = mb_strtolower($a);
  124. $b = mb_strtolower($b);
  125. } else {
  126. $a = strtolower($a);
  127. $b = strtolower($b);
  128. }
  129. if ($a == $b) return 0;
  130. return ($a < $b) ? -1 : 1;
  131. }
  132. }
  133. ?>