PageRenderTime 50ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/phpmyfaq/admin/editor/plugins/ajaxfilemanager/inc/class.file.php

http://github.com/thorsten/phpMyFAQ
PHP | 452 lines | 302 code | 27 blank | 123 comment | 52 complexity | 8b927270b7a275b5ea9c18acc0b96b53 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.1, LGPL-3.0
  1. <?php
  2. if(!defined('AJAX_INIT_DONE'))
  3. {
  4. die('Permission denied');
  5. }
  6. ?><?php
  7. /**
  8. * file modification
  9. * @author Logan Cai (cailongqun [at] yahoo [dot] com [dot] cn)
  10. * @link www.phpletter.com
  11. * @since 22/April/2007
  12. *
  13. */
  14. class file
  15. {
  16. var $fileInfo = "";
  17. var $filePath = "";
  18. var $fileStat = "";
  19. var $mask = '0775';
  20. var $debug = false;
  21. var $errors = array();
  22. /**
  23. * constructor
  24. *
  25. * @param string $path the path to a file or folder
  26. */
  27. function __construct($path = null)
  28. {
  29. if(!is_null($path))
  30. {
  31. if(file_exists($path))
  32. {
  33. $this->filePath = $path;
  34. if(is_file($this->filePath))
  35. {
  36. $this->fileStat = @stat($path);
  37. $this->fileInfo['size'] = $this->fileStat[7];
  38. $this->fileInfo['atime'] = $this->fileStat[8];
  39. $this->fileInfo['ctime'] = $this->fileStat[10];
  40. $this->fileInfo['mtime'] = $this->fileStat[9];
  41. $this->fileInfo['path'] = $path;
  42. $this->fileInfo['name'] = basename($path);
  43. $this->fileInfo['is_writable'] = $this->isWritable();
  44. $this->fileInfo['is_readable'] = $this->isReadable();
  45. $imageSize = @getimagesize($path);
  46. if(is_array($imageSize) && !empty($imageSize))
  47. {
  48. $this->fileInfo['is_image'] = 1;
  49. $this->fileInfo['x'] = $imageSize[0];
  50. $this->fileInfo['y'] = $imageSize[1];
  51. }else
  52. {
  53. $this->fileInfo['is_image'] = 0;
  54. }
  55. }elseif(is_dir($this->filePath))
  56. {
  57. $this->fileStat = @stat($path);
  58. $this->fileInfo['name'] = basename($path);
  59. $this->fileInfo['path'] = $path;
  60. $this->fileInfo['atime'] = $this->fileStat[8];
  61. $this->fileInfo['ctime'] = $this->fileStat[10];
  62. $this->fileInfo['mtime'] = $this->fileStat[9];
  63. $this->fileInfo['is_writable'] = $this->isWritable();
  64. $this->fileInfo['is_readable'] = $this->isReadable();
  65. }
  66. }else
  67. {
  68. trigger_error('File does not exist ', E_USER_NOTICE);
  69. }
  70. }
  71. }
  72. /**
  73. * contructor
  74. *
  75. * @param string $path
  76. */
  77. function file($path=null)
  78. {
  79. $this->__construct($path);
  80. }
  81. /**
  82. * check if a file or folder writable
  83. *
  84. * @param file path $path
  85. * @return boolean
  86. */
  87. function isWritable($path=null)
  88. {
  89. $path = (is_null($path)?$this->filePath:$path);
  90. if (DIRECTORY_SEPARATOR == "\\")
  91. {
  92. $path = slashToBackslash($path);
  93. if(is_file($path))
  94. {
  95. $fp = @fopen($path,'ab');
  96. if($fp)
  97. {
  98. @fclose($fp);
  99. return true;
  100. }
  101. }elseif(is_dir($path))
  102. {
  103. $path = addTrailingSlash($path);
  104. $tmp = uniqid(time());
  105. if (@touch($path . $tmp))
  106. {
  107. @unlink($path . $tmp);
  108. return true;
  109. }
  110. }
  111. return false;
  112. }else
  113. {
  114. return @is_writable(slashToBackslash($path));
  115. }
  116. }
  117. /**
  118. * Returns true if the files is readable.
  119. *
  120. * @return boolean true if the files is readable.
  121. */
  122. function isReadable($path =null)
  123. {
  124. $path = is_null($path)?$this->filePath:$path;
  125. return @is_readable(slashToBackslash($path));
  126. }
  127. /**
  128. * change the modified time
  129. *
  130. * @param string $path
  131. * @param string $time
  132. * @return boolean
  133. */
  134. function setLastModified($path=null, $time)
  135. {
  136. $path = is_null($path)?$this->filePath:$path;
  137. $time = is_null($time)?time():$time;
  138. return @touch(slashToBackslash($path), $time);
  139. }
  140. /**
  141. * create a new folder
  142. *
  143. * @path the path for the new folder
  144. * @mask
  145. * @dirOwner
  146. * @return boolean
  147. */
  148. function mkdir($path = null, $mask=null, $dirOwner='')
  149. {
  150. $path = is_null($path)?$this->filePath:$path;
  151. if(!file_exists($path))
  152. {
  153. $mask = is_null($mask)?$this->mask:$mask;
  154. $status = @mkdir(slashToBackslash($path));
  155. if ($mask)
  156. {
  157. @chmod(slashToBackslash($path), intval($mask, 8));
  158. }
  159. if($dirOwner)
  160. {
  161. $this->chown(slashToBackslash($path), $dirOwner);
  162. }
  163. return $status;
  164. }
  165. return true;
  166. }
  167. /**
  168. * change the own of a file or folder
  169. *
  170. * @param the file path $path
  171. * @param $owner
  172. */
  173. function chown($path, $owner)
  174. {
  175. if(!empty($owner))
  176. {
  177. $owners = explode(":", $owner);
  178. if(!empty($owners[0]))
  179. @chown($path, $owners[0]);
  180. if(!empty($owners[1]))
  181. @chgrp($path, $owner[1]);
  182. }
  183. }
  184. /**
  185. * Copy a file, or recursively copy a folder and its contents
  186. * @author Aidan Lister <aidan@php.net>
  187. * @author Paul Scott
  188. * @version 1.0.1
  189. * @param string $source Source path
  190. * @param string $dest Destination path
  191. * @return bool Returns TRUE on success, FALSE on failure
  192. */
  193. function copyTo($source, $dest)
  194. {
  195. $source = removeTrailingSlash(backslashToSlash($source));
  196. $dest = removeTrailingSlash(backslashToSlash($dest));
  197. if(!file_exists($dest) || !is_dir($dest))
  198. {
  199. if(!$this->mkdir($dest))
  200. {
  201. $this->_debug('Unable to create folder (' . $dest . ")");
  202. return false;
  203. }
  204. }
  205. // Copy in to your self?
  206. if (getAbsPath($source) == getAbsPath($dest))
  207. {
  208. $this->_debug('Unable to copy itself. source: ' . getAbsPath($source) . "; dest: " . getAbsPath($dest));
  209. return false;
  210. }
  211. // Simple copy for a file
  212. if (is_file($source))
  213. {
  214. $dest = addTrailingSlash($dest) . (basename($source));
  215. if(file_exists($dest))
  216. {
  217. return false;
  218. }else {
  219. return copy($source, $dest);
  220. }
  221. }elseif(is_dir($source))
  222. {
  223. // Loop through the folder
  224. if(file_exists(addTrailingSlash($dest) . basename($source)))
  225. {
  226. return false;
  227. }else
  228. {
  229. if(!file_exists(addTrailingSlash($dest) . basename($source)) || !is_dir(addTrailingSlash($dest) . basename($source)))
  230. {
  231. if(!$this->mkdir(addTrailingSlash($dest) . basename($source)))
  232. {
  233. $this->_debug('Unable to create folder (' . addTrailingSlash($dest) . basename($source) . ")");
  234. return false;
  235. }
  236. }
  237. $handle = opendir($source);
  238. while(false !== ($readdir = readdir($handle)))
  239. {
  240. if($readdir != '.' && $readdir != '..')
  241. {
  242. $path = addTrailingSlash($source).'/'.$readdir;
  243. $this->copyTo($path, addTrailingSlash($dest) . basename($source));
  244. }
  245. }
  246. closedir($handle);
  247. return true;
  248. }
  249. }
  250. return false;
  251. }
  252. /**
  253. * get next available file name
  254. *
  255. * @param string $fileToMove the path of the file will be moved to
  256. * @param string $destFolder the path of destination folder
  257. * @return string
  258. */
  259. function getNextAvailableFileName($fileToMove, $destFolder)
  260. {
  261. $folderPath = addslashes(backslashToSlash(getParentPath($fileToMove)));
  262. $destFolder = addslashes(backslashToSlash(getParentPath($destFolder)));
  263. $finalPath = $destFolder . basename($fileToMove);
  264. if(file_exists($fileToMove))
  265. {
  266. if(is_file())
  267. {
  268. $fileExt = getFileExt($fileToMove);
  269. $fileBaseName = basename($fileToMove, '.' . $fileExt);
  270. $count = 1;
  271. while(file_exists($destFolder . $fileBaseName . $count . "." . $fileExt))
  272. {
  273. $count++;
  274. }
  275. $filePath = $destFolder . $fileBaseName . $count . "." . $fileExt;
  276. }elseif(is_dir())
  277. {
  278. $folderName = basename($fileToMove);
  279. $count = 1;
  280. while(file_exists($destFolder . $folderName . $count))
  281. {
  282. $count++;
  283. }
  284. $filePath = $destFolder . $fileBaseName . $count;
  285. }
  286. }
  287. return $finalPath;
  288. }
  289. /**
  290. * get file information
  291. *
  292. * @return array
  293. */
  294. function getFileInfo()
  295. {
  296. return $this->fileInfo;
  297. }
  298. /**
  299. * close
  300. *
  301. */
  302. function close()
  303. {
  304. $this->fileInfo = null;
  305. $this->fileStat = null;
  306. }
  307. /**
  308. * delete a file or a folder and all contents within that folder
  309. *
  310. * @param string $path
  311. * @return boolean
  312. */
  313. function delete($path = null)
  314. {
  315. $path = is_null($path)?$this->filePath:$path;
  316. if(file_exists($path))
  317. {
  318. if(is_file($path))
  319. {
  320. return @unlink($path);
  321. }elseif(is_dir($path))
  322. {
  323. return $this->__recursive_remove_directory($path);
  324. }
  325. }
  326. return false;
  327. }
  328. /**
  329. * empty a folder
  330. *
  331. * @param string $path
  332. * @return boolean
  333. */
  334. function emptyFolder($path)
  335. {
  336. $path = is_null($path)?$this->filePath:"";
  337. if(file_exists($path) && is_dir($path))
  338. {
  339. return $this->__recursive_remove_directory($path, true);
  340. }
  341. return false;
  342. }
  343. function _debug($info)
  344. {
  345. if($this->debug)
  346. {
  347. echo $info . "<br>\n";
  348. }else
  349. {
  350. $this->errors[] = $info;
  351. }
  352. }
  353. /**
  354. * recursive_remove_directory( directory to delete, empty )
  355. * expects path to directory and optional TRUE / FALSE to empty
  356. * of course PHP has to have the rights to delete the directory
  357. * you specify and all files and folders inside the directory
  358. *
  359. * to use this function to totally remove a directory, write:
  360. * recursive_remove_directory('path/to/directory/to/delete');
  361. * to use this function to empty a directory, write:
  362. * recursive_remove_directory('path/to/full_directory',TRUE);
  363. * @param string $directory
  364. * @param boolean $empty
  365. * @return boolean
  366. */
  367. function __recursive_remove_directory($directory, $empty=FALSE)
  368. {
  369. // if the path has a slash at the end we remove it here
  370. if(substr($directory,-1) == '/')
  371. {
  372. $directory = substr($directory,0,-1);
  373. }
  374. // if the path is not valid or is not a directory ...
  375. if(!file_exists($directory) || !is_dir($directory))
  376. {
  377. // ... we return false and exit the function
  378. return FALSE;
  379. // ... if the path is not readable
  380. }elseif(!is_readable($directory))
  381. {
  382. // ... we return false and exit the function
  383. return FALSE;
  384. // ... else if the path is readable
  385. }else{
  386. // we open the directory
  387. $handle = @opendir($directory);
  388. // and scan through the items inside
  389. while (FALSE !== ($item = @readdir($handle)))
  390. {
  391. // if the filepointer is not the current directory
  392. // or the parent directory
  393. if($item != '.' && $item != '..')
  394. {
  395. // we build the new path to delete
  396. $path = $directory.'/'.$item;
  397. // if the new path is a directory
  398. if(is_dir($path)) {
  399. // we call this function with the new path
  400. $this->__recursive_remove_directory($path);
  401. // if the new path is a file
  402. }else{
  403. // we remove the file
  404. @unlink($path);
  405. }
  406. }
  407. }
  408. // close the directory
  409. @closedir($handle);
  410. // if the option to empty is not set to true
  411. if($empty == FALSE)
  412. {
  413. // try to delete the now empty directory
  414. if(!@rmdir($directory))
  415. {
  416. // return false if not possible
  417. return FALSE;
  418. }
  419. }
  420. // return success
  421. return TRUE;
  422. }
  423. }
  424. }
  425. ?>