142 lines
5.4 KiB
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();
|
|
|
|
$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);
|
|
}
|