. //============================================================================ /** * @copyright Francois Laupretre * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, V 2.0 * @category phool * @package phool */ //============================================================================ namespace Phool; class File { //---- public static function suffix($filename) { $dotpos=strrpos($filename,'.'); if ($dotpos===false) return ''; return strtolower(substr($filename,$dotpos+1)); } //---- public static function fileSuffix($filename) { return self::suffix($filename); } //---- /** * Combines a base path with another path * * The base path can be relative or absolute. * * The 2nd path can also be relative or absolute. If absolute, it is returned * as-is. If it is a relative path, it is combined to the base path. * * Uses '/' as separator (to be compatible with stream-wrapper URIs). * * @param string $base The base path * @param string|null $path The path to combine * @param bool $separ true: add trailing sep, false: remove it * @return string The resulting path */ public static function combinePath($base,$path,$separ=false) { if (($base=='.') || ($base=='') || self::isAbsolutePath($path)) $res=$path; elseif (($path=='.') || is_null($path)) $res=$base; else //-- Relative path : combine it to base $res=rtrim($base,'/\\').'/'.$path; return self::trailingSepar($res,$separ); } //--------------------------------- /** * Adds or removes a trailing separator in a path * * @param string $path Input * @param bool $flag true: add trailing sep, false: remove it * @return bool The result path */ public static function trailingSepar($path, $separ) { $path=rtrim($path,'/\\'); if ($path=='') return '/'; if ($separ) $path=$path.'/'; return $path; } //--------------------------------- /** * Determines if a given path is absolute or relative * * @param string $path The path to check * @return bool True if the path is absolute, false if relative */ public static function isAbsolutePath($path) { return ((strpos($path,':')!==false) ||(strpos($path,'/')===0) ||(strpos($path,'\\')===0)); } //--------------------------------- /** * Build an absolute path from a given (absolute or relative) path * * If the input path is relative, it is combined with the current working * directory. * * @param string $path The path to make absolute * @param bool $separ True if the resulting path must contain a trailing separator * @return string The resulting absolute path */ public static function mkAbsolutePath($path,$separ=false) { if (!self::isAbsolutePath($path)) $path=self::combinePath(getcwd(),$path); return self::trailingSepar($path,$separ); } //--------- public static function readFile($path) { if (($data=@file_get_contents($path))===false) throw new \Exception($path.': Cannot get file content'); return $data; } //--------- // Throws exceptions and removes '.' and '..' public static function scandir($path) { if (($subnames=scandir($path))===false) throw new \Exception($path.': Cannot read directory'); $a=array(); foreach($subnames as $f) if (($f!='.') && ($f!='..')) $a[]=$f; return $a; } //--------------------------------- public static function atomicWrite($path,$data) { $tmpf=tempnam(dirname($path),'tmp_'); if (file_put_contents($tmpf,$data)!=strlen($data)) throw new \Exception($tmpf.": Cannot write"); // Windows does not support renaming to an existing file (looses atomicity) if (Util::envIsWindows()) @unlink($path); if (!rename($tmpf,$path)) { unlink($tmpf); throw new \Exception($path,'Cannot replace file'); } } //--------------------------------- /** * Computes a string uniquely identifying a given path on this host. * * Mount point unicity is based on a combination of device+inode+mtime. * * On systems which don't supply a valid inode number (eg Windows), we * maintain a fake inode table, whose unicity is based on the path filtered * through realpath(). It is not perfect because I am not sure that realpath * really returns a unique 'canonical' path, but this is best solution I * have found so far. * * @param string $path The path to be mounted * @return string the computed mount point * @throws Exception */ private static $simul_inode_array=array(); private static $simul_inode_index=1; public static function pathUniqueID($prefix,$path,&$mtime) { if (($s=stat($path))===false) throw new \Exception("$path: File not found"); $dev=$s[0]; $inode=$s[1]; $mtime=$s[9]; if ($inode==0) // This system does not support inodes { $rpath=realpath($path); if ($rpath === false) throw new \Exception("$path: Cannot compute realpath"); if (isset(self::$simul_inode_array[$rpath])) $inode=self::$simul_inode_array[$rpath]; else { // Create a new slot $inode=self::$simul_inode_index++; self::$simul_inode_array[$rpath]=$inode; } } return sprintf('%s_%X_%X_%X',$prefix,$dev,$inode,$mtime); } //--------------------------------- public static function recursiveCopy($src,$dst) { if (is_dir($src)) { $dir = opendir($src); @mkdir($dst); while(($entry=readdir($dir))!==false) { if (($entry==='.')||($entry==='..')) continue; self::recursiveCopy($src.'/'.$entry,$dst.'/'.$entry); } closedir($dir); } else { copy($src,$dst); } } //---------- } // End of class //============================================================================= ?>