<?php
namespace lib;
/**
* 文件与目录操作类
* @version 1.0.0
*/
class file extends \Symfony\Component\Filesystem\Filesystem
{
	/**
	 * 格式化目录
	 * 
	 * 将 \ 转换成 / , 将两个 // 转换成 一个 /, 并去掉末尾的 /
	 * @param string $dir  待格式化的目录名或者是文件名
	 * @return  string
	 */
    public function formatDir($dir){
        $dir = str_replace('\\','/',$dir);
        $dir = str_replace('//','/',$dir);
        $dir = rtrim($dir,'/');
        return $dir;
    }
	/**
	 * 取文件扩展名
	 * @param string $filename  文件名
	 * @return string 返回小写字母不带点号.的扩展名
	 * @example ```extName('INDEX.HTML'); //返回 "html"```
	 */
    public function extName($filename){
        $arr = pathinfo($filename);
        return strtolower($arr['extension']);
    }
	/**
	 * 递归创建目录. 在POSIX文件系统上, 使用默认模式值0777创建目录. 您可以使用第二个参数来设置自己的模式
	 * @param string $dir
	 * @param number $mod 权限，默认0777
	 * @return void
	 */
    public function mkdir($dir,$mod=0777){
        return parent::mkdir($this->formatDir($dir),$mod);
    }
	/**
	 * 检查是否存在一个或多个文件或目录，如果缺少文件或目录，则返回 false
	 * @param string|array $var 
	 * @example ```exists('/tmp/photos');```
	 * @example ```exists(['rabbit.jpg', 'bottle.png']);```
	 * @return bool
	 */
    public function exists($var){
        return parent::exists($var);
    }
	/**
	 * 复制单个文件
	 * 
	 * 如果目标已经存在，仅当源文件修改日期晚于目标时才复制文件。第三个参数为强制覆盖
	 * @param string $srcFilename 源文件
	 * @param string $distFilename 目标文件
	 * @param string $overwrite 目录存在是否强制覆盖
	 * @example ```copy('image-ICC.jpg', 'image.jpg');```
	 * @example ```copy('image-ICC.jpg', 'image.jpg', true);```
	 * @return bool
	 */
    public function copy($srcFilename,$distFilename,$overwrite=false){
        return parent::copy($this->formatDir($srcFilename),$this->formatDir($distFilename),$overwrite);
    }
	/**
	 * 将源目录的所有内容复制到目标目录中
	 * 
	 * 如果目标已经存在，仅当源文件修改日期晚于目标时才复制文件。第三个参数为强制覆盖
	 * @param string $srcDir 源目录
	 * @param string $distDir 目标目录
     * @param \Traversable|null $iterator  迭代器，过滤要复制的文件和目录，如果为空，则创建递归迭代器
     * @param array             $options   选项
     *                                     - $options['override'] 为 true 则强制覆盖, 为false时，判断源文件修改时间是否大于目录文件修改时间再复制
     *                                     - $options['copy_on_windows'] 是否在Windows上复制文件而不是链接,为true,如果文件是个链接，将会找它的实体文件
     *                                     - $options['delete'] 是否删除源文件文件，默认false, 为 true 相当于是移动操作
	 * @example ```mirror('/path/to/source', '/path/to/target');```
	 * @example ```mirror('/path/to/source', '/path/to/target', null, ['override'=>true]); //强制覆盖```
	 * @example ```mirror('/path/to/source', '/path/to/target', null, ['delete'=>true]); //移动```
	 * @return bool
	 */
    public function mirror($srcDir,$distDir,\Traversable $iterator=null,$options= []){
		$options = array_merge(['override'=>false,'copy_on_windows'=>true,'delete'=>false], $options);
        return parent::mirror($this->formatDir($srcDir),$this->formatDir($distDir),$iterator,$options);
    }
	/**
	 * 设置文件的访问和修改时间
	 * 
	 * 默认-1使用当前时间。您可以使用第二个参数设置自己的参数。第三个参数是访问时间
	 * @param string $filename
	 * @param integer $modifyTime 修改时间
	 * @param integer $accessTime 访问时间
	 * @example ```touch('file.txt')```
	 * @example ```touch('file.txt', time() + 10);```
	 * @example ```touch('file.txt', time(), time() - 10);```
	 * @return bool
	 */
    public function touch($filename,$modifyTime=-1,$accessTime=-1){
		$filename = $this->formatDir($filename);
		if($modifyTime!=-1 && $accessTime!=-1){
			return parent::touch($filename,$modifyTime,$accessTime);
		}else if($modifyTime!=-1){
			return parent::touch($filename,$modifyTime);
		}else{
			return parent::touch($filename);
		}
    }
	/**
	 * 更改文件的模式或权限。第四个参数是布尔型递归选项是否执行子目录
	 * 
	 * @param string $filename
	 * @param number $mod 权限 0777全部人权限, 0755所有者权限
	 * @param number $param3 不清楚,默认 0000
	 * @param bool $isSubdirectory 是否设置子目录,默认是
	 * @example ```chmod('video.ogg', 0755);```
	 * @return void
	 */
    public function chmod($filename,$mod,$param3=0000, $isSubdirectory=true){
		return parent::chmod($this->formatDir($filename),$mod,$param3,$isSubdirectory);
    }
	/**
	 * 递归删除文件，目录和符号链接 
	 * 
	 * @param string|array $var
	 * @example ```remove(['symlink', '/path/to/directory', 'activity.log']);```
	 * @return void
	 */
    public function remove($var){
		return parent::remove($this->formatDir($var));
    }
	/**
	 * 更改单个文件或目录的名称
	 * 
	 * @param string $src 源文件或目录
	 * @param string $dist 目标文件或目录
	 * @param bool $overwrite 目录存在时是否覆盖
	 * @example ```rename('/tmp/processed_video.ogg', '/path/to/store/video_647.ogg');//更名文件```
	 * @example ```rename('/tmp/files', '/path/to/store/files');//更名目录```
	 * @return void
	 */
    public function rename($src,$dist,$overwrite = false){
		return parent::rename($this->formatDir($src),$this->formatDir($dist),$overwrite);
    }
	/**
	 * 采取两条绝对路径并返回从第二条路径到第一条路径的相对路径
	 * @param string $dir1
	 * @param string $dir2
	 * @example ```makePathRelative('/a/b','/a/b/c/d); //返回 ../../```
	 * @return string
	 */
    public function makePathRelative($dir1,$dir2){
        return parent::makePathRelative($this->formatDir($dir1),$this->formatDir($dir2));
    }
	/**
	 * 如果给定路径是否是一个绝对路径
	 * @param string $dir
	 * @example ```isAbsolutePath('/tmp'); //true```
	 * @example ```isAbsolutePath('c:\\Windows'); //true```
	 * @example ```isAbsolutePath('../dir'); //false```
	 * @example ```isAbsolutePath('tmp'); //false```
	 * @return bool
	 */
    public function isAbsolutePath($dir){
        return parent::isAbsolutePath($this->formatDir($dir));
    }
	/**
	 * 创建具有唯一文件名的临时文件，并返回其路径
	 * @param string $dir
	 * @param string $prefix 前缀
	 * @example ```tempnam('/tmp');```
	 * @return string 创建后的临时文件路径
	 */
    public function tempnam($dir,$prefix='tmp_'){
        return parent::tempnam($this->formatDir($dir),$prefix);
    }
	/**
	 * 将给定的内容保存到文件中（覆盖是写入）
	 * 
	 * 它以原子方式执行此操作：首先写入一个临时文件，然后在完成后将其移动到新文件位置。这意味着用户将始终看到完整的旧文件或完整的新文件（但看不到部分写入的文件）
	 * @param string $filename
	 * @param string $contents 要写入的内容
	 * @example ```dumpFile('file.txt', 'Hello World');```
	 * @return void
	 */
    public function dumpFile($filename,$contents){
        return parent::tempnam($this->formatDir($dir),$prefix);
    }
	/**
	 * 在文件的末尾追加新内容
	 * 
	 * @param string $filename
	 * @param string $contents 要写入的内容
	 * @example ```appendToFile('file.txt', 'this is new contents.');```
	 * @return void
	 */
    public function appendToFile($filename,$contents){
        return parent::tempnam($this->formatDir($dir),$prefix);
    }

}