/** * Create a symlink and return the Fs interface. * * @param string $target * @param string $link * @param int $flags Fs::% options as binary set * @param string $default Type for $target if file does not exist. * @return Fs_Node */ public static function symlink($target, $link, $flags = 0, $default = null) { if (is_link($link) && $flags & self::OVERWRITE) { unlink($link); } if (!@symlink($target, $link)) { throw new Fs_Exception("Failed to create symlink '{$link}' to '{$target}'", error_get_last()); } return Fs::get($link, $default); }
/** * Copy or rename/move this file. * * @param callback $fn copy or rename * @param Fs_Dir $dir * @param string $name * @param int $flags Fs::% options as binary set * @return Fs_Node */ protected function doCopyRename($fn, $dir, $name, $flags = 0) { if (empty($name) || $name == '.' || $name == '..' || strpos('/', $name) !== false) { throw new SecurityException("Unable to {$fn} '{$this->_path}' to '{$dir}/{$name}': Invalid filename '{$name}'"); } if (!$dir instanceof Fs_Dir) { $dir = Fs::dir($dir, dirname($this->_path)); } if (!$dir->exists()) { if (~$flags & Fs::MKDIR) { throw new Fs_Exception("Unable to " . ($fn == 'rename' ? 'move' : $fn) . " '{$this->_path}' to '{$dir}/': Directory does not exist"); } $dir->create(); } elseif ($dir->has($name)) { $dest = $dir->{$name}; if ($dest instanceof Fs_Dir && !$dest instanceof Fs_Symlink && count($dest) != 0) { throw new Fs_Exception("Unable to {$fn} '{$this->_path}' to '{$dest->_path}': Target is a non-empty directory"); } if ($flags & Fs::UPDATE == Fs::UPDATE && $dest['ctime'] >= $this['ctime']) { return false; } if (~$flags & Fs::OVERWRITE) { throw new Fs_Exception("Unable to {$fn} '{$this->_path}' to '{$dest->_path}': Target already exists"); } if ($dest instanceof Fs_Dir) { if (!@rmdir($dest->_path)) { throw new Fs_Exception("Failed to {$fn} '{$this->_path}' to '{$dir}/{$name}'", error_get_last()); } } elseif ($this instanceof Fs_Dir) { if (!unlink($dest->_path)) { throw new Fs_Exception("Failed to {$fn} '{$this->_path}' to '{$dir}/{$name}'", error_get_last()); } } } if ($fn == 'copy' && $flags & Fs::NO_DEREFERENCE) { return Fs::symlink($this->target(), "{$dir}/{$name}"); } if (!@$fn($this->_path, "{$dir}/{$name}")) { throw new Fs_Exception("Failed to {$fn} '{$this->_path}' to '{$dir}/{$name}'", error_get_last()); } return Fs::get("{$dir}/{$name}"); }