zfile.class.php 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. <?php
  2. /**
  3. * The zfile library of zentaopms.
  4. *
  5. * @copyright Copyright 2009-2015 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
  6. * @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
  7. * @author Chunsheng Wang <chunsheng@cnezsoft.com>
  8. * @package Zfile
  9. * @version $Id: zfile.class.php 2605 2013-01-09 07:22:58Z wwccss $
  10. * @link http://www.zentao.net
  11. */
  12. class zfile
  13. {
  14. /**
  15. * Copy a directory from an directory to another directory.
  16. *
  17. * @param string $from
  18. * @param string $to
  19. * @param bool $logLevel
  20. * @param string $logFile
  21. * @param array $excludeFiles
  22. * @param bool $toIsLink
  23. * @access public
  24. * @return array copied files, count, size or message.
  25. */
  26. public function copyDir($from, $to, $logLevel = false, $logFile = '', $excludeFiles = array(), $toIsLink = false)
  27. {
  28. if(is_file($from)) return false;
  29. static $copiedFiles = array();
  30. static $errorFiles = array();
  31. $count = $size = 0;
  32. $log['copiedFiles'] = array();
  33. $log['count'] = 0;
  34. $log['size'] = 0;
  35. if(!is_dir($from) or !is_readable($from))
  36. {
  37. if(!is_dir($from)) $log['message'] = "$from: Dir is not exists";
  38. if(!is_readable($from)) $log['message'] = "$from: Permission denied";
  39. }
  40. if(!is_dir($to) and !@mkdir($to, 0777, true)) $log['message'] = "$to: Permission denied";
  41. if($logFile and !file_exists($logFile)) touch($logFile);
  42. if(!empty($log['message'])) return $log;
  43. $from = realpath($from) . '/';
  44. if(is_link($to) || $toIsLink)
  45. {
  46. $to = $to . '/';
  47. $toIsLink = true;
  48. }
  49. else
  50. {
  51. $to = realpath($to) . '/';
  52. }
  53. $entries = scandir($from);
  54. foreach($entries as $entry)
  55. {
  56. if($entry == '.' or $entry == '..' or $entry == '.svn' or $entry == '.git' or in_array($entry, $excludeFiles)) continue;
  57. $fullEntry = $from . $entry;
  58. if(is_file($fullEntry))
  59. {
  60. if(is_dir($to) and !is_writeable($to)) $log['message'] = "$to: Permission denied";
  61. if(!empty($log['message'])) return $log;
  62. if(file_exists($to . $entry)) unlink($to . $entry);
  63. if(copy($fullEntry, $to . $entry))
  64. {
  65. if($logLevel) $copiedFiles[] = $to . $entry;
  66. $count += 1;
  67. $size += filesize($fullEntry);
  68. if($logFile and file_exists($logFile))
  69. {
  70. $summary = json_decode(file_get_contents($logFile), true);
  71. if(empty($summary)) $summary = array();
  72. if(empty($summary['count'])) $summary['count'] = 0;
  73. $summary['count'] += 1;
  74. file_put_contents($logFile, json_encode($summary));
  75. }
  76. }
  77. else
  78. {
  79. $errorFiles[] = $fullEntry;
  80. }
  81. }
  82. else
  83. {
  84. $nextFrom = $fullEntry;
  85. $nextTo = $to . $entry;
  86. $result = $this->copyDir($nextFrom, $nextTo, $logLevel, $logFile, array(), $toIsLink);
  87. $count += $result['count'];
  88. $size += $result['size'];
  89. }
  90. }
  91. if($logLevel) $log['copiedFiles'] = $copiedFiles;
  92. $log['errorFiles'] = $errorFiles;
  93. $log['count'] = $count;
  94. $log['size'] = $size;
  95. $log['logFile'] = $logFile;
  96. return $log;
  97. }
  98. /**
  99. * Get count.
  100. *
  101. * @param string $dir
  102. * @param array $excludeFiles
  103. * @access public
  104. * @return int
  105. */
  106. public function getCount($dir, $excludeFiles = array())
  107. {
  108. if(!file_exists($dir)) return 0;
  109. if(is_file($dir)) return 1;
  110. $count = 0;
  111. $entries = scandir($dir);
  112. foreach($entries as $entry)
  113. {
  114. if($entry == '.' or $entry == '..' or $entry == '.svn' or $entry == '.git' or in_array($entry, $excludeFiles)) continue;
  115. $fullEntry = $dir . '/' . $entry;
  116. $count += $this->getCount($fullEntry);
  117. }
  118. return $count;
  119. }
  120. /**
  121. * Remove a dir.
  122. *
  123. * @param string $dir
  124. * @access public
  125. * @return bool
  126. */
  127. public function removeDir($dir)
  128. {
  129. if(empty($dir)) return true;
  130. $dir = realpath($dir) . '/';
  131. if($dir == '/') return false;
  132. if(!is_writable($dir)) return false;
  133. if(!is_dir($dir)) return true;
  134. $entries = scandir($dir);
  135. foreach($entries as $entry)
  136. {
  137. if($entry == '.' or $entry == '..' or $entry == '.svn') continue;
  138. $fullEntry = $dir . $entry;
  139. if(is_file($fullEntry))
  140. {
  141. unlink($fullEntry);
  142. }
  143. else
  144. {
  145. $this->removeDir($fullEntry);
  146. }
  147. }
  148. if(!@rmdir($dir)) return false;
  149. return true;
  150. }
  151. /**
  152. * Get files under a directory recursive.
  153. *
  154. * @param string $dir
  155. * @param array $exceptions
  156. * @access private
  157. * @return array
  158. */
  159. public function readDir($dir, $exceptions = array())
  160. {
  161. static $files = array();
  162. if(!is_dir($dir)) return $files;
  163. $dir = realpath($dir) . '/';
  164. $entries = scandir($dir);
  165. foreach($entries as $entry)
  166. {
  167. if($entry == '.' or $entry == '..' or $entry == '.svn') continue;
  168. if(in_array($entry, $exceptions)) continue;
  169. $fullEntry = $dir . $entry;
  170. if(is_file($fullEntry))
  171. {
  172. $files[] = $dir . $entry;
  173. }
  174. else
  175. {
  176. $nextDir = $dir . $entry;
  177. $this->readDir($nextDir);
  178. }
  179. }
  180. return $files;
  181. }
  182. /**
  183. * Make a dir.
  184. *
  185. * @param string $dir
  186. * @access public
  187. * @return bool
  188. */
  189. public function mkdir($dir)
  190. {
  191. return mkdir($dir, 0755, true);
  192. }
  193. /**
  194. * Remove a file
  195. *
  196. * @param string $file
  197. * @access public
  198. * @return bool
  199. */
  200. public function removeFile($file)
  201. {
  202. if(!file_exists($file)) return true;
  203. return @unlink($file);
  204. }
  205. /**
  206. * Batch remove files. use glob function.
  207. *
  208. * @param string $patern
  209. * @access public
  210. * @return void
  211. */
  212. public function batchRemoveFile($patern)
  213. {
  214. $files = glob($patern);
  215. foreach($files as $file) @unlink($file);
  216. }
  217. /**
  218. * Remove a file
  219. *
  220. * @param string from
  221. * @param string to
  222. * @access public
  223. * @return bool
  224. */
  225. public function copyFile($from, $to)
  226. {
  227. return @copy($from, $to);
  228. }
  229. /**
  230. * Rename a file or directory.
  231. *
  232. * @param string from
  233. * @param string to
  234. * @access public
  235. * @return bool
  236. */
  237. public function rename($from, $to)
  238. {
  239. return rename($from, $to);
  240. }
  241. /**
  242. * Get file size.
  243. *
  244. * @param string $file
  245. * @access public
  246. * @return int
  247. */
  248. public function getFileSize($file)
  249. {
  250. return abs(filesize($file));
  251. }
  252. /**
  253. * Get directory size.
  254. *
  255. * @param string $dir
  256. * @access public
  257. * @return int
  258. */
  259. public function getDirSize($dir)
  260. {
  261. $size = 0;
  262. foreach(glob("$dir/*") as $file)
  263. {
  264. if(is_dir($file))
  265. {
  266. $size += $this->getDirSize($file);
  267. }
  268. else
  269. {
  270. $size += $this->getFileSize($file);
  271. }
  272. }
  273. return $size;
  274. }
  275. }