vendor/symfony/src/Symfony/Component/HttpKernel/Util/Filesystem.php
changeset 0 7f95f8617b0b
equal deleted inserted replaced
-1:000000000000 0:7f95f8617b0b
       
     1 <?php
       
     2 
       
     3 /*
       
     4  * This file is part of the Symfony package.
       
     5  *
       
     6  * (c) Fabien Potencier <fabien@symfony.com>
       
     7  *
       
     8  * For the full copyright and license information, please view the LICENSE
       
     9  * file that was distributed with this source code.
       
    10  */
       
    11 
       
    12 namespace Symfony\Component\HttpKernel\Util;
       
    13 
       
    14 /**
       
    15  * Provides basic utility to manipulate the file system.
       
    16  *
       
    17  * @author Fabien Potencier <fabien@symfony.com>
       
    18  */
       
    19 class Filesystem
       
    20 {
       
    21     /**
       
    22      * Copies a file.
       
    23      *
       
    24      * This method only copies the file if the origin file is newer than the target file.
       
    25      *
       
    26      * By default, if the target already exists, it is not overridden.
       
    27      *
       
    28      * @param string $originFile The original filename
       
    29      * @param string $targetFile The target filename
       
    30      * @param array  $override   Whether to override an existing file or not
       
    31      */
       
    32     public function copy($originFile, $targetFile, $override = false)
       
    33     {
       
    34         $this->mkdir(dirname($targetFile));
       
    35 
       
    36         $mostRecent = false;
       
    37         if (file_exists($targetFile)) {
       
    38             $statTarget = stat($targetFile);
       
    39             $statOrigin = stat($originFile);
       
    40             $mostRecent = $statOrigin['mtime'] > $statTarget['mtime'];
       
    41         }
       
    42 
       
    43         if ($override || !file_exists($targetFile) || $mostRecent) {
       
    44             copy($originFile, $targetFile);
       
    45         }
       
    46     }
       
    47 
       
    48     /**
       
    49      * Creates a directory recursively.
       
    50      *
       
    51      * @param  string|array|\Traversable $dirs The directory path
       
    52      * @param  int                       $mode The directory mode
       
    53      *
       
    54      * @return Boolean true if the directory has been created, false otherwise
       
    55      */
       
    56     public function mkdir($dirs, $mode = 0777)
       
    57     {
       
    58         $ret = true;
       
    59         foreach ($this->toIterator($dirs) as $dir) {
       
    60             if (is_dir($dir)) {
       
    61                 continue;
       
    62             }
       
    63 
       
    64             $ret = @mkdir($dir, $mode, true) && $ret;
       
    65         }
       
    66 
       
    67         return $ret;
       
    68     }
       
    69 
       
    70     /**
       
    71      * Creates empty files.
       
    72      *
       
    73      * @param string|array|\Traversable $files A filename, an array of files, or a \Traversable instance to remove
       
    74      */
       
    75     public function touch($files)
       
    76     {
       
    77         foreach ($this->toIterator($files) as $file) {
       
    78             touch($file);
       
    79         }
       
    80     }
       
    81 
       
    82     /**
       
    83      * Removes files or directories.
       
    84      *
       
    85      * @param string|array|\Traversable $files A filename, an array of files, or a \Traversable instance to remove
       
    86      */
       
    87     public function remove($files)
       
    88     {
       
    89         $files = iterator_to_array($this->toIterator($files));
       
    90         $files = array_reverse($files);
       
    91         foreach ($files as $file) {
       
    92             if (!file_exists($file)) {
       
    93                 continue;
       
    94             }
       
    95 
       
    96             if (is_dir($file) && !is_link($file)) {
       
    97                 $this->remove(new \FilesystemIterator($file));
       
    98 
       
    99                 rmdir($file);
       
   100             } else {
       
   101                 unlink($file);
       
   102             }
       
   103         }
       
   104     }
       
   105 
       
   106     /**
       
   107      * Change mode for an array of files or directories.
       
   108      *
       
   109      * @param string|array|\Traversable $files A filename, an array of files, or a \Traversable instance to remove
       
   110      * @param integer                   $mode  The new mode
       
   111      * @param integer                   $umask The mode mask (octal)
       
   112      */
       
   113     public function chmod($files, $mode, $umask = 0000)
       
   114     {
       
   115         $currentUmask = umask();
       
   116         umask($umask);
       
   117 
       
   118         foreach ($this->toIterator($files) as $file) {
       
   119             chmod($file, $mode);
       
   120         }
       
   121 
       
   122         umask($currentUmask);
       
   123     }
       
   124 
       
   125     /**
       
   126      * Renames a file.
       
   127      *
       
   128      * @param string $origin  The origin filename
       
   129      * @param string $target  The new filename
       
   130      *
       
   131      * @throws \RuntimeException When target file already exists
       
   132      */
       
   133     public function rename($origin, $target)
       
   134     {
       
   135         // we check that target does not exist
       
   136         if (is_readable($target)) {
       
   137             throw new \RuntimeException(sprintf('Cannot rename because the target "%" already exist.', $target));
       
   138         }
       
   139 
       
   140         rename($origin, $target);
       
   141     }
       
   142 
       
   143     /**
       
   144      * Creates a symbolic link or copy a directory.
       
   145      *
       
   146      * @param string  $originDir     The origin directory path
       
   147      * @param string  $targetDir     The symbolic link name
       
   148      * @param Boolean $copyOnWindows Whether to copy files if on windows
       
   149      */
       
   150     public function symlink($originDir, $targetDir, $copyOnWindows = false)
       
   151     {
       
   152         if (!function_exists('symlink') && $copyOnWindows) {
       
   153             $this->mirror($originDir, $targetDir);
       
   154 
       
   155             return;
       
   156         }
       
   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 
       
   167         if (!$ok) {
       
   168             symlink($originDir, $targetDir);
       
   169         }
       
   170     }
       
   171 
       
   172     /**
       
   173      * Mirrors a directory to another.
       
   174      *
       
   175      * @param string $originDir      The origin directory
       
   176      * @param string $targetDir      The target directory
       
   177      * @param \Traversable $iterator A Traversable instance
       
   178      * @param array  $options        An array of options (see copy())
       
   179      *
       
   180      * @throws \RuntimeException When file type is unknown
       
   181      */
       
   182     public function mirror($originDir, $targetDir, \Traversable $iterator = null, $options = array())
       
   183     {
       
   184         if (null === $iterator) {
       
   185             $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($originDir, \FilesystemIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST);
       
   186         }
       
   187 
       
   188         if ('/' === substr($targetDir, -1) || '\\' === substr($targetDir, -1)) {
       
   189             $targetDir = substr($targetDir, 0, -1);
       
   190         }
       
   191 
       
   192         if ('/' === substr($originDir, -1) || '\\' === substr($originDir, -1)) {
       
   193             $originDir = substr($originDir, 0, -1);
       
   194         }
       
   195 
       
   196         foreach ($iterator as $file) {
       
   197             $target = $targetDir.'/'.str_replace($originDir.DIRECTORY_SEPARATOR, '', $file->getPathname());
       
   198 
       
   199             if (is_dir($file)) {
       
   200                 $this->mkdir($target);
       
   201             } else if (is_file($file)) {
       
   202                 $this->copy($file, $target, $options);
       
   203             } else if (is_link($file)) {
       
   204                 $this->symlink($file, $target);
       
   205             } else {
       
   206                 throw new \RuntimeException(sprintf('Unable to guess "%s" file type.', $file));
       
   207             }
       
   208         }
       
   209     }
       
   210 
       
   211     /**
       
   212      * Returns whether the file path is an absolute path.
       
   213      *
       
   214      * @param string $file A file path
       
   215      *
       
   216      * @return Boolean
       
   217      */
       
   218     public function isAbsolutePath($file)
       
   219     {
       
   220         if ($file[0] == '/' || $file[0] == '\\'
       
   221             || (strlen($file) > 3 && ctype_alpha($file[0])
       
   222                 && $file[1] == ':'
       
   223                 && ($file[2] == '\\' || $file[2] == '/')
       
   224             )
       
   225         ) {
       
   226             return true;
       
   227         }
       
   228 
       
   229         return false;
       
   230     }
       
   231 
       
   232     private function toIterator($files)
       
   233     {
       
   234         if (!$files instanceof \Traversable) {
       
   235             $files = new \ArrayObject(is_array($files) ? $files : array($files));
       
   236         }
       
   237 
       
   238         return $files;
       
   239     }
       
   240 }