download-zip.php 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. <?php
  2. declare(strict_types=1);
  3. use App\App\Bootstrap;
  4. use App\Admin\Auth;
  5. use App\Storage\JsonStore;
  6. require dirname(__DIR__) . '/src/autoload.php';
  7. Bootstrap::init();
  8. $auth = new Auth();
  9. $auth->requireLogin();
  10. if (!class_exists('ZipArchive')) {
  11. http_response_code(500);
  12. echo 'ZipArchive ist auf diesem Server nicht verfügbar.';
  13. exit;
  14. }
  15. $id = trim((string) ($_GET['id'] ?? ''));
  16. $store = new JsonStore();
  17. $submission = $store->getSubmissionByKey($id);
  18. if ($submission === null) {
  19. http_response_code(404);
  20. echo 'Antrag nicht gefunden.';
  21. exit;
  22. }
  23. $app = Bootstrap::config('app');
  24. $baseUploads = rtrim((string) $app['storage']['uploads'], '/');
  25. $formData = (array) ($submission['form_data'] ?? []);
  26. $vorname = preg_replace('/[^a-zA-Z0-9-]/', '_', (string) ($formData['vorname'] ?? ''));
  27. $nachname = preg_replace('/[^a-zA-Z0-9-]/', '_', (string) ($formData['nachname'] ?? ''));
  28. $namePart = trim($vorname . '_' . $nachname, '_');
  29. if ($namePart === '') {
  30. $namePart = $id;
  31. }
  32. $zipPath = sys_get_temp_dir() . '/antrag_' . $namePart . '_' . bin2hex(random_bytes(4)) . '.zip';
  33. $zip = new ZipArchive();
  34. if ($zip->open($zipPath, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) {
  35. http_response_code(500);
  36. echo 'ZIP konnte nicht erstellt werden.';
  37. exit;
  38. }
  39. foreach ((array) ($submission['uploads'] ?? []) as $field => $files) {
  40. foreach ((array) $files as $file) {
  41. if (!is_array($file)) {
  42. continue;
  43. }
  44. $relativePath = str_replace(['..', '\\'], '', (string) ($file['relative_path'] ?? ''));
  45. $fullPath = $baseUploads . '/' . ltrim($relativePath, '/');
  46. if (!is_file($fullPath)) {
  47. continue;
  48. }
  49. $name = (string) ($file['original_filename'] ?? basename($fullPath));
  50. $name = str_replace(["\r", "\n"], '', $name);
  51. $zipEntry = $field . '/' . $name;
  52. $suffix = 1;
  53. while ($zip->locateName($zipEntry) !== false) {
  54. $zipEntry = $field . '/' . $suffix . '_' . $name;
  55. $suffix++;
  56. }
  57. $zip->addFile($fullPath, $zipEntry);
  58. }
  59. }
  60. $zip->close();
  61. header('Content-Type: application/zip');
  62. header('Content-Length: ' . (string) filesize($zipPath));
  63. header('Content-Disposition: attachment; filename="antrag_' . $namePart . '.zip"');
  64. readfile($zipPath);
  65. unlink($zipPath);
  66. exit;