PageRenderTime 44ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/bluebox/helpers/filesystem.php

https://github.com/robertleeplummerjr/bluebox
PHP | 272 lines | 166 code | 43 blank | 63 comment | 36 complexity | 0d041c368fd086add067a54a588c4e67 MD5 | raw file
  1. <?php defined('SYSPATH') or die('No direct access allowed.');
  2. /**
  3. * @package Core/Helpers/Filesystem
  4. * @author K Anderson <bitbashing@gmail.com>
  5. * @license Mozilla Public License (MPL)
  6. */
  7. class filesystem
  8. {
  9. /**
  10. * Recursively create a directory
  11. * Retrieved from http://us2.php.net/function.mkdir on July 18, 2009 by K Anderson
  12. *
  13. * @author bat at flurf dot net
  14. * @param string $dir the full directory to create
  15. * @param int $mode the mode to use during creation
  16. * @return bool true on success, otherwise false
  17. */
  18. public static function createDirectory($dir, $mode = 0755)
  19. {
  20. if (is_dir($dir) || @mkdir($dir, $mode, TRUE))
  21. {
  22. return TRUE;
  23. }
  24. if (!self::createDirectory(dirname($dir) , $mode))
  25. {
  26. return FALSE;
  27. }
  28. return @mkdir($dir, $mode, TRUE);
  29. }
  30. /**
  31. * Copy a file, or recursively copy a folder and its contents
  32. *
  33. * @author Aidan Lister <aidan@php.net> modified by K Anderson
  34. * @version 1.0.1
  35. * @link http://aidanlister.com/repos/v/function.copyr.php
  36. * @param string $source Source path
  37. * @param string $dest Destination path
  38. * @return bool Returns TRUE on success, FALSE on failure
  39. */
  40. public static function copy($source, $dest, $mode = 0755, $flags = array(), $ignore = array())
  41. {
  42. if (is_link($dest) || is_file($dest))
  43. {
  44. if (!empty($flags['overwrite']))
  45. {
  46. kohana::log('debug', 'Instructed not to overwrite ' . basename($dest));
  47. return NULL;
  48. }
  49. if (!empty($flags['update']))
  50. {
  51. if (filemtime($dest) > filemtime($source))
  52. {
  53. kohana::log('debug', 'Existing copy of ' . basename($dest) . ' is newer');
  54. return NULL;
  55. }
  56. kohana::log('debug', 'Found ' . $source . ' to be a newer copy of ' . $dest);
  57. }
  58. }
  59. // Check for symlinks
  60. if (is_link($source))
  61. {
  62. kohana::log('debug', 'Creating symlink of ' . basename($dest));
  63. return symlink(readlink($source) , $dest);
  64. }
  65. // Simple copy for a file
  66. if (is_file($source))
  67. {
  68. kohana::log('debug', 'Copying ' . basename($dest));
  69. return copy($source, $dest);
  70. }
  71. // Make destination directory
  72. if (!is_dir($dest))
  73. {
  74. self::createDirectory($dest, $mode);
  75. }
  76. // Loop through the folder
  77. $dir = @dir($source);
  78. if (!$dir)
  79. {
  80. kohana::log('error', 'Unable to read from ' . $source);
  81. return FALSE;
  82. }
  83. while (false !== $entry = $dir->read())
  84. {
  85. // Skip pointers
  86. if ($entry == '.' || $entry == '..' || in_array($entry, $ignore))
  87. {
  88. continue;
  89. }
  90. // Deep copy directories
  91. self::copy($source .DIRECTORY_SEPARATOR .$entry, $dest .DIRECTORY_SEPARATOR .$entry, $mode, $flags);
  92. }
  93. // Clean up
  94. $dir->close();
  95. return true;
  96. }
  97. /**
  98. * This function takes a guess as to if a file is a binary file
  99. * (jpeg, mp3, exe, ect). It should not be relied upon...
  100. *
  101. * @param string $file
  102. * @param string $blk Used by the internal function during recursion
  103. * @return bool
  104. */
  105. public static function is_binary($file, $blk = NULL)
  106. {
  107. if (!is_null($blk))
  108. {
  109. $blk = substr($blk, 0, 512);
  110. }
  111. else
  112. {
  113. if (!file_exists($file))
  114. {
  115. return 0;
  116. }
  117. if (!is_file($file))
  118. {
  119. return 0;
  120. }
  121. $fh = fopen($file, "r");
  122. $blk = fread($fh, 512);
  123. fclose($fh);
  124. clearstatcache();
  125. }
  126. if (substr_count($blk, "\x00") > 0)
  127. {
  128. return TRUE;
  129. }
  130. $blk = preg_replace('/[^\x00-\x08\x0B\x0E-\x1F]*/','', $blk);
  131. if (strlen($blk) > 2)
  132. {
  133. return TRUE;
  134. }
  135. return FALSE;
  136. }
  137. /**
  138. * Recursive delete
  139. *
  140. * @param string $dir
  141. * @param bool $removeParent
  142. * @return bool
  143. */
  144. public static function delete($dir, $removeParent = TRUE)
  145. {
  146. if(is_file($dir))
  147. {
  148. return @unlink($dir);
  149. }
  150. if(!$dh = @opendir($dir))
  151. {
  152. return;
  153. }
  154. while (($obj = readdir($dh)))
  155. {
  156. if($obj=='.' || $obj=='..')
  157. {
  158. continue;
  159. }
  160. try
  161. {
  162. if (!@unlink($dir .DIRECTORY_SEPARATOR .$obj))
  163. {
  164. self::delete($dir .DIRECTORY_SEPARATOR .$obj, TRUE);
  165. }
  166. }
  167. catch (Exception $e)
  168. {
  169. self::delete($dir .DIRECTORY_SEPARATOR .$obj, TRUE);
  170. }
  171. }
  172. if ($removeParent)
  173. {
  174. closedir($dh);
  175. @rmdir($dir);
  176. }
  177. }
  178. /**
  179. * This function is used to test if a directory is writable
  180. * Retrieved from http://us.php.net/manual/en/function.is-writable.php on 6/18/2009
  181. * will work in despite of Windows ACLs bug NOTE: use a trailing slash for folders!!!
  182. *
  183. * @return bool true if directory or file is writable otherwise false
  184. * @param string $path
  185. */
  186. public static function is_writable($path)
  187. {
  188. if ($path{strlen($path) - 1} == DIRECTORY_SEPARATOR)
  189. {
  190. return self::is_writable($path .uniqid(mt_rand()) .'.tmp');
  191. }
  192. else if (is_dir($path))
  193. {
  194. return self::is_writable($path .DIRECTORY_SEPARATOR .uniqid(mt_rand()) .'.tmp');
  195. }
  196. // check tmp file for read/write capabilities
  197. $rm = file_exists($path);
  198. $f = @fopen($path, 'w');
  199. if ($f === FALSE)
  200. {
  201. return FALSE;
  202. }
  203. fclose($f);
  204. if (!$rm)
  205. {
  206. unlink($path);
  207. }
  208. return TRUE;
  209. }
  210. /**
  211. * This is a helper funciton to convert windows or linux paths into the
  212. * appropriate system, it is very rudamentary and converts all slashs at
  213. * this time...
  214. * @param string $path
  215. * @param bool $escape
  216. * @return string
  217. */
  218. public static function convert_path(&$path, $escape)
  219. {
  220. $path = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $path);
  221. if ($escape)
  222. {
  223. $path = str_replace('/', '\/', $path);
  224. }
  225. return $path;
  226. }
  227. }