'Nenhum item selecionado.'];
}
// Verificar se ZipArchive está disponível
if (!class_exists('ZipArchive')) {
return ['error' => 'Extensão ZIP não disponível no servidor.'];
}
// Criar nome único para o ZIP
$zip_name = 'backup_' . date('Y-m-d_H-i-s') . '_' . substr(md5(uniqid()), 0, 8) . '.zip';
$zip_path = $temp_dir . $zip_name;
$zip = new ZipArchive();
if ($zip->open($zip_path, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== TRUE) {
return ['error' => 'Não foi possível criar o arquivo ZIP.'];
}
$added_count = 0;
$errors_zip = [];
foreach ($items as $item) {
$item = basename($item); // Segurança
$item_path = $current_dir . $item;
if (!file_exists($item_path)) {
$errors_zip[] = "Item não encontrado: " . htmlspecialchars($item);
continue;
}
// Verificar se está dentro da base
$real_path = realpath($item_path);
if ($real_path === false || strpos($real_path . DIRECTORY_SEPARATOR, $base_dir) !== 0) {
$errors_zip[] = "Acesso negado: " . htmlspecialchars($item);
continue;
}
if (is_dir($item_path)) {
// Adicionar pasta recursivamente
$base_path = dirname($real_path) . DIRECTORY_SEPARATOR;
$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($real_path, RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::SELF_FIRST
);
foreach ($files as $file) {
$file_path = $file->getRealPath();
$relative_path = substr($file_path, strlen($base_path));
if ($file->isDir()) {
$zip->addEmptyDir($relative_path);
} else {
$zip->addFile($file_path, $relative_path);
}
$added_count++;
}
} else {
// Adicionar arquivo único
$zip->addFile($real_path, $item);
$added_count++;
}
}
$zip->close();
if ($added_count === 0) {
unlink($zip_path);
return ['error' => 'Nenhum item foi adicionado ao ZIP.'];
}
return [
'success' => true,
'path' => $zip_path,
'name' => $zip_name,
'count' => $added_count,
'errors' => $errors_zip
];
}
// ============================================
// FUNÇÃO: Download múltiplo como ZIP
// ============================================
function downloadMultipleAsZip($items, $current_dir, $base_dir) {
$temp_zip = $base_dir . 'temp_download_' . uniqid() . '.zip';
$zip = new ZipArchive();
if ($zip->open($temp_zip, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== TRUE) {
return false;
}
foreach ($items as $item) {
$item = basename($item);
$item_path = $current_dir . $item;
if (!file_exists($item_path)) continue;
$real_path = realpath($item_path);
if ($real_path === false || strpos($real_path . DIRECTORY_SEPARATOR, $base_dir) !== 0) continue;
if (is_dir($item_path)) {
$base_path = dirname($real_path) . DIRECTORY_SEPARATOR;
$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($real_path, RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::SELF_FIRST
);
foreach ($files as $file) {
$file_path = $file->getRealPath();
$relative_path = substr($file_path, strlen($base_path));
if ($file->isDir()) {
$zip->addEmptyDir($relative_path);
} else {
$zip->addFile($file_path, $relative_path);
}
}
} else {
$zip->addFile($real_path, $item);
}
}
$zip->close();
return $temp_zip;
}
// ============================================
// GERENCIADOR DE ARQUIVOS
// ============================================
// Obter diretório atual da navegação
$rel_dir = '';
if (isset($_GET['dir'])) {
$rel_dir = trim($_GET['dir'], '/\\');
}
// Validar e obter diretório atual
$current_dir = $base_dir;
if (!empty($rel_dir)) {
$test_dir = securePath($rel_dir, $base_dir);
if ($test_dir !== false && is_dir($test_dir)) {
$current_dir = $test_dir;
} else {
$errors[] = "Diretório inválido ou acesso negado.";
$rel_dir = '';
}
}
// Calcular caminho relativo para breadcrumbs
$display_rel = str_replace($base_dir, '', $current_dir);
// ============================================
// AÇÃO: Compactar selecionados
// ============================================
if (isset($_POST['action']) && $_POST['action'] === 'compress' && !empty($_POST['items'])) {
$selected_items = $_POST['items'];
$result = createZipFromSelection($selected_items, $current_dir, $base_dir, $temp_dir);
if (isset($result['error'])) {
$errors[] = $result['error'];
} else {
// Mover ZIP para o diretório atual
$final_path = $current_dir . $result['name'];
if (rename($result['path'], $final_path)) {
chmod($final_path, 0644);
$success = "✅ Compactação concluída!
" .
"Arquivo: " . htmlspecialchars($result['name']) . "
" .
"Itens adicionados: " . $result['count'] . "
" .
"Tamanho: " . formatSize(filesize($final_path));
if (!empty($result['errors'])) {
$success .= "
⚠️ Avisos: " . implode('; ', $result['errors']) . "";
}
} else {
$errors[] = "Erro ao mover arquivo ZIP para o diretório atual.";
}
}
}
// ============================================
// AÇÃO: Download múltiplo
// ============================================
if (isset($_POST['action']) && $_POST['action'] === 'download_selected' && !empty($_POST['items'])) {
$selected_items = $_POST['items'];
if (count($selected_items) === 1) {
// Download único
$item = basename($selected_items[0]);
$item_path = $current_dir . $item;
if (is_file($item_path)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $item . '"');
header('Content-Length: ' . filesize($item_path));
readfile($item_path);
exit;
} else {
// Se for pasta, compactar primeiro
$temp_file = downloadMultipleAsZip([$item], $current_dir, $base_dir);
if ($temp_file && file_exists($temp_file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="' . $item . '.zip"');
header('Content-Length: ' . filesize($temp_file));
readfile($temp_file);
unlink($temp_file);
exit;
}
}
} else {
// Múltiplos itens - compactar e baixar
$temp_file = downloadMultipleAsZip($selected_items, $current_dir, $base_dir);
if ($temp_file && file_exists($temp_file)) {
$download_name = 'arquivos_selecionados_' . date('Y-m-d_H-i-s') . '.zip';
header('Content-Description: File Transfer');
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="' . $download_name . '"');
header('Content-Length: ' . filesize($temp_file));
readfile($temp_file);
unlink($temp_file);
exit;
} else {
$errors[] = "Erro ao preparar download.";
}
}
}
// Ação: Download
if (isset($_GET['download']) && !empty($_GET['download'])) {
$filename = basename($_GET['download']);
$filepath = securePath(($rel_dir ? $rel_dir . '/' : '') . $filename, $base_dir);
if ($filepath !== false && is_file($filepath)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Content-Length: ' . filesize($filepath));
header('Cache-Control: no-cache, must-revalidate');
readfile($filepath);
exit;
} else {
$errors[] = "Arquivo não encontrado ou acesso negado.";
}
}
// Ação: Visualizar arquivo texto
if (isset($_GET['view']) && !empty($_GET['view'])) {
$filename = basename($_GET['view']);
$filepath = securePath(($rel_dir ? $rel_dir . '/' : '') . $filename, $base_dir);
$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
if ($filepath !== false && is_file($filepath) && in_array($ext, $text_extensions)) {
header('Content-Type: text/plain; charset=utf-8');
header('Content-Disposition: inline; filename="' . $filename . '"');
$filesize = filesize($filepath);
if ($filesize > 5 * 1024 * 1024) {
echo "Arquivo muito grande para visualização. Faça o download.";
exit;
}
readfile($filepath);
exit;
} else {
$errors[] = "Arquivo não encontrado, acesso negado ou não é um arquivo de texto.";
}
}
// Ação: Copiar arquivo
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'copy') {
$source_name = basename($_POST['source'] ?? '');
$target_name = basename($_POST['target'] ?? '');
$target_dir_post = $_POST['target_dir'] ?? '';
if (empty($source_name) || empty($target_name)) {
$errors[] = "Nome de arquivo inválido.";
} else {
$source_path = securePath(($rel_dir ? $rel_dir . '/' : '') . $source_name, $base_dir);
$dest_dir = !empty($target_dir_post) ? trim($target_dir_post, '/\\') : $rel_dir;
$dest_dir_path = securePath($dest_dir, $base_dir);
if ($source_path !== false && is_file($source_path) && $dest_dir_path !== false && is_dir($dest_dir_path)) {
$target_path = $dest_dir_path . $target_name;
if (file_exists($target_path)) {
$errors[] = "Arquivo de destino já existe: " . htmlspecialchars($target_name);
} elseif (copy($source_path, $target_path)) {
chmod($target_path, 0644);
$success = "Arquivo copiado com sucesso!
" .
"De: " . htmlspecialchars($source_name) . "
" .
"Para: " . htmlspecialchars($target_name);
} else {
$errors[] = "Erro ao copiar o arquivo. Verifique permissões.";
}
} else {
$errors[] = "Origem ou destino inválido.";
}
}
}
// Ação: Criar nova pasta
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'mkdir') {
$folder_name = basename($_POST['folder_name'] ?? '');
if (empty($folder_name)) {
$errors[] = "Nome da pasta inválido.";
} else {
$new_folder = $current_dir . $folder_name;
if (!file_exists($new_folder)) {
if (mkdir($new_folder, 0755, true)) {
$success = "Pasta criada com sucesso: " . htmlspecialchars($folder_name);
} else {
$errors[] = "Erro ao criar pasta. Verifique permissões.";
}
} else {
$errors[] = "Esta pasta já existe.";
}
}
}
// Ação: Deletar arquivo/pasta
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'delete') {
$item_name = basename($_POST['item'] ?? '');
$item_path = securePath(($rel_dir ? $rel_dir . '/' : '') . $item_name, $base_dir);
if ($item_path !== false && $item_path !== $base_dir && strpos($item_path, $base_dir) === 0) {
if (is_dir($item_path)) {
$contents = scandir($item_path);
if (count($contents) <= 2) {
if (rmdir($item_path)) {
$success = "Pasta removida: " . htmlspecialchars($item_name);
} else {
$errors[] = "Erro ao remover pasta.";
}
} else {
$errors[] = "A pasta não está vazia. Remova os arquivos primeiro.";
}
} elseif (is_file($item_path)) {
if (unlink($item_path)) {
$success = "Arquivo removido: " . htmlspecialchars($item_name);
} else {
$errors[] = "Erro ao remover arquivo.";
}
} else {
$errors[] = "Item não encontrado.";
}
} else {
$errors[] = "Operação não permitida.";
}
}
// ============================================
// UPLOADS
// ============================================
// Upload via URL com cURL
if (isset($_POST['upload_url'])) {
$url = trim($_POST['url']);
$upload_to = isset($_POST['upload_dir']) ? trim($_POST['upload_dir'], '/\\') : '';
$dest_path = securePath($upload_to, $base_dir);
if ($dest_path === false || !is_dir($dest_path)) {
$dest_path = $base_dir;
}
if (empty($url)) {
$errors[] = "URL não pode estar vazia.";
} elseif (!filter_var($url, FILTER_VALIDATE_URL)) {
$errors[] = "URL inválida.";
} else {
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 5,
CURLOPT_TIMEOUT => 30,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_USERAGENT => 'Mozilla/5.0 (compatible; FileManager/1.0)'
]);
$file_content = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$content_type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
$curl_error = curl_error($ch);
curl_close($ch);
if ($curl_error) {
$errors[] = "Erro cURL: " . $curl_error;
} elseif ($http_code !== 200) {
$errors[] = "Erro HTTP: " . $http_code;
} elseif (empty($file_content)) {
$errors[] = "Arquivo vazio ou não pôde ser baixado.";
} else {
$url_parts = parse_url($url);
$path_parts = pathinfo($url_parts['path']);
$original_name = $path_parts['filename'];
$file_ext = strtolower($path_parts['extension'] ?? '');
if (empty($file_ext) && $content_type) {
$mime_map = [
'application/zip' => 'zip',
'application/pdf' => 'pdf',
'image/jpeg' => 'jpg',
'image/png' => 'png',
'text/plain' => 'txt'
];
foreach ($mime_map as $mime => $ext) {
if (strpos($content_type, $mime) !== false) {
$file_ext = $ext;
break;
}
}
}
if (empty($file_ext)) $file_ext = 'bin';
if (!in_array($file_ext, $allowed_types)) {
$errors[] = "Tipo de arquivo não permitido: " . $file_ext;
} else {
$filename = $original_name . '_' . time() . '.' . $file_ext;
$target_path = $dest_path . $filename;
if (file_put_contents($target_path, $file_content)) {
chmod($target_path, 0644);
$success = "Arquivo baixado com sucesso!
" .
"Nome: " . htmlspecialchars($filename) . "
" .
"Tamanho: " . round(strlen($file_content) / 1024, 2) . " KB
" .
"Salvo em: " . htmlspecialchars(str_replace($base_dir, '', $dest_path));
} else {
$errors[] = "Erro ao salvar arquivo.";
}
}
}
}
}
// Upload local
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['fileToUpload'])) {
$upload_to = isset($_POST['upload_dir']) ? trim($_POST['upload_dir'], '/\\') : '';
$dest_path = securePath($upload_to, $base_dir);
if ($dest_path === false || !is_dir($dest_path)) {
$dest_path = $base_dir;
}
$file_name = basename($_FILES["fileToUpload"]["name"]);
$target_file = $dest_path . $file_name;
$fileType = strtolower(pathinfo($target_file, PATHINFO_EXTENSION));
if (!is_uploaded_file($_FILES["fileToUpload"]["tmp_name"])) {
$errors[] = "Arquivo inválido.";
} elseif ($_FILES["fileToUpload"]["size"] > $max_size) {
$errors[] = "Arquivo muito grande. Máximo: " . ($max_size / 1024 / 1024) . "MB";
} elseif (!in_array($fileType, $allowed_types)) {
$errors[] = "Tipo de arquivo não permitido.";
} elseif (file_exists($target_file)) {
$errors[] = "Arquivo já existe.";
} else {
if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
chmod($target_file, 0644);
$success = "Upload realizado com sucesso!
" .
"Nome: " . htmlspecialchars($file_name) . "
" .
"Tamanho: " . round($_FILES["fileToUpload"]["size"] / 1024, 2) . " KB";
} else {
$errors[] = "Erro ao mover arquivo.";
}
}
}
?>