* @author Alex Makarov * @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: * * @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); } } }