* @license PHP License * @package WB * @subpackage base */ /** * File operation * * Simplifies file handling. Make sure all file are within wb/dir/base * and have proper file permissions * * @version 0.5.0 * @package WB * @subpackage base */ class WBFile extends WBStdClass { /** * base dir * @var string */ protected $base; /** * length of base dir string * @var int */ protected $baseLen = 0; /** * dirname * @var string */ protected $dir = ''; /** * basename * @var string */ protected $file = ''; /** * file handle * @var resource */ protected $fh; /** * * @return unknown_type */ public function __construct() { $this->base = realpath(WBParam::get('wb/dir/base')) . '/'; $this->baseLen = strlen($this->base); } /** * Destructor * * Close open file handle */ public function __destruct() { if (empty($this->fh)) { return; } $this->close(); } /** * Open CSV file * * Wrapper to fopen() * * @see fopen() * @param string $mode */ public function open($mode = 'r') { $this->fh = fopen($this->realpath(), $mode); return $this; } /** * Close * * Close open file handle */ public function close() { fclose($this->fh); $this->fh = null; return $this; } /** * Fseek wrapper * * Jump to position in file * * @see fseek() * @param int $offset * @param int $whence */ public function seek($offset, $whence = SEEK_SET) { fseek($this->fh, $offset, $whence); } /** * Ftell wrapper * * Get current offset in file * * @see ftell() * @return int */ public function tell() { return ftell($this->fh); } /** * Feof wrapper * * @see feof() * @return bool */ public function eof() { return feof($this->fh); } /** * Get Line From File * * @param int max length * @return string */ public function get($length = 4096) { return fgets($this->fh, $length); } /** * Write to File * * @param string * @param int length, -1 for auto */ public function put($cnt, $length = -1) { if (-1 == $length) { $length = strlen($cnt); } return fputs($this->fh, $cnt, $length); } /** * guess mime type * * Try several methods to guess mime type and normalize output * * @param string $path * @return array major and minor mime type */ public function getMimeType($path = null) { if ($path) { $this->exists($path); } $file = $this->realpath(); // use a custom magic database file, if you want $magic = WBParam::get('wb/file/mime/magic', ''); // import file using mime-type importer if (function_exists('finfo_open')) { $finfo = new finfo(FILEINFO_MIME, $magic); $mime = $finfo->file($file); } else { $cmd = 'file -bi%s ' . $file; if (empty($magic)) { $cmd = sprintf($cmd, ''); } else { $cmd = sprintf($cmd, ' -m ' . $magic); } exec($cmd, $out); $mime = array_shift($out); } if (!$mime || empty($mime)) { $mime = 'unknown/unknown'; } // separate major and minor mime type $mime = explode('/', $mime, 2); // strip optional charset and stuff list($mime[1]) = explode(' ', $mime[1]); list($mime[1]) = explode(';', $mime[1]); return $mime; } /** * check whether file exists * * In case file exists, internal file pointer are set accordingly * * @see file_exists() * @param string $path * @return bool true if file/dir exists */ public function exists($path = null) { if ($path === null) { $path = $this->dir . $this->file; } if (!file_exists($this->base . $path)) { return false; } if (is_dir($this->base . $path)) { $this->dir = $path; $this->file = ''; return true; } $this->dir = dirname($path); $this->file = basename($path); return true; } /** * directory? * * Check whether current object represents a folder * * @see isDir() * @param string $path * @return bool true in case path is folder */ public function isDir($path = null) { if ($path !== null) { if (!$this->exists($path)) { return false; } } if (empty($this->file)) { return true; } return false; } /** * file? * * Check whether current object represents a file * * @see isFile() * @param string $path * @return bool true in case path is file */ public function isFile($path = null) { if ($path !== null) { if (!$this->exists($path)) { return false; } } if (empty($this->file)) { return false; } return true; } /** * actually create folder * * @see mkdir * @param string * @return WBFile */ public function mkdir($dir) { if (strstr($dir, '/../') ) { WBClass::load('WBException_File'); throw new WBException_File('Cannot break out of configured wb/dir/base!', 1, __CLASS__); } $this->file = ''; $this->dir = $dir; if (is_dir($this->base . $dir)) { return $this; } $tmp = array(); $dir = explode('/', $dir); foreach ($dir as $d) { $tmp[] = $d; $des = $this->base . implode('/', $tmp); if (is_dir($des)) { continue; } mkdir($des, 0777); chmod($des, 0777); } return $this; } /** * touch file * * @see touch() * @param $file * @return WBFile */ public function touch($file) { $this->dir = dirname($file); $this->mkdir($this->dir); $this->file = basename($file); $file = $this->base . $this->dir . '/' . $this->file; if (file_exists($file)) { return $this; } touch($file); chmod($file, 0666); return $this; } /** * create temporary file * * The temporary file will be created in local temp folder * [BASE_DIR]/var/tmp * Please notice, that you are responsible for removing the file * after use. * * @see tempnam() * @param string * @return WBFile */ public function tempnam($prefix = '') { $this->mkdir('var/tmp'); $file = tempnam($this->base . $this->dir, $prefix); chmod($file, 0666); $this->file = basename($file); return $this; } /** * create temporary folder * * The temporary folder will be created in local temp folder * [BASE_DIR]/var/tmp * Please notice, that you are responsible for removing the folder * after use. * * This method uses tempnam to get a name for temporary folder * * @see tempnam() * @param string * @return WBFile */ public function tempdir($prefix = '') { $this->tempnam($prefix); $tmp = $this->realpath(); $this->mkdir('var/tmp/' . basename($tmp) . '.d'); unlink($tmp); return $this; } /** * delete file * * @return WBFile */ public function unlink() { if (!$this->dir || !$this->file) { return $this; } unlink($this->base . $this->dir . '/' . $this->file); return $this->clear(); } /** * Clear * * Reset internal path */ public function clear() { $this->dir = ''; $this->file = ''; return $this; } /** * Remove folder recursively * * @param string $dir * @param bool $inBaseDir */ public function removeDir($dir = '', $inBaseDir = true) { if (empty($dir)) { $dir = $this->dir; } if ($inBaseDir) { $dir = $this->base . '/' . $dir; } if (!is_dir($dir)) { return; } $di = new DirectoryIterator($dir); foreach ($di as $i) { if ($i->isDot()) { continue; } if ($i->isDir()) { $this->removeDir($i->getPathname(), false); continue; } unlink($i->getPathname()); } rmdir($dir); } /** * copy file * * @see copy() * @param string $src * @return WBFile */ public function copy($src) { $des = $this->base . $this->dir; if (is_file($src)) { if (!$this->file) { $this->file = basename($src); } $des .= '/' . $this->file; } else { $des .= '/' . basename($src); } $this->copyRec($src, $des); return $this; } /** * Recursive Copy * * Allow to copy whole directory structures. * @todo reconsider permissions of file and folders * @param string $src * @param string $des */ private function copyRec($src, $des) { // simple case: copy file if (is_file($src)) { copy($src, $des); chmod($des, 0666); return; } // make folder if (!file_exists($des)) { mkdir($des); chmod($des, 0777); } $di = new DirectoryIterator($src); foreach ($di as $i) { if ($i->isDot()) { continue; } // recursion $this->copyRec($i->getPathname(), $des . '/' . $i->getbasename()); } } /** * move file * * @param string $src * @return WBFile */ public function rename($src) { if (!$this->file) { $this->file = basename($src); } $des = $this->base . $this->dir . '/' . $this->file; rename($src, $des); chmod($des, 0666); return $this; } /** * fetch realpath of current file or directory * * @see ralpath() * @return string */ public function realpath() { if (!$this->dir) { return $this->base; } $dir = $this->base . $this->dir; if (!$this->file) { return realpath($dir); } return realpath($dir . '/' . $this->file); } /** * fetch dirname * * @see dirname() * @return string */ public function dirname() { return $this->dir; } /** * fetch filename * * @see basename() * @param $suffix * @return unknown_type */ public function basename($suffix = null) { if (!$suffix) { return $this->file; } return basename($this->file, $suffix); } /** * get base folder * * Return base installation folder * * @return string */ public function getBase() { return $this->base; } }