Files
nat-as-server/db_view_ordered.php

142 lines
5.4 KiB
PHP

<?php
// /var/www/html/db_view_ordered.php
require_once __DIR__ . '/db_init.php';
header('Content-Type: text/html; charset=UTF-8');
$tokenRec = require_valid_token_web();
$ORDER_JSON = __DIR__ . '/header_order.json';
$LABELS_JSON = __DIR__ . '/questions_en.json';
$VALS_JSON = __DIR__ . '/translations_en.json';
$order = @json_decode(@file_get_contents($ORDER_JSON), true);
$labels = @json_decode(@file_get_contents($LABELS_JSON), true);
$vals = @json_decode(@file_get_contents($VALS_JSON), true);
if (!is_array($order) || empty($order)) { http_response_code(500); echo "header_order.json missing or empty."; exit; }
if (!is_array($labels)) $labels = [];
if (!is_array($vals)) $vals = [];
function t_val(string $id, string $raw, array $vals): string {
if ($raw === '' || $raw === 'None' || $raw === 'Done' || $raw === 'Not Done') return $raw;
$norm = strtolower(preg_replace('/[^a-z0-9]+/i', '_', $raw));
$cands = [$raw];
if ($norm && $norm !== $raw) $cands[] = $norm;
$cands[] = "{$id}_{$raw}";
$cands[] = "{$id}-{$raw}";
$cands[] = "{$id}_{$norm}";
$cands[] = "{$id}-{$norm}";
foreach ($cands as $k) {
if (isset($vals[$k]) && is_string($vals[$k]) && $vals[$k] !== '') return $vals[$k];
}
if (isset($vals[$norm])) return (string)$vals[$norm];
if (isset($vals[$raw])) return (string)$vals[$raw];
return $raw;
}
$dbPath = QDB_PATH;
if (!file_exists($dbPath)) { http_response_code(404); echo "Database not found"; exit; }
$enc = file_get_contents($dbPath);
if ($enc === false) { http_response_code(500); echo "Read error"; exit; }
try { $plain = aes256_cbc_decrypt_bytes($enc, get_master_key_bytes()); }
catch (Throwable $e) { http_response_code(500); echo "Decryption failed"; exit; }
$tmp = tempnam(sys_get_temp_dir(), 'qdb_');
file_put_contents($tmp, $plain);
try {
$pdo = new PDO("sqlite:$tmp");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
[$rbacClause, $rbacParams] = rbac_client_filter($tokenRec);
$clientStmt = $pdo->prepare(
"SELECT client.clientCode FROM client WHERE $rbacClause ORDER BY client.clientCode"
);
foreach ($rbacParams as $k => $v) $clientStmt->bindValue($k, $v);
$clientStmt->execute();
$clients = $clientStmt->fetchAll(PDO::FETCH_COLUMN) ?: [];
$questionnaireIds = $pdo->query("SELECT questionnaireID FROM questionnaire")->fetchAll(PDO::FETCH_COLUMN) ?: [];
$qidSet = array_fill_keys($questionnaireIds, true);
$completed = [];
$cqStmt = $pdo->prepare(
"SELECT cq.clientCode, cq.questionnaireID, cq.status
FROM completed_questionnaire cq
JOIN client ON client.clientCode = cq.clientCode
WHERE $rbacClause"
);
foreach ($rbacParams as $k => $v) $cqStmt->bindValue($k, $v);
$cqStmt->execute();
while ($row = $cqStmt->fetch(PDO::FETCH_ASSOC)) {
$completed[$row['clientCode']][$row['questionnaireID']] = $row['status'];
}
// client_answer uses questionID, which maps to old "questionId" format
$answers = [];
$ansStmt = $pdo->prepare(
"SELECT ca.clientCode, ca.questionID, ca.answerOptionID, ca.freeTextValue, ca.numericValue
FROM client_answer ca
JOIN client ON client.clientCode = ca.clientCode
WHERE $rbacClause"
);
foreach ($rbacParams as $k => $v) $ansStmt->bindValue($k, $v);
$ansStmt->execute();
while ($row = $ansStmt->fetch(PDO::FETCH_ASSOC)) {
$val = $row['freeTextValue'] ?? $row['answerOptionID'] ?? '';
if ($val === '' && $row['numericValue'] !== null) {
$val = (string)$row['numericValue'];
}
$answers[$row['clientCode']][$row['questionID']] = $val;
}
echo '<style>
table{border-collapse:collapse;width:100%;}
th,td{border:1px solid #ddd;padding:6px 8px;text-align:left;vertical-align:top;}
thead th{background:#f7f7f7;position:sticky;top:0;z-index:1;}
thead tr:nth-child(2) th{background:#fafafa;}
.nowrap{white-space:nowrap;}
.chkcol{width:36px;text-align:center;}
</style>';
echo '<table id="qdb-table">';
echo '<thead>';
echo '<tr><th class="chkcol"><input type="checkbox" id="chkAll" title="select all"></th>';
foreach ($order as $id) echo '<th data-id="'.htmlspecialchars($id).'">'.htmlspecialchars($id).'</th>';
echo '</tr>';
echo '<tr><th class="chkcol"></th>';
foreach ($order as $id) {
$lbl = $labels[$id] ?? '';
echo '<th>'.htmlspecialchars($lbl).'</th>';
}
echo '</tr></thead><tbody>';
foreach ($clients as $client) {
echo '<tr data-client="'.htmlspecialchars($client).'">';
echo '<td class="chkcol"><input type="checkbox" class="rowchk"></td>';
foreach ($order as $id) {
if ($id === 'client_code') {
$val = $client;
} elseif (isset($qidSet[$id]) && strpos($id, '-') === false) {
$status = $completed[$client][$id] ?? '';
$val = ($status === 'done' || $status === 'Done') ? 'Done' : ($status !== '' ? $status : 'Not Done');
} else {
$raw = $answers[$client][$id] ?? '';
$val = (strlen(trim($raw)) > 0) ? t_val($id, $raw, $vals) : 'None';
}
echo '<td>'.htmlspecialchars($val).'</td>';
}
echo '</tr>';
}
echo '</tbody></table>';
} catch (Throwable $e) {
http_response_code(500);
error_log($e->getMessage());
echo "Server error";
} finally {
@unlink($tmp);
}