initial prototype based on nat-as-server
Some checks failed
PHPUnit / test (push) Has been cancelled

This commit is contained in:
tom.hempel
2026-06-29 12:39:55 +02:00
commit f1caa9e681
148 changed files with 34905 additions and 0 deletions

111
handlers/export.php Normal file
View File

@ -0,0 +1,111 @@
<?php
require_once __DIR__ . '/../lib/submissions.php';
$tokenRec = require_valid_token_web();
if ($method !== 'GET') {
json_error('METHOD_NOT_ALLOWED', 'Method not allowed', 405);
}
if (!empty($_GET['bundle'])) {
require_role(['admin', 'supervisor'], $tokenRec);
try {
$opened = qdb_open_read_or_fail();
[$pdo, $tmpDb, $lockFp] = $opened;
$bundle = qdb_export_all_questionnaires_bundle($pdo);
qdb_discard($tmpDb, $lockFp);
$filename = 'questionnaires_bundle_' . date('Y-m-d_His') . '.json';
qdb_http_download(
json_encode($bundle, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT),
[
'Content-Type' => 'application/json; charset=UTF-8',
'Content-Disposition' => 'attachment; filename="' . $filename . '"',
]
);
} catch (Throwable $e) {
qdb_handler_fail($e, 'Export questionnaires bundle', null, $tmpDb ?? null, $lockFp ?? null);
}
}
if (!empty($_GET['exportAll'])) {
require_role(['admin'], $tokenRec);
try {
$opened = qdb_open_read_or_fail();
[$pdo, $tmpDb, $lockFp] = $opened;
$allVersions = !empty($_GET['allVersions']);
$zipPath = qdb_build_server_export_zip($pdo, $tokenRec, $allVersions);
qdb_discard($tmpDb, $lockFp);
$label = $allVersions ? 'all_versions' : 'current';
$filename = 'responses_export_' . $label . '_' . date('Y-m-d_His') . '.zip';
$zipBody = (string)file_get_contents($zipPath);
@unlink($zipPath);
qdb_http_download($zipBody, [
'Content-Type' => 'application/zip',
'Content-Disposition' => 'attachment; filename="' . $filename . '"',
'Content-Length' => (string)strlen($zipBody),
]);
} catch (Throwable $e) {
qdb_handler_fail($e, 'Export responses ZIP', null, $tmpDb ?? null, $lockFp ?? null);
}
}
$qnID = $_GET['questionnaireID'] ?? '';
if (!$qnID) {
json_error('MISSING_PARAM', 'questionnaireID query param required', 400);
}
$allVersions = !empty($_GET['allVersions']);
try {
$opened = qdb_open_read_or_fail();
[$pdo, $tmpDb, $lockFp] = $opened;
$qn = $pdo->prepare('SELECT * FROM questionnaire WHERE questionnaireID = :id');
$qn->execute([':id' => $qnID]);
$questionnaire = $qn->fetch(PDO::FETCH_ASSOC);
if (!$questionnaire) {
qdb_discard($tmpDb, $lockFp);
json_error('NOT_FOUND', 'Questionnaire not found', 404);
}
$ctx = qdb_export_questionnaire_context($pdo, $qnID);
$questions = $ctx['questions'];
$resultColumns = $ctx['resultColumns'];
$optionTextMap = $ctx['optionTextMap'];
if ($allVersions) {
$rows = qdb_export_all_versions_rows($pdo, $qnID, $questions, $resultColumns, $optionTextMap, $tokenRec);
qdb_discard($tmpDb, $lockFp);
$safeName = qdb_export_safe_basename($questionnaire['name']);
$filename = $safeName . '_all_versions_' . date('Y-m-d') . '.csv';
qdb_http_download(
qdb_export_rows_to_csv_string($rows, qdb_export_all_versions_csv_fallback_header($resultColumns)),
[
'Content-Type' => 'text/csv; charset=UTF-8',
'Content-Disposition' => 'attachment; filename="' . $filename . '"',
]
);
}
$rows = qdb_export_current_rows($pdo, $qnID, $questions, $resultColumns, $optionTextMap, $tokenRec);
qdb_discard($tmpDb, $lockFp);
$safeName = qdb_export_safe_basename($questionnaire['name']);
$filename = $safeName . '_v' . $questionnaire['version'] . '.csv';
qdb_http_download(
qdb_export_rows_to_csv_string($rows, qdb_export_current_csv_fallback_header($resultColumns)),
[
'Content-Type' => 'text/csv; charset=UTF-8',
'Content-Disposition' => 'attachment; filename="' . $filename . '"',
]
);
} catch (Throwable $e) {
qdb_handler_fail($e, 'Export CSV', null, $tmpDb ?? null, $lockFp ?? null);
}