Files
nat-as-server/handlers/questions.php
tom.hempel 06fc134299
Some checks failed
Tests / test (push) Has been cancelled
just testing the environment
2026-05-20 07:10:08 +02:00

187 lines
7.8 KiB
PHP

<?php
$tokenRec = require_valid_token();
switch ($method) {
case 'GET':
$qnID = $_GET['questionnaireID'] ?? '';
if (!$qnID) {
json_error('BAD_REQUEST', 'questionnaireID query param required', 400);
}
[$pdo, $tmpDb, $lockFp] = qdb_open(false);
$stmt = $pdo->prepare("
SELECT questionID, questionnaireID, defaultText, type, orderIndex, isRequired, configJson
FROM question WHERE questionnaireID = :qid ORDER BY orderIndex
");
$stmt->execute([':qid' => $qnID]);
$questions = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($questions as &$q) {
$q['isRequired'] = (int)$q['isRequired'];
$q['orderIndex'] = (int)$q['orderIndex'];
$q['configJson'] = $q['configJson'] ?: '{}';
$ao = $pdo->prepare("
SELECT answerOptionID, questionID, defaultText, points, orderIndex, nextQuestionId
FROM answer_option WHERE questionID = :qid ORDER BY orderIndex
");
$ao->execute([':qid' => $q['questionID']]);
$q['answerOptions'] = $ao->fetchAll(PDO::FETCH_ASSOC);
foreach ($q['answerOptions'] as &$opt) {
$opt['points'] = (int)$opt['points'];
$opt['orderIndex'] = (int)$opt['orderIndex'];
}
$tr = $pdo->prepare("SELECT languageCode, text FROM question_translation WHERE questionID = :qid");
$tr->execute([':qid' => $q['questionID']]);
$q['translations'] = $tr->fetchAll(PDO::FETCH_ASSOC);
}
unset($q);
qdb_discard($tmpDb, $lockFp);
json_success(['questions' => $questions]);
break;
case 'POST':
require_role(['admin', 'supervisor'], $tokenRec);
$body = read_json_body();
if (empty($body['questionnaireID']) || !isset($body['defaultText'])) {
json_error('BAD_REQUEST', 'questionnaireID and defaultText required', 400);
}
$id = bin2hex(random_bytes(16));
$qnID = $body['questionnaireID'];
$text = trim($body['defaultText']);
$type = trim($body['type'] ?? '');
$order = (int)($body['orderIndex'] ?? 0);
$req = (int)($body['isRequired'] ?? 0);
$config = $body['configJson'] ?? '{}';
[$pdo, $tmpDb, $lockFp] = qdb_open(true);
try {
$chk = $pdo->prepare("SELECT 1 FROM questionnaire WHERE questionnaireID = :id");
$chk->execute([':id' => $qnID]);
if (!$chk->fetch()) {
qdb_discard($tmpDb, $lockFp);
json_error('NOT_FOUND', 'Questionnaire not found', 404);
}
if ($order === 0) {
$max = $pdo->prepare("SELECT COALESCE(MAX(orderIndex),0)+1 FROM question WHERE questionnaireID = :id");
$max->execute([':id' => $qnID]);
$order = (int)$max->fetchColumn();
}
$pdo->prepare("INSERT INTO question (questionID, questionnaireID, defaultText, type, orderIndex, isRequired, configJson)
VALUES (:id, :qid, :t, :ty, :o, :r, :cj)")
->execute([':id' => $id, ':qid' => $qnID, ':t' => $text, ':ty' => $type,
':o' => $order, ':r' => $req, ':cj' => $config]);
qdb_save($tmpDb, $lockFp);
json_success(['question' => [
'questionID' => $id, 'questionnaireID' => $qnID, 'defaultText' => $text,
'type' => $type, 'orderIndex' => $order, 'isRequired' => $req,
'configJson' => $config, 'answerOptions' => [], 'translations' => [],
]]);
} catch (QdbHttpResponse $e) {
throw $e;
} catch (Throwable $e) {
qdb_discard($tmpDb, $lockFp);
error_log($e->getMessage());
json_error('SERVER_ERROR', 'Server error', 500);
}
break;
case 'PUT':
require_role(['admin', 'supervisor'], $tokenRec);
$body = read_json_body();
if (empty($body['questionID'])) {
json_error('BAD_REQUEST', 'questionID is required', 400);
}
$id = $body['questionID'];
[$pdo, $tmpDb, $lockFp] = qdb_open(true);
try {
$existing = $pdo->prepare("SELECT * FROM question WHERE questionID = :id");
$existing->execute([':id' => $id]);
$row = $existing->fetch(PDO::FETCH_ASSOC);
if (!$row) {
qdb_discard($tmpDb, $lockFp);
json_error('NOT_FOUND', 'Question not found', 404);
}
$text = trim($body['defaultText'] ?? $row['defaultText']);
$type = trim($body['type'] ?? $row['type']);
$order = (int)($body['orderIndex'] ?? $row['orderIndex']);
$req = (int)($body['isRequired'] ?? $row['isRequired']);
$config = $body['configJson'] ?? $row['configJson'];
$pdo->prepare("UPDATE question SET defaultText = :t, type = :ty, orderIndex = :o, isRequired = :r, configJson = :cj WHERE questionID = :id")
->execute([':t' => $text, ':ty' => $type, ':o' => $order, ':r' => $req, ':cj' => $config, ':id' => $id]);
qdb_save($tmpDb, $lockFp);
json_success(['question' => [
'questionID' => $id, 'questionnaireID' => $row['questionnaireID'],
'defaultText' => $text, 'type' => $type, 'orderIndex' => $order, 'isRequired' => $req,
'configJson' => $config,
]]);
} catch (QdbHttpResponse $e) {
throw $e;
} catch (Throwable $e) {
qdb_discard($tmpDb, $lockFp);
error_log($e->getMessage());
json_error('SERVER_ERROR', 'Server error', 500);
}
break;
case 'DELETE':
require_role(['admin', 'supervisor'], $tokenRec);
$body = read_json_body();
if (empty($body['questionID'])) {
json_error('BAD_REQUEST', 'questionID is required', 400);
}
$id = $body['questionID'];
[$pdo, $tmpDb, $lockFp] = qdb_open(true);
try {
$pdo->exec("PRAGMA foreign_keys = OFF;");
$pdo->beginTransaction();
$aoIds = $pdo->prepare("SELECT answerOptionID FROM answer_option WHERE questionID = :id");
$aoIds->execute([':id' => $id]);
foreach ($aoIds->fetchAll(PDO::FETCH_COLUMN) as $aoid) {
$pdo->prepare("DELETE FROM answer_option_translation WHERE answerOptionID = :id")->execute([':id' => $aoid]);
}
$pdo->prepare("DELETE FROM answer_option WHERE questionID = :id")->execute([':id' => $id]);
$pdo->prepare("DELETE FROM question_translation WHERE questionID = :id")->execute([':id' => $id]);
$pdo->prepare("DELETE FROM client_answer WHERE questionID = :id")->execute([':id' => $id]);
$pdo->prepare("DELETE FROM question WHERE questionID = :id")->execute([':id' => $id]);
$pdo->commit();
$pdo->exec("PRAGMA foreign_keys = ON;");
qdb_save($tmpDb, $lockFp);
json_success(['deleted' => true]);
} catch (QdbHttpResponse $e) {
throw $e;
} catch (Throwable $e) {
if ($pdo->inTransaction()) {
$pdo->rollBack();
}
qdb_discard($tmpDb, $lockFp);
error_log($e->getMessage());
json_error('SERVER_ERROR', 'Server error', 500);
}
break;
case 'PATCH':
require_role(['admin', 'supervisor'], $tokenRec);
$body = read_json_body();
if (empty($body['questionnaireID']) || !is_array($body['order'] ?? null)) {
json_error('BAD_REQUEST', 'questionnaireID and order[] required', 400);
}
[$pdo, $tmpDb, $lockFp] = qdb_open(true);
try {
$stmt = $pdo->prepare("UPDATE question SET orderIndex = :o WHERE questionID = :id AND questionnaireID = :qid");
foreach ($body['order'] as $idx => $qid) {
$stmt->execute([':o' => $idx, ':id' => $qid, ':qid' => $body['questionnaireID']]);
}
qdb_save($tmpDb, $lockFp);
json_success(['reordered' => true]);
} catch (QdbHttpResponse $e) {
throw $e;
} catch (Throwable $e) {
qdb_discard($tmpDb, $lockFp);
error_log($e->getMessage());
json_error('SERVER_ERROR', 'Server error', 500);
}
break;
default:
json_error('METHOD_NOT_ALLOWED', 'Method not allowed', 405);
}