FilesUtil.php 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. <?php
  2. namespace PhpZip\Util;
  3. use PhpZip\Util\Iterator\IgnoreFilesFilterIterator;
  4. use PhpZip\Util\Iterator\IgnoreFilesRecursiveFilterIterator;
  5. /**
  6. * Files util.
  7. *
  8. * @author Ne-Lexa alexey@nelexa.ru
  9. * @license MIT
  10. */
  11. class FilesUtil
  12. {
  13. /**
  14. * Is empty directory
  15. *
  16. * @param string $dir Directory
  17. * @return bool
  18. */
  19. public static function isEmptyDir($dir)
  20. {
  21. if (!is_readable($dir)) {
  22. return false;
  23. }
  24. return count(scandir($dir)) === 2;
  25. }
  26. /**
  27. * Remove recursive directory.
  28. *
  29. * @param string $dir Directory path.
  30. */
  31. public static function removeDir($dir)
  32. {
  33. $files = new \RecursiveIteratorIterator(
  34. new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS),
  35. \RecursiveIteratorIterator::CHILD_FIRST
  36. );
  37. foreach ($files as $fileInfo) {
  38. $function = ($fileInfo->isDir() ? 'rmdir' : 'unlink');
  39. $function($fileInfo->getRealPath());
  40. }
  41. rmdir($dir);
  42. }
  43. /**
  44. * Convert glob pattern to regex pattern.
  45. *
  46. * @param string $globPattern
  47. * @return string
  48. */
  49. public static function convertGlobToRegEx($globPattern)
  50. {
  51. // Remove beginning and ending * globs because they're useless
  52. $globPattern = trim($globPattern, '*');
  53. $escaping = false;
  54. $inCurrent = 0;
  55. $chars = str_split($globPattern);
  56. $regexPattern = '';
  57. foreach ($chars as $currentChar) {
  58. switch ($currentChar) {
  59. case '*':
  60. $regexPattern .= ($escaping ? "\\*" : '.*');
  61. $escaping = false;
  62. break;
  63. case '?':
  64. $regexPattern .= ($escaping ? "\\?" : '.');
  65. $escaping = false;
  66. break;
  67. case '.':
  68. case '(':
  69. case ')':
  70. case '+':
  71. case '|':
  72. case '^':
  73. case '$':
  74. case '@':
  75. case '%':
  76. $regexPattern .= '\\' . $currentChar;
  77. $escaping = false;
  78. break;
  79. case '\\':
  80. if ($escaping) {
  81. $regexPattern .= "\\\\";
  82. $escaping = false;
  83. } else {
  84. $escaping = true;
  85. }
  86. break;
  87. case '{':
  88. if ($escaping) {
  89. $regexPattern .= "\\{";
  90. } else {
  91. $regexPattern = '(';
  92. $inCurrent++;
  93. }
  94. $escaping = false;
  95. break;
  96. case '}':
  97. if ($inCurrent > 0 && !$escaping) {
  98. $regexPattern .= ')';
  99. $inCurrent--;
  100. } elseif ($escaping) {
  101. $regexPattern = "\\}";
  102. } else {
  103. $regexPattern = "}";
  104. }
  105. $escaping = false;
  106. break;
  107. case ',':
  108. if ($inCurrent > 0 && !$escaping) {
  109. $regexPattern .= '|';
  110. } elseif ($escaping) {
  111. $regexPattern .= "\\,";
  112. } else {
  113. $regexPattern = ",";
  114. }
  115. break;
  116. default:
  117. $escaping = false;
  118. $regexPattern .= $currentChar;
  119. }
  120. }
  121. return $regexPattern;
  122. }
  123. /**
  124. * Search files.
  125. *
  126. * @param string $inputDir
  127. * @param bool $recursive
  128. * @param array $ignoreFiles
  129. * @return array Searched file list
  130. */
  131. public static function fileSearchWithIgnore($inputDir, $recursive = true, array $ignoreFiles = [])
  132. {
  133. $directoryIterator = $recursive ?
  134. new \RecursiveDirectoryIterator($inputDir) :
  135. new \DirectoryIterator($inputDir);
  136. if (!empty($ignoreFiles)) {
  137. $directoryIterator = $recursive ?
  138. new IgnoreFilesRecursiveFilterIterator($directoryIterator, $ignoreFiles) :
  139. new IgnoreFilesFilterIterator($directoryIterator, $ignoreFiles);
  140. }
  141. $iterator = $recursive ?
  142. new \RecursiveIteratorIterator($directoryIterator) :
  143. new \IteratorIterator($directoryIterator);
  144. $fileList = [];
  145. foreach ($iterator as $file) {
  146. if ($file instanceof \SplFileInfo) {
  147. $fileList[] = $file->getPathname();
  148. }
  149. }
  150. return $fileList;
  151. }
  152. /**
  153. * Search files from glob pattern.
  154. *
  155. * @param string $globPattern
  156. * @param int $flags
  157. * @param bool $recursive
  158. * @return array Searched file list
  159. */
  160. public static function globFileSearch($globPattern, $flags = 0, $recursive = true)
  161. {
  162. $flags = (int)$flags;
  163. $recursive = (bool)$recursive;
  164. $files = glob($globPattern, $flags);
  165. if (!$recursive) {
  166. return $files;
  167. }
  168. foreach (glob(dirname($globPattern) . '/*', GLOB_ONLYDIR | GLOB_NOSORT) as $dir) {
  169. $files = array_merge($files, self::globFileSearch($dir . '/' . basename($globPattern), $flags, $recursive));
  170. }
  171. return $files;
  172. }
  173. /**
  174. * Search files from regex pattern.
  175. *
  176. * @param string $folder
  177. * @param string $pattern
  178. * @param bool $recursive
  179. * @return array Searched file list
  180. */
  181. public static function regexFileSearch($folder, $pattern, $recursive = true)
  182. {
  183. $directoryIterator = $recursive ? new \RecursiveDirectoryIterator($folder) : new \DirectoryIterator($folder);
  184. $iterator = $recursive ? new \RecursiveIteratorIterator($directoryIterator) : new \IteratorIterator($directoryIterator);
  185. $regexIterator = new \RegexIterator($iterator, $pattern, \RegexIterator::MATCH);
  186. $fileList = [];
  187. foreach ($regexIterator as $file) {
  188. if ($file instanceof \SplFileInfo) {
  189. $fileList[] = $file->getPathname();
  190. }
  191. }
  192. return $fileList;
  193. }
  194. /**
  195. * Convert bytes to human size.
  196. *
  197. * @param int $size Size bytes
  198. * @param string|null $unit Unit support 'GB', 'MB', 'KB'
  199. * @return string
  200. */
  201. public static function humanSize($size, $unit = null)
  202. {
  203. if (($unit === null && $size >= 1 << 30) || $unit === "GB") {
  204. return number_format($size / (1 << 30), 2) . "GB";
  205. }
  206. if (($unit === null && $size >= 1 << 20) || $unit === "MB") {
  207. return number_format($size / (1 << 20), 2) . "MB";
  208. }
  209. if (($unit === null && $size >= 1 << 10) || $unit === "KB") {
  210. return number_format($size / (1 << 10), 2) . "KB";
  211. }
  212. return number_format($size) . " bytes";
  213. }
  214. /**
  215. * Normalizes zip path.
  216. *
  217. * @param string $path Zip path
  218. * @return string
  219. */
  220. public static function normalizeZipPath($path)
  221. {
  222. return implode(
  223. '/',
  224. array_filter(
  225. explode('/', (string)$path),
  226. static function ($part) {
  227. return $part !== '.' && $part !== '..';
  228. }
  229. )
  230. );
  231. }
  232. }