new system prototype
This commit is contained in:
120
lib/repositories/ResultRepo.php
Normal file
120
lib/repositories/ResultRepo.php
Normal file
@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
class ResultRepo
|
||||
{
|
||||
/**
|
||||
* Build the full results payload for a questionnaire, optionally filtered to one client.
|
||||
* Uses rbac_client_filter() so callers only see what their role permits.
|
||||
*
|
||||
* @return array{questionnaire: array, questions: list<array>, clients: list<array>}
|
||||
*/
|
||||
public static function getQuestionnaireResults(
|
||||
PDO $pdo,
|
||||
string $questionnaireID,
|
||||
array $tokenRecord,
|
||||
?string $clientCode = null
|
||||
): array {
|
||||
$qn = $pdo->prepare("SELECT * FROM questionnaire WHERE questionnaireID = :id");
|
||||
$qn->execute([':id' => $questionnaireID]);
|
||||
$questionnaire = $qn->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$questionnaire) {
|
||||
return ['questionnaire' => null, 'questions' => [], 'clients' => []];
|
||||
}
|
||||
|
||||
$qStmt = $pdo->prepare("
|
||||
SELECT questionID, defaultText, type, orderIndex, isRequired
|
||||
FROM question WHERE questionnaireID = :id ORDER BY orderIndex
|
||||
");
|
||||
$qStmt->execute([':id' => $questionnaireID]);
|
||||
$questions = $qStmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
$questionIDs = array_column($questions, 'questionID');
|
||||
|
||||
foreach ($questions as &$q) {
|
||||
$q['isRequired'] = (int) $q['isRequired'];
|
||||
$q['orderIndex'] = (int) $q['orderIndex'];
|
||||
|
||||
$ao = $pdo->prepare("
|
||||
SELECT answerOptionID, defaultText, points, orderIndex
|
||||
FROM answer_option WHERE questionID = :qid ORDER BY orderIndex
|
||||
");
|
||||
$ao->execute([':qid' => $q['questionID']]);
|
||||
$q['answerOptions'] = $ao->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
foreach ($q['answerOptions'] as &$opt) {
|
||||
$opt['points'] = (int) $opt['points'];
|
||||
$opt['orderIndex'] = (int) $opt['orderIndex'];
|
||||
}
|
||||
unset($opt);
|
||||
}
|
||||
unset($q);
|
||||
|
||||
[$rbacClause, $rbacParams] = rbac_client_filter($tokenRecord, 'cl');
|
||||
|
||||
$sql = "
|
||||
SELECT cl.clientCode, cl.coachID,
|
||||
cq.status, cq.startedAt, cq.completedAt, cq.sumPoints, cq.assignedByCoach
|
||||
FROM client cl
|
||||
INNER JOIN completed_questionnaire cq
|
||||
ON cq.clientCode = cl.clientCode AND cq.questionnaireID = :qnid
|
||||
WHERE $rbacClause
|
||||
";
|
||||
$params = array_merge([':qnid' => $questionnaireID], $rbacParams);
|
||||
|
||||
if ($clientCode) {
|
||||
$sql .= " AND cl.clientCode = :cc";
|
||||
$params[':cc'] = $clientCode;
|
||||
}
|
||||
$sql .= " ORDER BY cl.clientCode";
|
||||
|
||||
$cStmt = $pdo->prepare($sql);
|
||||
$cStmt->execute($params);
|
||||
$clients = $cStmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!empty($questionIDs) && !empty($clients)) {
|
||||
$qPlaceholders = implode(',', array_fill(0, count($questionIDs), '?'));
|
||||
$answerStmt = $pdo->prepare("
|
||||
SELECT clientCode, questionID, answerOptionID, freeTextValue, numericValue, answeredAt
|
||||
FROM client_answer
|
||||
WHERE clientCode = ? AND questionID IN ($qPlaceholders)
|
||||
");
|
||||
|
||||
foreach ($clients as &$c) {
|
||||
self::castClientInts($c);
|
||||
|
||||
$answerStmt->execute(array_merge([$c['clientCode']], $questionIDs));
|
||||
$answers = $answerStmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
$answerMap = [];
|
||||
foreach ($answers as $a) {
|
||||
$answerMap[$a['questionID']] = [
|
||||
'answerOptionID' => $a['answerOptionID'],
|
||||
'freeTextValue' => $a['freeTextValue'],
|
||||
'numericValue' => $a['numericValue'] !== null ? (float) $a['numericValue'] : null,
|
||||
'answeredAt' => $a['answeredAt'] !== null ? (int) $a['answeredAt'] : null,
|
||||
];
|
||||
}
|
||||
$c['answers'] = $answerMap;
|
||||
}
|
||||
unset($c);
|
||||
} else {
|
||||
foreach ($clients as &$c) {
|
||||
self::castClientInts($c);
|
||||
$c['answers'] = (object) [];
|
||||
}
|
||||
unset($c);
|
||||
}
|
||||
|
||||
return [
|
||||
'questionnaire' => $questionnaire,
|
||||
'questions' => $questions,
|
||||
'clients' => $clients,
|
||||
];
|
||||
}
|
||||
|
||||
private static function castClientInts(array &$c): void
|
||||
{
|
||||
$c['sumPoints'] = $c['sumPoints'] !== null ? (int) $c['sumPoints'] : null;
|
||||
$c['startedAt'] = $c['startedAt'] !== null ? (int) $c['startedAt'] : null;
|
||||
$c['completedAt'] = $c['completedAt'] !== null ? (int) $c['completedAt'] : null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user