Development

/branches/1.1/lib/task/sfFilesystem.class.php

You must first sign up to be able to contribute.

root/branches/1.1/lib/task/sfFilesystem.class.php

Revision 9097, 7.8 kB (checked in by FabianLange, 6 years ago)

1.1: fixed @param phpdoc to fit specs in task (refs #2991)

  • Property svn:mime-type set to text/x-php
  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1 <?php
2
3 /*
4  * This file is part of the symfony package.
5  * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
6  *
7  * For the full copyright and license information, please view the LICENSE
8  * file that was distributed with this source code.
9  */
10
11 /**
12  * sfFilesystem provides basic utility to manipulate the file system.
13  *
14  * @package    symfony
15  * @subpackage util
16  * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
17  * @version    SVN: $Id$
18  */
19 class sfFilesystem
20 {
21   protected
22     $dispatcher = null,
23     $formatter  = null;
24
25   /**
26    * Constructor.
27    *
28    * @param sfEventDispatcher $dispatcher  An sfEventDispatcher instance
29    * @param sfFormatter       $formatter   An sfFormatter instance
30    */
31   public function __construct(sfEventDispatcher $dispatcher = null, sfFormatter $formatter = null)
32   {
33     $this->dispatcher = $dispatcher;
34     $this->formatter = $formatter;
35   }
36
37   /**
38    * Copies a file.
39    *
40    * This method only copies the file if the origin file is newer than the target file.
41    *
42    * By default, if the target already exists, it is not overriden.
43    *
44    * To override existing files, pass the "override" option.
45    *
46    * @param string $originFile  The original filename
47    * @param string $targetFile  The target filename
48    * @param array  $options     An array of options
49    */
50   public function copy($originFile, $targetFile, $options = array())
51   {
52     if (!array_key_exists('override', $options))
53     {
54       $options['override'] = false;
55     }
56
57     // we create target_dir if needed
58     if (!is_dir(dirname($targetFile)))
59     {
60       $this->mkdirs(dirname($targetFile));
61     }
62
63     $mostRecent = false;
64     if (file_exists($targetFile))
65     {
66       $statTarget = stat($targetFile);
67       $stat_origin = stat($originFile);
68       $mostRecent = ($stat_origin['mtime'] > $statTarget['mtime']) ? true : false;
69     }
70
71     if ($options['override'] || !file_exists($targetFile) || $mostRecent)
72     {
73       $this->logSection('file+', $targetFile);
74       copy($originFile, $targetFile);
75     }
76   }
77
78   /**
79    * Creates a directory recursively.
80    *
81    * @param  string $path  The directory path
82    * @param  int    $mode  The directory mode
83    *
84    * @return bool true if the directory has been created, false otherwise
85    */
86   public function mkdirs($path, $mode = 0777)
87   {
88     if (is_dir($path))
89     {
90       return true;
91     }
92
93     $this->logSection('dir+', $path);
94
95     return @mkdir($path, $mode, true);
96   }
97
98   /**
99    * Creates empty files.
100    *
101    * @param mixed $files  The filename, or an array of filenames
102    */
103   public function touch($files)
104   {
105     if (!is_array($files))
106     {
107       $files = array($files);
108     }
109
110     foreach ($files as $file)
111     {
112       $this->logSection('file+', $file);
113
114       touch($file);
115     }
116   }
117
118   /**
119    * Removes files or directories.
120    *
121    * @param mixed $files  A filename or an array of files to remove
122    */
123   public function remove($files)
124   {
125     if (!is_array($files))
126     {
127       $files = array($files);
128     }
129
130     $files = array_reverse($files);
131     foreach ($files as $file)
132     {
133       if (is_dir($file) && !is_link($file))
134       {
135         $this->logSection('dir-', $file);
136
137         rmdir($file);
138       }
139       else
140       {
141         $this->logSection(is_link($file) ? 'link-' : 'file-', $file);
142
143         unlink($file);
144       }
145     }
146   }
147
148   /**
149    * Change mode for an array of files or directories.
150    *
151    * @param array   $files  An array of files or directories
152    * @param integer $mode   The new mode
153    * @param integer $umask  The mode mask (octal)
154    */
155   public function chmod($files, $mode, $umask = 0000)
156   {
157     $currentUmask = umask();
158     umask($umask);
159
160     if (!is_array($files))
161     {
162       $files = array($files);
163     }
164
165     foreach ($files as $file)
166     {
167       $this->logSection(sprintf('chmod %o', $mode), $file);
168       chmod($file, $mode);
169     }
170
171     umask($currentUmask);
172   }
173
174   /**
175    * Renames a file.
176    *
177    * @param string $origin  The origin filename
178    * @param string $target  The new filename
179    */
180   public function rename($origin, $target)
181   {
182     // we check that target does not exist
183     if (is_readable($target))
184     {
185       throw new sfException(sprintf('Cannot rename because the target "%" already exist.', $target));
186     }
187
188     $this->logSection('rename', $origin.' > '.$target);
189     rename($origin, $target);
190   }
191
192   /**
193    * Creates a symbolic link or copy a directory.
194    *
195    * @param string $originDir      The origin directory path
196    * @param string $targetDir      The symbolic link name
197    * @param bool   $copyOnWindows  Whether to copy files if on windows
198    */
199   public function symlink($originDir, $targetDir, $copyOnWindows = false)
200   {
201     if (!function_exists('symlink') && $copyOnWindows)
202     {
203       $finder = sfFinder::type('any');
204       $this->mirror($originDir, $targetDir, $finder);
205       return;
206     }
207
208     $ok = false;
209     if (is_link($targetDir))
210     {
211       if (readlink($targetDir) != $originDir)
212       {
213         unlink($targetDir);
214       }
215       else
216       {
217         $ok = true;
218       }
219     }
220
221     if (!$ok)
222     {
223       $this->logSection('link+', $targetDir);
224       symlink($originDir, $targetDir);
225     }
226   }
227
228   /**
229    * Mirrors a directory to another.
230    *
231    * @param string   $originDir  The origin directory
232    * @param string   $targetDir  The target directory
233    * @param sfFinder $finder     An sfFinder instance
234    * @param array    $options    An array of options (see copy())
235    */
236   public function mirror($originDir, $targetDir, $finder, $options = array())
237   {
238     foreach ($finder->relative()->in($originDir) as $file)
239     {
240       if (is_dir($originDir.DIRECTORY_SEPARATOR.$file))
241       {
242         $this->mkdirs($targetDir.DIRECTORY_SEPARATOR.$file);
243       }
244       else if (is_file($originDir.DIRECTORY_SEPARATOR.$file))
245       {
246         $this->copy($originDir.DIRECTORY_SEPARATOR.$file, $targetDir.DIRECTORY_SEPARATOR.$file, $options);
247       }
248       else if (is_link($originDir.DIRECTORY_SEPARATOR.$file))
249       {
250         $this->symlink($originDir.DIRECTORY_SEPARATOR.$file, $targetDir.DIRECTORY_SEPARATOR.$file);
251       }
252       else
253       {
254         throw new sfException(sprintf('Unable to guess "%s" file type.', $file));
255       }
256     }
257   }
258
259   /**
260    * Executes a shell command.
261    *
262    * @param string $cmd  The command to execute on the shell
263    */
264   public function sh($cmd)
265   {
266     $this->logSection('exec ', $cmd);
267
268     ob_start();
269     passthru($cmd.' 2>&1', $return);
270     $content = ob_get_contents();
271     ob_end_clean();
272
273     if ($return > 0)
274     {
275       throw new sfException(sprintf('Problem executing command %s', "\n".$content));
276     }
277
278     return $content;
279   }
280
281   /**
282    * Replaces tokens in an array of files.
283    *
284    * @param array  $files       An array of filenames
285    * @param string $beginToken  The begin token delimiter
286    * @param string $endToken    The end token delimiter
287    * @param array  $tokens      An array of token/value pairs
288    */
289   public function replaceTokens($files, $beginToken, $endToken, $tokens)
290   {
291     if (!is_array($files))
292     {
293       $files = array($files);
294     }
295
296     foreach ($files as $file)
297     {
298       $content = file_get_contents($file);
299       foreach ($tokens as $key => $value)
300       {
301         $content = str_replace($beginToken.$key.$endToken, $value, $content, $count);
302       }
303
304       $this->logSection('tokens', $file);
305
306       file_put_contents($file, $content);
307     }
308   }
309
310   /**
311    * Logs a message in a section.
312    *
313    * @param string $section  The section name
314    * @param string $message  The message
315    * @param int    $size     The maximum size of a line
316    */
317   protected function logSection($section, $message, $size = null)
318   {
319     if (!$this->dispatcher)
320     {
321       return;
322     }
323
324     $message = $this->formatter ? $this->formatter->formatSection($section, $message, $size) : $section.' '.$message."\n";
325
326     $this->dispatcher->notify(new sfEvent($this, 'command.log', array($message)));
327   }
328 }
329
Note: See TracBrowser for help on using the browser.