/** * Copy directory. * * Skip unreadable entries. * * @param string $source_dir * @param string $target_dir * @param string $link_root (default = '', if set keep links) */ public static function copy($source_dir, $target_dir, $link_root = '') { if (empty($source_dir)) { throw new Exception("Source directory is empty"); } if (empty($target_dir)) { throw new Exception("Target directory is empty"); } $s = FSEntry::stat($source_dir); if (!FSEntry::isDir($target_dir, false)) { Dir::create($target_dir, $s['perms']['octal']); } $entries = Dir::entries($source_dir); foreach ($entries as $entry) { $s = FSEntry::stat($entry); if ($s['filetype']['is_link'] && $link_root) { if (($pos = mb_strpos($s['file']['realpath'], $link_root)) !== false && $pos == 0) { // link is inside source dir $link_target = str_replace($link_root . '/', '', $s['file']['realpath']); symlink($link_target, $target_dir . '/' . basename($entry)); } else { symlink($s['file']['realpath'], $target_dir . '/' . basename($entry)); } continue; } if (!$s['filetype']['is_readable']) { if (self::$SKIP_UNREADABLE) { continue; } throw new Exception("Entry is unreadable", $entry); } if ($s['filetype']['is_dir']) { $target_subdir = $target_dir . '/' . basename($entry); Dir::create($target_subdir, $s['perms']['octal']); Dir::copy($entry, $target_subdir, $link_root); } else { if ($s['filetype']['is_file']) { File::copy($entry, $target_dir . '/' . basename($entry), $s['perms']['octal']); } } } }