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

/wp-content/plugins/backupbuddy/pluginbuddy/classes/filesystem.php

https://bitbucket.org/summitds/bloomsburgpa.org
PHP | 307 lines | 155 code | 36 blank | 116 comment | 18 complexity | 6a8ff49a5ab47823aeb19976d4e2b9b5 MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0, BSD-3-Clause, GPL-3.0, LGPL-2.1
  1. <?php
  2. /* class pluginbuddy_filesystem
  3. * @author Dustin Bolton
  4. *
  5. * Handles interfacing with the file system.
  6. */
  7. class pb_backupbuddy_filesystem {
  8. // ********** PUBLIC PROPERTIES **********
  9. // ********** PRIVATE PROPERTIES **********
  10. // ********** FUNCTIONS **********
  11. /* pluginbuddy_filesystem->__construct()
  12. *
  13. * Default constructor.
  14. *
  15. * @return null
  16. */
  17. function __construct() {
  18. } // End __construct().
  19. /* pb_backupbuddy::$filesystem->mkdir()
  20. *
  21. * mkdir that defaults to recursive behaviour. 99% of the time this is what we want.
  22. *
  23. * @param $pathname string Path to create.
  24. * @param $mode int Default: 0777. See PHP's mkdir() function for details.
  25. * @param $recursive boolean Default: true. See PHP's mkdir() function for details.
  26. * @return boolean Returns TRUE on success or FALSE on failure.
  27. */
  28. public static function mkdir( $pathname, $mode = 0777, $recursive = true) {
  29. return @mkdir( $pathname, $mode, $recursive );
  30. } // End mkdir().
  31. /* pluginbuddy_filesystem->unlink_recursive()
  32. *
  33. * Unlink a directory recursively. Files all files and directories within. USE WITH CAUTION.
  34. *
  35. * @param string $dir Directory to delete -- all contents within, subdirectories, files, etc will be permanently deleted.
  36. * @return boolean True on success; else false.
  37. */
  38. function unlink_recursive( $dir ) {
  39. if ( defined( 'PB_DEMO_MODE' ) ) {
  40. return false;
  41. }
  42. if ( !file_exists( $dir ) ) {
  43. return true;
  44. }
  45. if ( !is_dir( $dir ) || is_link( $dir ) ) {
  46. return unlink($dir);
  47. }
  48. foreach ( scandir( $dir ) as $item ) {
  49. if ( $item == '.' || $item == '..' ) {
  50. continue;
  51. }
  52. if ( !$this->unlink_recursive( $dir . "/" . $item ) ) {
  53. @chmod( $dir . "/" . $item, 0777 );
  54. if ( !$this->unlink_recursive( $dir . "/" . $item ) ) {
  55. return false;
  56. }
  57. }
  58. }
  59. return @rmdir($dir);
  60. } // End unlink_recursive().
  61. /**
  62. * pluginbuddy_filesystem->deepglob()
  63. *
  64. * Like the glob() function except walks down into paths to create a full listing of all results in the directory and all subdirectories.
  65. * This is essentially a recursive glob() although it does not use recursion to perform this.
  66. *
  67. * @param string $dir Path to pass to glob and walk through.
  68. * @return array Returns array of all matches found.
  69. */
  70. function deepglob( $dir ) {
  71. $items = glob( $dir . '/*' );
  72. for ( $i = 0; $i < count( $items ); $i++ ) {
  73. if ( is_dir( $items[$i] ) ) {
  74. $add = glob( $items[$i] . '/*' );
  75. $items = array_merge( $items, $add );
  76. }
  77. }
  78. return $items;
  79. } // End deepglob().
  80. function recursive_copy( $src, $dst ) {
  81. //pb_backupbuddy::status( 'details', 'Copying `' . $src . '` to `' . $dst . '`.' );
  82. if ( is_dir( $src ) ) {
  83. pb_backupbuddy::status( 'details', 'Copying directory `' . $src . '` to `' . $dst . '` recursively.' );
  84. @$this->mkdir( $dst, 0777 );
  85. $files = scandir($src);
  86. foreach ( $files as $file ) {
  87. if ($file != "." && $file != "..") {
  88. $this->recursive_copy("$src/$file", "$dst/$file");
  89. }
  90. }
  91. } elseif ( file_exists( $src ) ) {
  92. @copy( $src, $dst ); // Todo: should this need suppression? Media copying was throwing $dst is directory errors.
  93. }
  94. }
  95. // RH added; from Chris?
  96. /*
  97. public function custom_copy( $source, $destination, $args = array() ) {
  98. $default_args = array(
  99. 'max_depth' => 100,
  100. 'folder_mode' => 0755,
  101. 'file_mode' => 0744,
  102. 'ignore_files' => array(),
  103. );
  104. $args = array_merge( $default_args, $args );
  105. return $this->_custom_copy( $source, $destination, $args );
  106. } // End custom_copy().
  107. private function _custom_copy( $source, $destination, $args, $depth = 0 ) {
  108. if ( $depth > $args['max_depth'] )
  109. return true;
  110. if ( in_array( basename( $source ), $args[ 'ignore_files' ] ) ) return true;
  111. if ( is_file( $source ) ) {
  112. if ( is_dir( $destination ) || preg_match( '|/$|', $destination ) ) {
  113. $destination = preg_replace( '|/+$|', '', $destination );
  114. $destination = "$destination/" . basename( $source );
  115. }
  116. if ( false === $this->mkdir( dirname( $destination ), $args['folder_mode'] ) )
  117. return false;
  118. if ( false === @copy( $source, $destination ) )
  119. return false;
  120. @chmod( $destination, $args['file_mode'] );
  121. return true;
  122. }
  123. else if ( is_dir( $source ) || preg_match( '|/\*$|', $source ) ) {
  124. if ( preg_match( '|/\*$|', $source ) )
  125. $source = preg_replace( '|/\*$|', '', $source );
  126. else if ( preg_match( '|/$|', $destination ) )
  127. $destination = $destination . basename( $source );
  128. $destination = preg_replace( '|/$|', '', $destination );
  129. $files = array_diff( array_merge( glob( $source . '/.*' ), glob( $source . '/*' ) ), array( $source . '/.', $source . '/..' ) );
  130. if ( false === @mkdir( $destination ) )
  131. return false;
  132. $result = true;
  133. foreach ( (array) $files as $file ) {
  134. if ( false === $this->_custom_copy( $file, "$destination/", $args, $depth + 1 ) )
  135. $result = false;
  136. }
  137. return $result;
  138. }
  139. return false;
  140. } // End _copy().
  141. */
  142. // todo: document
  143. // $exclusions is never modified so just use PHP's copy on modify default behaviour for memory management.
  144. /* function_name()
  145. *
  146. * function description
  147. * @param array/boolean Array of directory paths to exclude. If true then this directory is excluded so no need to check with exclusion directory.
  148. * @return array array( TOTAL_DIRECTORY_SIZE, TOTAL_SIZE_WITH_EXCLUSIONS_TAKEN_INTO_ACCOUNT )
  149. */
  150. function dir_size_map( $dir, $base, $exclusions, &$dir_array ) {
  151. $dir = rtrim( $dir, '/\\' ); // Force no trailing slash.
  152. if( !is_dir( $dir ) ) {
  153. return 0;
  154. }
  155. $ret = 0;
  156. $ret_with_exclusions = 0;
  157. $exclusions_result = $exclusions;
  158. $sub = opendir( $dir );
  159. while( $file = readdir( $sub ) ) {
  160. $exclusions_result = $exclusions;
  161. $dir_path = '/' . str_replace( $base, '', $dir . '/' . $file ); //str_replace( $base, '', $dir . $file . '/' );
  162. if ( ( $file == '.' ) || ( $file == '..' ) ) {
  163. // Do nothing.
  164. } elseif ( is_dir( $dir . '/' . $file ) ) { // DIRECTORY.
  165. if ( ( $exclusions === true ) || self::in_array_substr( $exclusions, $dir_path, '/' ) ) {
  166. $exclusions_result = true;
  167. }
  168. $result = $this->dir_size_map( $dir . '/' . $file . '/', $base, $exclusions, $dir_array );
  169. $this_size = $result[0];
  170. if ( $exclusions_result === true ) { // If excluding then wipe excluded value.
  171. $this_size_with_exclusions = false;
  172. } else {
  173. $this_size_with_exclusions = $result[1]; // / 1048576 );
  174. }
  175. $dir_array[ $dir_path ] = array( $this_size, $this_size_with_exclusions ); // $dir_array[ DIRECTORY_PATH ] = DIRECTORY_SIZE;
  176. $ret += $this_size;
  177. $ret_with_exclusions += $this_size_with_exclusions;
  178. unset( $file );
  179. } else { // FILE.
  180. $stats = stat( $dir . '/' . $file );
  181. $ret += $stats['size'];
  182. //if ( ( $exclusions !== true ) && !self::in_array_substr( $exclusions, $dir_path ) ) { // Not excluding.
  183. if ( ( $exclusions !== true ) && !in_array( $dir_path, $exclusions ) ) { // Not excluding.
  184. $ret_with_exclusions += $stats['size'];
  185. }
  186. unset( $file );
  187. }
  188. }
  189. closedir( $sub );
  190. unset( $sub );
  191. return array( $ret, $ret_with_exclusions );
  192. } // End dir_size_map().
  193. public static function in_array_substr( $haystack, $needle, $trailing = '' ) {
  194. foreach( $haystack as $hay ) {
  195. if ( ( $hay . $trailing ) == substr( $needle . $trailing, 0, strlen( $hay . $trailing ) ) ) {
  196. //echo $needle . '~' . $hay . '<br>';
  197. return true;
  198. }
  199. }
  200. return false;
  201. }
  202. public function exit_code_lookup( $code ) {
  203. switch( (string)$code ) {
  204. case '0':
  205. return 'Command completed & returned normally.';
  206. break;
  207. case '127':
  208. return 'Command not found.';
  209. break;
  210. case '152':
  211. return 'SIGXCPU 152; CPU time limit exceeded.';
  212. break;
  213. case '153':
  214. return 'SIGXFSZ 153; File size limit exceeded. Verify enough free space exists & filesystem max size not exceeded.';
  215. break;
  216. case '158':
  217. return 'SIGXCPU 158; CPU time limit exceeded.';
  218. break;
  219. case '159':
  220. return 'SIGXFSZ 159; File size limit exceeded. Verify enough free space exists & filesystem max size not exceeded.';
  221. break;
  222. default:
  223. return '-No information available for this exit code-';
  224. break;
  225. }
  226. }
  227. } // End class pluginbuddy_settings.
  228. ?>