Add frontend test scoring

This commit is contained in:
Wojtek
2026-10-15 12:22:11 +02:00
parent 270143ad6a
commit 9742c273de
8 changed files with 113 additions and 9 deletions
@@ -5,8 +5,18 @@ namespace Komponent\Component\Testquestions\Site\Controller;
defined('_JEXEC') or die;
use Joomla\CMS\MVC\Controller\BaseController;
use Joomla\CMS\Session\Session;
class DisplayController extends BaseController
{
protected $default_view = 'questions';
public function check()
{
if (!Session::checkToken()) {
throw new \RuntimeException('Invalid token', 403);
}
return $this->display();
}
}
@@ -22,7 +22,7 @@ class QuestionsModel extends ListModel
{
$db = Factory::getContainer()->get('DatabaseDriver');
$query = $db->getQuery(true)
->select(['question_type', 'question', 'answer_a', 'answer_b', 'answer_c', 'answer_d', 'answer_open', 'correct_answer', 'image', 'time_limit', 'points'])
->select(['id', 'test_symbol', 'question_type', 'question', 'answer_a', 'answer_b', 'answer_c', 'answer_d', 'answer_open', 'correct_answer', 'image', 'time_limit', 'points'])
->from($db->quoteName('#__testquestions_questions'))
->where($db->quoteName('published') . ' = 1')
->order($db->quoteName('ordering') . ' ASC, ' . $db->quoteName('id') . ' ASC');
@@ -5,12 +5,14 @@ namespace Komponent\Component\Testquestions\Site\View\Questions;
defined('_JEXEC') or die;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
use Joomla\CMS\Factory;
class HtmlView extends BaseHtmlView
{
protected $items;
protected $symbol;
protected $symbols;
protected $results;
public function formatSheetLabel($sheet)
{
@@ -43,6 +45,53 @@ class HtmlView extends BaseHtmlView
$this->items = $this->get('Items');
$this->symbol = $this->get('State')->get('filter.test_symbol');
$this->symbols = $this->get('TestSymbols');
$this->results = $this->buildResults($this->items);
return parent::display($tpl);
}
protected function buildResults(array $items)
{
$input = Factory::getApplication()->getInput();
if ($input->getCmd('task') !== 'check' || $input->getMethod() !== 'POST') {
return null;
}
$answers = (array) $input->post->get('answers', [], 'array');
$results = [];
$correct = 0;
foreach ($items as $item) {
$selected = isset($answers[$item->id]) ? trim((string) $answers[$item->id]) : '';
$isCorrect = false;
if ($item->question_type === 'open') {
$patterns = preg_split('/\s*\|\s*/', (string) $item->answer_open, -1, PREG_SPLIT_NO_EMPTY);
foreach ($patterns as $pattern) {
if (mb_strtolower(trim($pattern), 'UTF-8') === mb_strtolower($selected, 'UTF-8')) {
$isCorrect = true;
break;
}
}
} else {
$isCorrect = (string) $item->correct_answer === $selected;
}
if ($isCorrect) {
$correct++;
}
$results[$item->id] = [
'selected' => $selected,
'correct' => $isCorrect,
];
}
return [
'items' => $results,
'correct' => $correct,
'total' => count($items),
'percentage' => count($items) ? round(($correct / count($items)) * 100, 2) : 0,
];
}
}