175 lines
6.5 KiB
PHP
175 lines
6.5 KiB
PHP
<?php
|
|
/**
|
|
* One-time import: reads the temp-asset JSON files and populates the DB.
|
|
* Run from CLI: php import_questionnaires.php
|
|
* Or via browser (requires admin token): import_questionnaires.php
|
|
*/
|
|
require_once __DIR__ . '/common.php';
|
|
require_once __DIR__ . '/db_init.php';
|
|
|
|
$isCli = (php_sapi_name() === 'cli');
|
|
|
|
if (!$isCli) {
|
|
header('Content-Type: application/json; charset=UTF-8');
|
|
$tokenRec = require_valid_token();
|
|
require_role(['admin'], $tokenRec);
|
|
}
|
|
|
|
function out(string $msg, bool $isCli): void {
|
|
if ($isCli) { echo $msg . "\n"; }
|
|
}
|
|
|
|
$assetsDir = __DIR__ . '/website/temp-assets';
|
|
$orderFile = $assetsDir . '/questionnaire_order.json';
|
|
|
|
$orderData = json_decode(file_get_contents($orderFile), true);
|
|
if (!$orderData) {
|
|
$err = "Could not read questionnaire_order.json";
|
|
if ($isCli) { die($err . "\n"); }
|
|
http_response_code(500);
|
|
echo json_encode(["error" => $err]);
|
|
exit;
|
|
}
|
|
|
|
[$pdo, $tmpDb, $lockFp] = qdb_open(true);
|
|
|
|
try {
|
|
$pdo->beginTransaction();
|
|
|
|
foreach ($orderData as $orderIdx => $entry) {
|
|
$filename = $entry['file'];
|
|
$showPoints = (int)($entry['showPoints'] ?? 0);
|
|
$condition = json_encode($entry['condition'] ?? new stdClass());
|
|
|
|
$jsonPath = $assetsDir . '/' . $filename;
|
|
$qData = json_decode(file_get_contents($jsonPath), true);
|
|
if (!$qData) {
|
|
throw new Exception("Could not parse $filename");
|
|
}
|
|
|
|
$questionnaireID = $qData['meta']['id'];
|
|
$name = str_replace('_', ' ', preg_replace('/^questionnaire_\d+_/', '', $questionnaireID));
|
|
$name = ucwords($name);
|
|
|
|
out("Importing: $questionnaireID ($name)", $isCli);
|
|
|
|
$pdo->prepare("INSERT OR REPLACE INTO questionnaire
|
|
(questionnaireID, name, version, state, orderIndex, showPoints, conditionJson)
|
|
VALUES (:id, :n, :v, :s, :o, :sp, :cj)")
|
|
->execute([
|
|
':id' => $questionnaireID,
|
|
':n' => $name,
|
|
':v' => '1.0',
|
|
':s' => 'active',
|
|
':o' => $orderIdx,
|
|
':sp' => $showPoints,
|
|
':cj' => $condition,
|
|
]);
|
|
|
|
$questions = $qData['questions'] ?? [];
|
|
foreach ($questions as $qIdx => $q) {
|
|
$qLocalId = $q['id'];
|
|
$layout = $q['layout'];
|
|
$qKey = $q['question'] ?? '';
|
|
|
|
$questionID = $questionnaireID . '__' . $qLocalId;
|
|
|
|
$config = [];
|
|
|
|
if (isset($q['textKey'])) $config['textKey'] = $q['textKey'];
|
|
if (isset($q['textKey1'])) $config['textKey1'] = $q['textKey1'];
|
|
if (isset($q['textKey2'])) $config['textKey2'] = $q['textKey2'];
|
|
if (isset($q['hint'])) $config['hint'] = $q['hint'];
|
|
if (isset($q['hint1'])) $config['hint1'] = $q['hint1'];
|
|
if (isset($q['hint2'])) $config['hint2'] = $q['hint2'];
|
|
if (isset($q['symptoms'])) $config['symptoms'] = $q['symptoms'];
|
|
if (isset($q['range'])) $config['range'] = $q['range'];
|
|
if (isset($q['constraints'])) $config['constraints'] = $q['constraints'];
|
|
if (isset($q['minSelection'])) $config['minSelection'] = $q['minSelection'];
|
|
|
|
if ($layout === 'string_spinner' && isset($q['options']) && is_array($q['options'])
|
|
&& isset($q['options'][0]) && is_string($q['options'][0])) {
|
|
$config['options'] = $q['options'];
|
|
}
|
|
|
|
if ($layout === 'value_spinner' && isset($q['options']) && is_array($q['options'])) {
|
|
$valueOptions = [];
|
|
foreach ($q['options'] as $vo) {
|
|
if (is_array($vo) && isset($vo['value'])) {
|
|
$valueOptions[] = $vo;
|
|
}
|
|
}
|
|
if ($valueOptions) {
|
|
$config['valueOptions'] = $valueOptions;
|
|
}
|
|
}
|
|
|
|
$configJson = !empty($config) ? json_encode($config) : '{}';
|
|
|
|
$pdo->prepare("INSERT OR REPLACE INTO question
|
|
(questionID, questionnaireID, defaultText, type, orderIndex, isRequired, configJson)
|
|
VALUES (:id, :qnid, :dt, :ty, :oi, :ir, :cj)")
|
|
->execute([
|
|
':id' => $questionID,
|
|
':qnid' => $questionnaireID,
|
|
':dt' => $qKey,
|
|
':ty' => $layout,
|
|
':oi' => $qIdx,
|
|
':ir' => 0,
|
|
':cj' => $configJson,
|
|
]);
|
|
|
|
if (isset($q['options']) && is_array($q['options'])) {
|
|
$hasObjects = isset($q['options'][0]) && is_array($q['options'][0]);
|
|
if ($hasObjects) {
|
|
$pointsMap = $q['pointsMap'] ?? [];
|
|
foreach ($q['options'] as $optIdx => $opt) {
|
|
$optKey = $opt['key'] ?? '';
|
|
if (!$optKey) continue;
|
|
|
|
$nextQId = '';
|
|
if (isset($opt['nextQuestionId'])) {
|
|
$nextQId = $opt['nextQuestionId'];
|
|
}
|
|
$pts = (int)($pointsMap[$optKey] ?? 0);
|
|
$answerOptionID = $questionID . '__opt_' . $optIdx;
|
|
|
|
$pdo->prepare("INSERT OR REPLACE INTO answer_option
|
|
(answerOptionID, questionID, defaultText, points, orderIndex, nextQuestionId)
|
|
VALUES (:id, :qid, :dt, :p, :oi, :nq)")
|
|
->execute([
|
|
':id' => $answerOptionID,
|
|
':qid' => $questionID,
|
|
':dt' => $optKey,
|
|
':p' => $pts,
|
|
':oi' => $optIdx,
|
|
':nq' => $nextQId,
|
|
]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
out(" -> " . count($questions) . " questions imported", $isCli);
|
|
}
|
|
|
|
$pdo->commit();
|
|
qdb_save($tmpDb, $lockFp);
|
|
|
|
if ($isCli) {
|
|
echo "\nImport complete.\n";
|
|
} else {
|
|
echo json_encode(["success" => true, "message" => "Import complete"]);
|
|
}
|
|
|
|
} catch (Throwable $e) {
|
|
if ($pdo->inTransaction()) $pdo->rollBack();
|
|
qdb_discard($tmpDb, $lockFp);
|
|
if ($isCli) {
|
|
die("ERROR: " . $e->getMessage() . "\n");
|
|
}
|
|
http_response_code(500);
|
|
error_log($e->getMessage());
|
|
echo json_encode(["error" => "Server error"]);
|
|
}
|