enhanced questionnaire version handling and handling uploads from outdated questionnaires through automatic revisioning and checks
Some checks failed
PHPUnit / test (push) Has been cancelled

This commit is contained in:
2026-06-12 21:38:39 +02:00
parent 5dff24a232
commit b4d4de72f4
17 changed files with 1289 additions and 209 deletions

View File

@ -1744,6 +1744,7 @@ function qdb_translation_row_label(array $e): string {
/** Export one questionnaire with structure + all translations (portable JSON). */
function qdb_export_questionnaire_bundle(PDO $pdo, string $qnID): ?array {
require_once __DIR__ . '/lib/scoring.php';
require_once __DIR__ . '/lib/questionnaire_structure.php';
$qn = $pdo->prepare('SELECT * FROM questionnaire WHERE questionnaireID = :id');
$qn->execute([':id' => $qnID]);
$qnRow = $qn->fetch(PDO::FETCH_ASSOC);
@ -1751,10 +1752,11 @@ function qdb_export_questionnaire_bundle(PDO $pdo, string $qnID): ?array {
return null;
}
$qStmt = $pdo->prepare("
SELECT questionID, defaultText, type, orderIndex, isRequired, configJson
FROM question WHERE questionnaireID = :id ORDER BY orderIndex
");
$qStmt = $pdo->prepare(
'SELECT questionID, defaultText, type, orderIndex, isRequired, configJson
FROM question WHERE questionnaireID = :id AND ' . qdb_active_questions_clause('question') . '
ORDER BY orderIndex'
);
$qStmt->execute([':id' => $qnID]);
$questionsOut = [];
@ -1763,10 +1765,11 @@ function qdb_export_questionnaire_bundle(PDO $pdo, string $qnID): ?array {
$config = json_decode($dbQ['configJson'] ?: '{}', true) ?: [];
$optionsOut = [];
$aoStmt = $pdo->prepare("
SELECT answerOptionID, defaultText, points, orderIndex, nextQuestionId
FROM answer_option WHERE questionID = :qid ORDER BY orderIndex
");
$aoStmt = $pdo->prepare(
'SELECT answerOptionID, defaultText, points, orderIndex, nextQuestionId
FROM answer_option WHERE questionID = :qid AND ' . qdb_active_options_clause('answer_option') . '
ORDER BY orderIndex'
);
$aoStmt->execute([':qid' => $dbQ['questionID']]);
$qKey = qdb_question_key($config, $dbQ['defaultText']);
foreach ($aoStmt->fetchAll(PDO::FETCH_ASSOC) as $ao) {
@ -1814,13 +1817,14 @@ function qdb_export_questionnaire_bundle(PDO $pdo, string $qnID): ?array {
return [
'questionnaire' => [
'questionnaireID' => $qnRow['questionnaireID'],
'name' => $qnRow['name'],
'version' => $qnRow['version'],
'state' => $qnRow['state'],
'orderIndex' => (int)$qnRow['orderIndex'],
'showPoints' => (int)$qnRow['showPoints'],
'conditionJson' => $qnRow['conditionJson'] ?: '{}',
'questionnaireID' => $qnRow['questionnaireID'],
'name' => $qnRow['name'],
'version' => $qnRow['version'],
'state' => $qnRow['state'],
'orderIndex' => (int)$qnRow['orderIndex'],
'showPoints' => (int)$qnRow['showPoints'],
'conditionJson' => $qnRow['conditionJson'] ?: '{}',
'structureRevision' => qdb_questionnaire_structure_revision($pdo, $qnID),
],
'questions' => $questionsOut,
'stringTranslations' => $stringTranslations,
@ -1855,7 +1859,7 @@ function qdb_export_scoring_profiles_bundle(PDO $pdo): array {
return qdb_list_scoring_profiles($pdo);
}
/** Remove questionnaire and related rows (no client_answer cleanup for other qns). */
/** Remove questionnaire and related rows (full replace import; not per-question retire). */
function qdb_delete_questionnaire_cascade(PDO $pdo, string $qnID): void {
$qIds = $pdo->prepare('SELECT questionID FROM question WHERE questionnaireID = :id');
$qIds->execute([':id' => $qnID]);
@ -1870,8 +1874,20 @@ function qdb_delete_questionnaire_cascade(PDO $pdo, string $qnID): void {
}
$pdo->prepare('DELETE FROM answer_option WHERE questionID = :qid')->execute([':qid' => $qid]);
$pdo->prepare('DELETE FROM question_translation WHERE questionID = :qid')->execute([':qid' => $qid]);
if (qdb_table_exists($pdo, 'client_answer_submission')) {
$pdo->prepare('DELETE FROM client_answer_submission WHERE questionID = :qid')
->execute([':qid' => $qid]);
}
$pdo->prepare('DELETE FROM client_answer WHERE questionID = :qid')->execute([':qid' => $qid]);
}
if (qdb_table_exists($pdo, 'questionnaire_structure_snapshot')) {
$pdo->prepare('DELETE FROM questionnaire_structure_snapshot WHERE questionnaireID = :id')
->execute([':id' => $qnID]);
}
if (qdb_table_exists($pdo, 'questionnaire_submission')) {
$pdo->prepare('DELETE FROM questionnaire_submission WHERE questionnaireID = :id')
->execute([':id' => $qnID]);
}
$pdo->prepare('DELETE FROM question WHERE questionnaireID = :id')->execute([':id' => $qnID]);
$pdo->prepare('DELETE FROM completed_questionnaire WHERE questionnaireID = :id')->execute([':id' => $qnID]);
$pdo->prepare('DELETE FROM questionnaire WHERE questionnaireID = :id')->execute([':id' => $qnID]);