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

/src/Symfony/Bundle/FrameworkBundle/Util/Filesystem.php

https://github.com/come/symfony
PHP | 225 lines | 118 code | 27 blank | 80 comment | 31 complexity | 84337933bef9d361118bab57facc59a2 MD5 | raw file
Possible License(s): ISC
  1. <?php
  2. namespace Symfony\Bundle\FrameworkBundle\Util;
  3. /*
  4. * This file is part of the Symfony framework.
  5. *
  6. * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
  7. *
  8. * This source file is subject to the MIT license that is bundled
  9. * with this source code in the file LICENSE.
  10. */
  11. /**
  12. * Provides basic utility to manipulate the file system.
  13. *
  14. * @package Symfony
  15. * @subpackage Bundle_FrameworkBundle
  16. * @author Fabien Potencier <fabien.potencier@symfony-project.com>
  17. */
  18. class Filesystem
  19. {
  20. /**
  21. * Copies a file.
  22. *
  23. * This method only copies the file if the origin file is newer than the target file.
  24. *
  25. * By default, if the target already exists, it is not overridden.
  26. *
  27. * To override existing files, pass the "override" option.
  28. *
  29. * @param string $originFile The original filename
  30. * @param string $targetFile The target filename
  31. * @param array $options An array of options
  32. */
  33. public function copy($originFile, $targetFile, $options = array())
  34. {
  35. if (!array_key_exists('override', $options)) {
  36. $options['override'] = false;
  37. }
  38. // we create target_dir if needed
  39. if (!is_dir(dirname($targetFile))) {
  40. $this->mkdirs(dirname($targetFile));
  41. }
  42. $mostRecent = false;
  43. if (file_exists($targetFile)) {
  44. $statTarget = stat($targetFile);
  45. $stat_origin = stat($originFile);
  46. $mostRecent = ($stat_origin['mtime'] > $statTarget['mtime']) ? true : false;
  47. }
  48. if ($options['override'] || !file_exists($targetFile) || $mostRecent) {
  49. copy($originFile, $targetFile);
  50. }
  51. }
  52. /**
  53. * Creates a directory recursively.
  54. *
  55. * @param string $path The directory path
  56. * @param int $mode The directory mode
  57. *
  58. * @return bool true if the directory has been created, false otherwise
  59. */
  60. public function mkdirs($path, $mode = 0777)
  61. {
  62. if (is_dir($path)) {
  63. return true;
  64. }
  65. return @mkdir($path, $mode, true);
  66. }
  67. /**
  68. * Creates empty files.
  69. *
  70. * @param mixed $files The filename, or an array of filenames
  71. */
  72. public function touch($files)
  73. {
  74. if (!is_array($files)) {
  75. $files = array($files);
  76. }
  77. foreach ($files as $file) {
  78. touch($file);
  79. }
  80. }
  81. /**
  82. * Removes files or directories.
  83. *
  84. * @param mixed $files A filename or an array of files to remove
  85. */
  86. public function remove($files)
  87. {
  88. if (!is_array($files)) {
  89. $files = array($files);
  90. }
  91. $files = array_reverse($files);
  92. foreach ($files as $file) {
  93. if (!file_exists($file)) {
  94. continue;
  95. }
  96. if (is_dir($file) && !is_link($file)) {
  97. $fp = opendir($file);
  98. while (false !== $item = readdir($fp)) {
  99. if (!in_array($item, array('.', '..'))) {
  100. $this->remove($file.'/'.$item);
  101. }
  102. }
  103. closedir($fp);
  104. rmdir($file);
  105. } else {
  106. unlink($file);
  107. }
  108. }
  109. }
  110. /**
  111. * Change mode for an array of files or directories.
  112. *
  113. * @param array $files An array of files or directories
  114. * @param integer $mode The new mode
  115. * @param integer $umask The mode mask (octal)
  116. */
  117. public function chmod($files, $mode, $umask = 0000)
  118. {
  119. $currentUmask = umask();
  120. umask($umask);
  121. if (!is_array($files)) {
  122. $files = array($files);
  123. }
  124. foreach ($files as $file) {
  125. chmod($file, $mode);
  126. }
  127. umask($currentUmask);
  128. }
  129. /**
  130. * Renames a file.
  131. *
  132. * @param string $origin The origin filename
  133. * @param string $target The new filename
  134. *
  135. * @throws \RuntimeException When target file already exists
  136. */
  137. public function rename($origin, $target)
  138. {
  139. // we check that target does not exist
  140. if (is_readable($target)) {
  141. throw new \RuntimeException(sprintf('Cannot rename because the target "%" already exist.', $target));
  142. }
  143. rename($origin, $target);
  144. }
  145. /**
  146. * Creates a symbolic link or copy a directory.
  147. *
  148. * @param string $originDir The origin directory path
  149. * @param string $targetDir The symbolic link name
  150. * @param bool $copyOnWindows Whether to copy files if on windows
  151. */
  152. public function symlink($originDir, $targetDir, $copyOnWindows = false)
  153. {
  154. if (!function_exists('symlink') && $copyOnWindows) {
  155. $this->mirror($originDir, $targetDir);
  156. return;
  157. }
  158. $ok = false;
  159. if (is_link($targetDir)) {
  160. if (readlink($targetDir) != $originDir) {
  161. unlink($targetDir);
  162. } else {
  163. $ok = true;
  164. }
  165. }
  166. if (!$ok) {
  167. symlink($originDir, $targetDir);
  168. }
  169. }
  170. /**
  171. * Mirrors a directory to another.
  172. *
  173. * @param string $originDir The origin directory
  174. * @param string $targetDir The target directory
  175. * @param \Traversable $iterator A Traversable instance
  176. * @param array $options An array of options (see copy())
  177. *
  178. * @throws \RuntimeException When file type is unknown
  179. */
  180. public function mirror($originDir, $targetDir, \Traversable $iterator = null, $options = array())
  181. {
  182. if (null === $iterator) {
  183. $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($originDir, \FilesystemIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST);
  184. }
  185. foreach ($iterator as $file) {
  186. $target = $targetDir.DIRECTORY_SEPARATOR.str_replace(realpath($originDir), '', $file->getRealPath());
  187. if (is_dir($file)) {
  188. $this->mkdirs($target);
  189. } else if (is_file($file)) {
  190. $this->copy($file, $target, $options);
  191. } else if (is_link($file)) {
  192. $this->symlink($file, $target);
  193. } else {
  194. throw new \RuntimeException(sprintf('Unable to guess "%s" file type.', $file));
  195. }
  196. }
  197. }
  198. }