requireLogin(); if (!class_exists('ZipArchive')) { http_response_code(500); echo 'ZipArchive ist auf diesem Server nicht verfügbar.'; exit; } $id = trim((string) ($_GET['id'] ?? '')); $store = new JsonStore(); $submission = $store->getSubmissionByKey($id); if ($submission === null) { http_response_code(404); echo 'Antrag nicht gefunden.'; exit; } $app = Bootstrap::config('app'); $baseUploads = rtrim((string) $app['storage']['uploads'], '/'); $zipPath = sys_get_temp_dir() . '/antrag_' . $id . '_' . bin2hex(random_bytes(4)) . '.zip'; $zip = new ZipArchive(); if ($zip->open($zipPath, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) { http_response_code(500); echo 'ZIP konnte nicht erstellt werden.'; exit; } foreach ((array) ($submission['uploads'] ?? []) as $field => $files) { foreach ((array) $files as $file) { if (!is_array($file)) { continue; } $relativePath = str_replace(['..', '\\'], '', (string) ($file['relative_path'] ?? '')); $fullPath = $baseUploads . '/' . ltrim($relativePath, '/'); if (!is_file($fullPath)) { continue; } $name = (string) ($file['original_filename'] ?? basename($fullPath)); $name = str_replace(["\r", "\n"], '', $name); $zipEntry = $field . '/' . $name; $suffix = 1; while ($zip->locateName($zipEntry) !== false) { $zipEntry = $field . '/' . $suffix . '_' . $name; $suffix++; } $zip->addFile($fullPath, $zipEntry); } } $zip->close(); header('Content-Type: application/zip'); header('Content-Length: ' . (string) filesize($zipPath)); header('Content-Disposition: attachment; filename="antrag_' . $id . '.zip"'); readfile($zipPath); unlink($zipPath); exit;