download.php 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  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. $id = trim((string) ($_GET['id'] ?? ''));
  11. $field = trim((string) ($_GET['field'] ?? ''));
  12. $index = (int) ($_GET['index'] ?? -1);
  13. $store = new JsonStore();
  14. $submission = $store->getSubmissionByKey($id);
  15. if ($submission === null) {
  16. http_response_code(404);
  17. echo 'Antrag nicht gefunden.';
  18. exit;
  19. }
  20. $entry = $submission['uploads'][$field][$index] ?? null;
  21. if (!is_array($entry)) {
  22. http_response_code(404);
  23. echo 'Datei nicht gefunden.';
  24. exit;
  25. }
  26. $app = Bootstrap::config('app');
  27. $base = rtrim((string) $app['storage']['uploads'], '/');
  28. $relativePath = (string) ($entry['relative_path'] ?? '');
  29. $relativePath = str_replace(['..', '\\'], '', $relativePath);
  30. $fullPath = $base . '/' . ltrim($relativePath, '/');
  31. if (!is_file($fullPath)) {
  32. http_response_code(404);
  33. echo 'Datei nicht vorhanden.';
  34. exit;
  35. }
  36. $downloadName = (string) ($entry['original_filename'] ?? basename($fullPath));
  37. $downloadName = str_replace(["\r", "\n"], '', $downloadName);
  38. $fallbackName = preg_replace('/[^A-Za-z0-9._-]/', '_', $downloadName) ?: 'download.bin';
  39. $encodedName = rawurlencode($downloadName);
  40. header('Content-Type: ' . ((string) ($entry['mime'] ?? 'application/octet-stream')));
  41. header('Content-Length: ' . (string) filesize($fullPath));
  42. header('Content-Disposition: attachment; filename="' . $fallbackName . '"; filename*=UTF-8\'\'' . $encodedName);
  43. readfile($fullPath);
  44. exit;