145 lines
5.0 KiB
PHP
145 lines
5.0 KiB
PHP
<?php
|
|
|
|
namespace Komponent\Component\Testquestions\Site\Model;
|
|
|
|
defined('_JEXEC') or die;
|
|
|
|
use Joomla\CMS\Factory;
|
|
use Joomla\CMS\MVC\Model\BaseDatabaseModel;
|
|
|
|
class SetModel extends BaseDatabaseModel
|
|
{
|
|
protected $resolvedSetId;
|
|
protected $randomizeQuestions = true;
|
|
|
|
protected function getSetId(): int
|
|
{
|
|
$application = Factory::getApplication();
|
|
$menu = $application->getMenu()->getActive();
|
|
$menuSetId = $menu ? (int) $menu->getParams()->get('set_id', 0) : 0;
|
|
|
|
return $application->getInput()->getInt('set_id', $menuSetId);
|
|
}
|
|
|
|
public function getSet()
|
|
{
|
|
$db = Factory::getContainer()->get('DatabaseDriver');
|
|
$setId = $this->getSetId();
|
|
|
|
if ($setId < 1) {
|
|
return null;
|
|
}
|
|
|
|
$set = $db->setQuery(
|
|
$db->getQuery(true)
|
|
->select(['s.*', 'sub.title AS subject_title'])
|
|
->from($db->quoteName('#__testquestions_sets', 's'))
|
|
->leftJoin($db->quoteName('#__testquestions_subjects', 'sub') . ' ON sub.id = s.subject_id')
|
|
->where('s.id = ' . $setId)
|
|
->where('s.parent_id = 0')
|
|
->where('s.published = 1')
|
|
)->loadObject();
|
|
|
|
if (!$set) {
|
|
return null;
|
|
}
|
|
|
|
$this->resolvedSetId = $setId;
|
|
$this->randomizeQuestions = $set->set_type !== 'multi';
|
|
|
|
if ($set->set_type === 'multi') {
|
|
$variantId = (int) $db->setQuery(
|
|
$db->getQuery(true)
|
|
->select('id')
|
|
->from($db->quoteName('#__testquestions_sets'))
|
|
->where('parent_id = ' . $setId)
|
|
->where('published = 1')
|
|
->order('RAND()')
|
|
->setLimit(1)
|
|
)->loadResult();
|
|
|
|
$this->resolvedSetId = $variantId;
|
|
}
|
|
|
|
return $set;
|
|
}
|
|
|
|
public function getItems()
|
|
{
|
|
$db = Factory::getContainer()->get('DatabaseDriver');
|
|
if ($this->resolvedSetId === null) {
|
|
$this->getSet();
|
|
}
|
|
$setId = (int) $this->resolvedSetId;
|
|
|
|
if ($setId < 1) {
|
|
return [];
|
|
}
|
|
|
|
$query = $db->getQuery(true)
|
|
->select(['q.id', 'q.question_type', 'q.question', 'q.answer_a', 'q.answer_b', 'q.answer_c', 'q.answer_d', 'q.answer_open', 'q.correct_answer', 'q.points', 'q.image', 'q.time_limit'])
|
|
->from($db->quoteName('#__testquestions_set_questions', 'sq'))
|
|
->innerJoin($db->quoteName('#__testquestions_questions', 'q') . ' ON q.id = sq.question_id')
|
|
->where('sq.set_id = ' . $setId)
|
|
->where('q.published = 1');
|
|
|
|
$query->order($this->randomizeQuestions ? 'RAND()' : 'sq.ordering ASC, q.id ASC');
|
|
|
|
return $db->setQuery($query)->loadObjectList();
|
|
}
|
|
|
|
public function getSets()
|
|
{
|
|
$db = Factory::getContainer()->get('DatabaseDriver');
|
|
|
|
return $db->setQuery(
|
|
$db->getQuery(true)
|
|
->select(['s.id', 's.title', 'sub.title AS subject_title'])
|
|
->from($db->quoteName('#__testquestions_sets', 's'))
|
|
->leftJoin($db->quoteName('#__testquestions_subjects', 'sub') . ' ON sub.id = s.subject_id')
|
|
->where('s.published = 1')
|
|
->where('s.parent_id = 0')
|
|
->order('sub.title ASC, s.title ASC')
|
|
)->loadObjectList();
|
|
}
|
|
|
|
public function saveResult(string $participantName, int $extraTime, int $startedAt, array $result): bool
|
|
{
|
|
$db = Factory::getContainer()->get('DatabaseDriver');
|
|
$setId = $this->getSetId();
|
|
$user = Factory::getApplication()->getIdentity();
|
|
|
|
if ($setId < 1 || trim($participantName) === '') {
|
|
return false;
|
|
}
|
|
|
|
$pointsBefore = 0;
|
|
$pointsTotal = 0;
|
|
foreach (($result['items'] ?? []) as $item) {
|
|
$pointsTotal += (int) ($item['points'] ?? 0);
|
|
if (!empty($item['correct'])) {
|
|
$pointsBefore += (int) ($item['points'] ?? 0);
|
|
}
|
|
}
|
|
|
|
$row = (object) [
|
|
'set_id' => $setId,
|
|
'participant_name' => trim($participantName),
|
|
'started' => $startedAt > 0 ? gmdate('Y-m-d H:i:s', $startedAt) : null,
|
|
'execution_time' => $startedAt > 0 ? max(0, time() - $startedAt) : 0,
|
|
'extra_time' => max(0, $extraTime),
|
|
'correct_count' => (int) ($result['correct'] ?? 0),
|
|
'total_count' => (int) ($result['total'] ?? 0),
|
|
'percentage' => (float) ($result['percentage'] ?? 0),
|
|
'points_total' => $pointsTotal,
|
|
'points_before' => $pointsBefore,
|
|
'points_after' => $pointsBefore,
|
|
'answers' => json_encode($result['items'] ?? [], JSON_UNESCAPED_UNICODE),
|
|
'created' => Factory::getDate()->toSql(),
|
|
'created_by' => $user ? (int) $user->id : 0,
|
|
];
|
|
|
|
return (bool) $db->insertObject('#__testquestions_results', $row);
|
|
}
|
|
}
|