1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
<?php
/**
* Filesystem helper class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @author Alex Makarov <sam@rmcreative.ru>
* @link http://www.yiiframework.com/
* @copyright Copyright © 2008-2012 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\util;
/**
* Filesystem helper
*
* @since 2.0
*/
class File
{
/**
* Copies a list of files from one place to another.
* @param array $fileList the list of files to be copied (name=>spec).
* The array keys are names displayed during the copy process, and array values are specifications
* for files to be copied. Each array value must be an array of the following structure:
* <ul>
* <li>source: required, the full path of the file/directory to be copied from</li>
* <li>target: required, the full path of the file/directory to be copied to</li>
* <li>callback: optional, the callback to be invoked when copying a file. The callback function
* should be declared as follows:
* <pre>
* function foo($source,$params)
* </pre>
* where $source parameter is the source file path, and the content returned
* by the function will be saved into the target file.</li>
* <li>params: optional, the parameters to be passed to the callback</li>
* </ul>
* @see buildFileList
*/
public function copyFiles($fileList)
{
$overwriteAll=false;
foreach($fileList as $name=>$file)
{
$source=strtr($file['source'],'/\\',DIRECTORY_SEPARATOR);
$target=strtr($file['target'],'/\\',DIRECTORY_SEPARATOR);
$callback=isset($file['callback']) ? $file['callback'] : null;
$params=isset($file['params']) ? $file['params'] : null;
if(is_dir($source))
{
$this->ensureDirectory($target);
continue;
}
if($callback!==null)
$content=call_user_func($callback,$source,$params);
else
$content=file_get_contents($source);
if(is_file($target))
{
if($content===file_get_contents($target))
{
echo " unchanged $name\n";
continue;
}
if($overwriteAll)
echo " overwrite $name\n";
else
{
echo " exist $name\n";
echo " ...overwrite? [Yes|No|All|Quit] ";
$answer=trim(fgets(STDIN));
if(!strncasecmp($answer,'q',1))
return;
else if(!strncasecmp($answer,'y',1))
echo " overwrite $name\n";
else if(!strncasecmp($answer,'a',1))
{
echo " overwrite $name\n";
$overwriteAll=true;
} else
{
echo " skip $name\n";
continue;
}
}
} else
{
$this->ensureDirectory(dirname($target));
echo " generate $name\n";
}
file_put_contents($target,$content);
}
}
/**
* Builds the file list of a directory.
* This method traverses through the specified directory and builds
* a list of files and subdirectories that the directory contains.
* The result of this function can be passed to {@link copyFiles}.
* @param string $sourceDir the source directory
* @param string $targetDir the target directory
* @param string $baseDir base directory
* @return array the file list (see {@link copyFiles})
*/
public function buildFileList($sourceDir, $targetDir, $baseDir='')
{
$list=array();
$handle=opendir($sourceDir);
while(($file=readdir($handle))!==false)
{
if($file==='.' || $file==='..' || $file==='.svn' ||$file==='.yii')
continue;
$sourcePath=$sourceDir.DIRECTORY_SEPARATOR.$file;
$targetPath=$targetDir.DIRECTORY_SEPARATOR.$file;
$name=$baseDir===''?$file : $baseDir.'/'.$file;
$list[$name]=array('source'=>$sourcePath, 'target'=>$targetPath);
if(is_dir($sourcePath))
$list=array_merge($list,$this->buildFileList($sourcePath,$targetPath,$name));
}
closedir($handle);
return $list;
}
/**
* Creates all parent directories if they do not exist.
* @param string $directory the directory to be checked
*/
public function ensureDirectory($directory)
{
if(!is_dir($directory))
{
$this->ensureDirectory(dirname($directory));
echo " mkdir ".strtr($directory,'\\','/')."\n";
mkdir($directory);
}
}
}