enhanced questionnaire version handling and handling uploads from outdated questionnaires through automatic revisioning and checks
Some checks failed
PHPUnit / test (push) Has been cancelled
Some checks failed
PHPUnit / test (push) Has been cancelled
This commit is contained in:
@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/../lib/questionnaire_structure.php';
|
||||
|
||||
$tokenRec = require_valid_token_web();
|
||||
$method = $_SERVER['REQUEST_METHOD'];
|
||||
|
||||
@ -50,12 +52,14 @@ case 'POST':
|
||||
|
||||
[$pdo, $tmpDb, $lockFp] = qdb_open_write_or_fail();
|
||||
try {
|
||||
$chk = $pdo->prepare('SELECT 1 FROM question WHERE questionID = :id');
|
||||
$chk = $pdo->prepare('SELECT questionnaireID FROM question WHERE questionID = :id');
|
||||
$chk->execute([':id' => $qID]);
|
||||
if (!$chk->fetch()) {
|
||||
$qnID = $chk->fetchColumn();
|
||||
if (!$qnID) {
|
||||
qdb_discard($tmpDb, $lockFp);
|
||||
json_error('NOT_FOUND', 'Question not found', 404);
|
||||
}
|
||||
$qnID = (string)$qnID;
|
||||
if ($order === 0) {
|
||||
$max = $pdo->prepare('SELECT COALESCE(MAX(orderIndex),0)+1 FROM answer_option WHERE questionID = :id');
|
||||
$max->execute([':id' => $qID]);
|
||||
@ -65,8 +69,11 @@ case 'POST':
|
||||
$pdo->prepare('INSERT INTO answer_option (answerOptionID, questionID, defaultText, points, orderIndex, nextQuestionId) VALUES (:id, :qid, :t, :p, :o, :nq)')
|
||||
->execute([':id' => $id, ':qid' => $qID, ':t' => $optKey, ':p' => $points, ':o' => $order, ':nq' => $nextQ]);
|
||||
qdb_upsert_source_translation($pdo, 'answer_option', $id, $text);
|
||||
$newRev = qdb_bump_structure_revision($pdo, $qnID, 'option_added');
|
||||
qdb_save($tmpDb, $lockFp);
|
||||
json_success(['answerOption' => [
|
||||
json_success([
|
||||
'structureRevision' => $newRev,
|
||||
'answerOption' => [
|
||||
'answerOptionID' => $id,
|
||||
'questionID' => $qID,
|
||||
'optionKey' => $optKey,
|
||||
@ -115,11 +122,19 @@ case 'PUT':
|
||||
$order = (int)($body['orderIndex'] ?? $row['orderIndex']);
|
||||
$nextQ = trim($body['nextQuestionId'] ?? $row['nextQuestionId']);
|
||||
|
||||
$keyChanged = $optKey !== qdb_option_key($row);
|
||||
$pdo->prepare('UPDATE answer_option SET defaultText = :t, points = :p, orderIndex = :o, nextQuestionId = :nq WHERE answerOptionID = :id')
|
||||
->execute([':t' => $optKey, ':p' => $points, ':o' => $order, ':nq' => $nextQ, ':id' => $id]);
|
||||
qdb_upsert_source_translation($pdo, 'answer_option', $id, $labelGerman);
|
||||
$qnID = qdb_questionnaire_id_for_question($pdo, (string)$row['questionID']);
|
||||
$newRev = null;
|
||||
if ($keyChanged && $qnID !== null) {
|
||||
$newRev = qdb_bump_structure_revision($pdo, $qnID, 'option_key_changed');
|
||||
}
|
||||
qdb_save($tmpDb, $lockFp);
|
||||
json_success(['answerOption' => [
|
||||
json_success([
|
||||
'structureRevision' => $newRev ?? ($qnID !== null ? qdb_questionnaire_structure_revision($pdo, $qnID) : 1),
|
||||
'answerOption' => [
|
||||
'answerOptionID' => $id,
|
||||
'questionID' => $row['questionID'],
|
||||
'optionKey' => $optKey,
|
||||
@ -144,15 +159,35 @@ case 'DELETE':
|
||||
|
||||
[$pdo, $tmpDb, $lockFp] = qdb_open_write_or_fail();
|
||||
try {
|
||||
$pdo->exec('PRAGMA foreign_keys = OFF;');
|
||||
$existing = $pdo->prepare('SELECT questionID FROM answer_option WHERE answerOptionID = :id');
|
||||
$existing->execute([':id' => $id]);
|
||||
$qid = $existing->fetchColumn();
|
||||
if (!$qid) {
|
||||
qdb_discard($tmpDb, $lockFp);
|
||||
json_error('NOT_FOUND', 'Answer option not found', 404);
|
||||
}
|
||||
$qnID = qdb_questionnaire_id_for_question($pdo, (string)$qid);
|
||||
if ($qnID === null) {
|
||||
qdb_discard($tmpDb, $lockFp);
|
||||
json_error('NOT_FOUND', 'Question not found', 404);
|
||||
}
|
||||
$pdo->beginTransaction();
|
||||
$newRev = qdb_bump_structure_revision($pdo, $qnID, 'option_removed');
|
||||
if (qdb_option_has_client_data($pdo, $id)) {
|
||||
$pdo->prepare('UPDATE answer_option SET retiredAt = :ts WHERE answerOptionID = :id')
|
||||
->execute([':ts' => time(), ':id' => $id]);
|
||||
$pdo->commit();
|
||||
qdb_save($tmpDb, $lockFp);
|
||||
json_success(['deleted' => false, 'retired' => true, 'structureRevision' => $newRev]);
|
||||
break;
|
||||
}
|
||||
$pdo->exec('PRAGMA foreign_keys = OFF;');
|
||||
$pdo->prepare('DELETE FROM answer_option_translation WHERE answerOptionID = :id')->execute([':id' => $id]);
|
||||
$pdo->prepare('UPDATE client_answer SET answerOptionID = NULL WHERE answerOptionID = :id')->execute([':id' => $id]);
|
||||
$pdo->prepare('DELETE FROM answer_option WHERE answerOptionID = :id')->execute([':id' => $id]);
|
||||
$pdo->commit();
|
||||
$pdo->exec('PRAGMA foreign_keys = ON;');
|
||||
$pdo->commit();
|
||||
qdb_save($tmpDb, $lockFp);
|
||||
json_success(['deleted' => true]);
|
||||
json_success(['deleted' => true, 'retired' => false, 'structureRevision' => $newRev]);
|
||||
} catch (Throwable $e) {
|
||||
qdb_handler_fail($e, 'Delete answer option', $pdo ?? null, $tmpDb ?? null, $lockFp ?? null);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user