19 declare(strict_types=1);
82 $this->ref_id = $this->testrequest->getRefId();
88 $this->
tabs->clearTargets();
90 $cmd = $this->
ctrl->getCmd();
91 $next_class = $this->
ctrl->getNextClass($this);
94 if ($cmd ===
'autosave') {
95 echo $this->
lng->txt(
'autosave_failed') .
': ' . $read_access;
98 $this->tpl->setOnScreenMessage(
'failure', $read_access,
true);
99 $this->
ctrl->redirectByClass([ilRepositoryGUI::class, ilObjTestGUI::class, TestScreenGUI::class]);
102 $this->
ctrl->saveParameter($this,
"sequence");
103 $this->
ctrl->saveParameter($this,
"pmode");
104 $this->
ctrl->saveParameter($this,
"active_id");
109 $this->test_session = $testSessionFactory->getSession($this->testrequest->int(
'active_id'));
117 $this->test_sequence = $test_sequence_factory->getSequenceByTestSession($this->test_session);
118 $this->test_sequence->loadFromDb();
119 $this->test_sequence->loadQuestions();
127 $instance_name = $this->
settings->get(
'short_inst_name') ??
'';
128 if (trim($instance_name) ===
'') {
129 $instance_name =
'ILIAS';
131 $this->global_screen->tool()->context()->current()->addAdditionalData(
135 $this->global_screen->tool()->context()->current()->addAdditionalData(
137 $this->
object->getKioskMode()
139 $this->global_screen->tool()->context()->current()->addAdditionalData(
143 $this->global_screen->tool()->context()->current()->addAdditionalData(
148 switch ($next_class) {
149 case 'ilassquestionpagegui':
155 $page_gui->setFileDownloadLink(
156 $this->
ctrl->getLinkTargetByClass(ilObjTestGUI::class,
'downloadFile')
158 $ret = $this->
ctrl->forwardCommand($page_gui);
161 case 'iltestsubmissionreviewgui':
167 $ret = $this->
ctrl->forwardCommand($gui);
170 case 'ilassspecfeedbackpagegui':
171 case 'ilassgenfeedbackpagegui':
172 $id = $this->testrequest->int(
'pg_id');
173 if ($this->
ctrl->getCmd() !==
'displayMediaFullscreen' 179 $next_class ===
'ilassgenfeedbackpagegui' ?
'qfbg' :
'qfbs',
181 ))->displayMediaFullscreen();
184 case 'iltestpasswordprotectiongui':
192 $this->password_checker,
196 $ret = $this->
ctrl->forwardCommand($gui);
204 if ($cmd ===
'outQuestionSummary' 205 || $cmd ===
'submitSolution') {
209 if ($cmd ===
'showQuestion') {
211 $testPassesSelector->setActiveId($this->test_session->getActiveId());
212 $testPassesSelector->setLastFinishedPass($this->test_session->getLastFinishedPass());
214 if (!$testPassesSelector->openPassExists()) {
215 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'tst_pass_finished'),
true);
216 $this->
ctrl->redirectByClass([ilRepositoryGUI::class, ilObjTestGUI::class, TestScreenGUI::class]);
221 $ret = $this->$cmd();
232 if (!$this->rbac_system->checkAccess(
'read', $this->object->getRefId())) {
233 return $this->
lng->txt(
'cannot_execute_test');
236 $participant_access = (
new ilTestAccess($this->
object->getRefId()))->isParticipantAllowed(
240 if ($participant_access !== ParticipantAccess::ALLOWED) {
241 return $participant_access->getAccessForbiddenMessage($this->
lng);
249 $executable = $this->
object->isExecutable($this->test_session, $this->test_session->getUserId());
251 if (!$executable[
'executable']) {
252 $this->tpl->setOnScreenMessage(
'info', $executable[
'errormessage'],
true);
253 $this->
ctrl->redirectByClass([ilRepositoryGUI::class, ilObjTestGUI::class, TestScreenGUI::class]);
260 throw new ilTestException(
'active id given does not relate to current user!');
287 $this->process_locker = $process_lockerFactory->withContextId((
int) $activeId)->getLocker();
299 $tagging_gui->setObject($this->
object->getId(), $this->
object->getType());
300 $tagging_gui->saveInput();
301 $this->
ctrl->redirectByClass([ilRepositoryGUI::class, ilObjTestGUI::class, ilInfoScreenGUI::class]);
310 $this->
object->updateWorkingTime(
ilSession::get(
"active_time_id"));
315 $this->
object->startWorkingTime(
316 $this->test_session->getActiveId(),
317 $this->test_session->getPass()
327 $this->test_session->getActiveId(),
328 $this->test_session->getPass()
333 bool $authorized =
true,
338 $formtimestamp = $this->testrequest->int(
'formtimestamp');
358 if ($question_obj ===
null) {
363 $saved = $this->
save($question_obj, $authorized);
370 $this->
ctrl->setParameter($this,
'save_error',
'1');
371 ilSession::set(
'previouspost', $this->testrequest->getParsedBody());
379 $q_id = $this->test_sequence->getQuestionForSequence($this->testrequest->int(
'sequence'));
386 if ($q_id ===
null) {
395 $active_id = $this->test_session->getActiveId();
405 if ($authorized && $this->test_session->isObjectiveOriented()) {
407 $objectivesAdapter->updateQuestionResult($this->test_session, $question_obj);
410 if ($authorized && $this->
object->isSkillServiceToBeConsidered()) {
414 if ($authorized && $this->
logger->isLoggingEnabled()
417 $this->
logger->getAdditionalInformationGenerator(),
421 $this->
logger->isIPLoggingEnabled() ?
$_SERVER[
'REMOTE_ADDR'] :
'',
422 TestParticipantInteractionTypes::ANSWER_SUBMITTED
424 $this->
logger->logParticipantInteraction($interaction);
436 $this->
ctrl->redirectByClass(TestScreenGUI::class, TestScreenGUI::DEFAULT_CMD);
441 $active_id = $this->test_session->getActiveId();
442 $starting_time = $this->
object->getStartingTimeOfUser($active_id);
443 if ($starting_time ===
false) {
446 return $this->
object->isMaxProcessingTimeReached($starting_time, $active_id);
452 $show_question_inline_score =
false;
453 if ($this->
object->getAnswerFeedbackPoints()) {
454 $show_question_inline_score =
true;
455 return $show_question_inline_score;
457 return $show_question_inline_score;
462 $this->tpl->setCurrentBlock(
'test_nav_toolbar');
463 $this->tpl->setVariable(
'TEST_NAV_TOOLBAR', $toolbar_gui->getHTML());
464 $this->tpl->parseCurrentBlock();
466 if ($this->finish_test_modal ===
null) {
470 $this->tpl->setCurrentBlock(
'finish_test_modal');
471 $this->tpl->setVariable(
473 $this->ui_renderer->render(
474 $this->finish_test_modal->withOnLoad($this->finish_test_modal->getShowSignal())
477 $this->tpl->parseCurrentBlock();
507 $this->tpl->setCurrentBlock(
"next_bottom");
508 $this->tpl->setVariable(
"BTN_NEXT_BOTTOM", $this->ui_renderer->render($button));
509 $this->tpl->parseCurrentBlock();
516 $this->tpl->setCurrentBlock(
"next");
517 $this->tpl->setVariable(
"BTN_NEXT", $this->ui_renderer->render($button));
518 $this->tpl->parseCurrentBlock();
525 $this->tpl->setCurrentBlock(
"prev_bottom");
526 $this->tpl->setVariable(
"BTN_PREV_BOTTOM", $this->ui_renderer->render($button));
527 $this->tpl->parseCurrentBlock();
534 $this->tpl->setCurrentBlock(
"prev");
535 $this->tpl->setVariable(
"BTN_PREV", $this->ui_renderer->render($button));
536 $this->tpl->parseCurrentBlock();
547 $button = $this->ui_factory->button()->primary(
548 $this->
lng->txt(
'next_question') . $this->ui_renderer->render($this->ui_factory->symbol()->glyph()->next()),
550 )->withUnavailableAction(
true)
553 $button = $this->ui_factory->button()->standard(
554 $this->
lng->txt(
'next_question') . $this->ui_renderer->render($this->ui_factory->symbol()->glyph()->next()),
556 )->withUnavailableAction(
true)
569 $button = $this->ui_factory->button()->standard(
570 $this->ui_renderer->render($this->ui_factory->symbol()->glyph()->back()) . $this->
lng->txt(
'previous_question'),
572 )->withUnavailableAction(
true)
579 return static function (
string $id) use ($target, $cmd):
string {
580 return "document.getElementById('{$id}').addEventListener('click', " 581 .
"(e) => {il.TestPlayerQuestionEditControl.checkNavigation('{$target}', '{$cmd}', e);}" 583 .
"document.getElementById('{$id}').removeAttribute('disabled');";
592 $solutionValues = $question_gui->
getObject()->getSolutionValues(
593 $this->test_session->getActiveId(),
598 $question_gui->
getObject()->fetchIndexedValuesFromValuePairs($solutionValues)
601 if (!empty($feedback)) {
602 $this->tpl->setCurrentBlock(
"specific_feedback");
603 $this->tpl->setVariable(
"SPECIFIC_FEEDBACK", $feedback);
604 $this->tpl->parseCurrentBlock();
616 $feedback = $question_gui->
getGenericFeedbackOutput($this->test_session->getActiveId(), $this->test_session->getPass());
618 if (strlen($feedback)) {
624 $this->tpl->setCurrentBlock(
"answer_feedback");
625 $this->tpl->setVariable(
"ANSWER_FEEDBACK", $feedback);
626 $this->tpl->setVariable(
"ILC_FB_CSS_CLASS", $cssClass);
627 $this->tpl->parseCurrentBlock();
635 $scoreInformation = sprintf(
636 $this->
lng->txt(
"you_received_a_of_b_points"),
641 $this->tpl->setCurrentBlock(
"received_points_information");
642 $this->tpl->setVariable(
"RECEIVED_POINTS_INFORMATION", $scoreInformation);
643 $this->tpl->parseCurrentBlock();
648 if (strlen($solutionoutput)) {
649 $this->tpl->setCurrentBlock(
"solution_output");
650 $this->tpl->setVariable(
"CORRECT_SOLUTION", $this->
lng->txt(
"tst_best_solution_is"));
651 $this->tpl->setVariable(
"QUESTION_FEEDBACK", $solutionoutput);
652 $this->tpl->parseCurrentBlock();
658 $this->tpl->setCurrentBlock(
"SyntaxStyle");
659 $this->tpl->setVariable(
660 "LOCATION_SYNTAX_STYLESHEET",
663 $this->tpl->parseCurrentBlock();
668 $this->tpl->setCurrentBlock(
"ContentStyle");
669 $this->tpl->setVariable(
670 "LOCATION_CONTENT_STYLESHEET",
673 $this->tpl->parseCurrentBlock();
683 if ($this->test_session->isAnonymousUser()) {
684 $this->test_session->setAccessCodeToSession($this->testrequest->strVal(
'anonymous_id'));
687 $this->
ctrl->redirectByClass([ilRepositoryGUI::class, ilObjTestGUI::class, ilInfoScreenGUI::class]);
699 $isFirstTestStartRequest =
false;
701 $this->process_locker->executeTestStartLockOperation(
function () use ($testStartLock, &$isFirstTestStartRequest) {
702 if ($this->test_session->lookupTestStartLock() !== $testStartLock) {
703 $this->test_session->persistTestStartLock($testStartLock);
704 $isFirstTestStartRequest =
true;
708 if ($isFirstTestStartRequest) {
713 $this->
ctrl->setParameterByClass(
'ilObjTestGUI',
'lock', $testStartLock);
714 $this->
ctrl->redirectByClass([ilRepositoryGUI::class, ilObjTestGUI::class, ilInfoScreenGUI::class]);
719 if ($this->testrequest->isset(
'lock') && strlen($this->testrequest->raw(
'lock'))) {
720 return $this->testrequest->raw(
'lock');
730 $active_id = $this->test_session->getActiveId();
731 $this->
ctrl->setParameter($this,
"active_id", $active_id);
733 $active_time_id = $this->
object->startWorkingTime($active_id, $this->test_session->getPass());
737 if ($this->
object->isRandomTest()) {
738 if (!$this->test_sequence->hasRandomQuestionsForPass($active_id, $this->test_session->getPass())) {
744 $shuffle = $this->
object->getShuffleQuestions();
745 if ($this->
object->isRandomTest()) {
749 $this->test_result_repository->updateTestAttemptResult(
751 $this->test_session->getPass(),
753 $this->
object->getId()
757 if (!$this->test_sequence->hasSequence()) {
758 $this->test_sequence->createNewSequence($this->
object->getQuestionCount(), $shuffle);
759 $this->test_sequence->saveToDb();
762 if ($this->
object->getListOfQuestionsStart()) {
766 $this->
ctrl->setParameter($this,
'sequence', $this->test_session->getLastSequence());
767 $this->
ctrl->setParameter($this,
'pmode',
'');
776 if ($this->test_session->isAnonymousUser()
777 && !$this->test_session->doesAccessCodeInSessionExists()) {
778 $access_code = $this->test_session->createNewAccessCode();
780 $this->test_session->setAccessCodeToSession($access_code);
781 $this->test_session->setAnonymousId($access_code);
782 $this->test_session->saveToDb();
787 if (!$this->test_session->isAnonymousUser()) {
788 $this->test_session->unsetAccessCodeInSession();
795 $this->tpl->addBlockFile($this->
getContentBlockName(),
"adm_content",
"tpl.il_as_tst_anonymous_code_presentation.html",
"components/ILIAS/Test");
796 $this->tpl->setCurrentBlock(
"adm_content");
797 $this->tpl->setVariable(
"TEXT_ANONYMOUS_CODE_CREATED", $this->
lng->txt(
"tst_access_code_created"));
798 $this->tpl->setVariable(
"TEXT_ANONYMOUS_CODE", $this->test_session->getAccessCodeFromSession());
799 $this->tpl->setVariable(
"FORMACTION", $this->
ctrl->getFormAction($this));
801 $this->tpl->setVariable(
"TXT_CONFIRM", $this->
lng->txt(
"continue_work"));
802 $this->tpl->parseCurrentBlock();
815 if ($this->
object->getNrOfTries() != 1
816 && $this->
object->getUsePreviousAnswers() == 1
818 $chb_use_previous_answers = 0;
819 if ($this->post_wrapper->has(
'chb_use_previous_answers')) {
820 $chb_use_previous_answers = $this->post_wrapper->retrieve(
821 'chb_use_previous_answers',
825 $this->
user->writePref(
"tst_use_previous_answers", (
string) $chb_use_previous_answers);
851 $this->tpl->addBlockFile($this->
getContentBlockName(),
"adm_content",
"tpl.il_as_tst_redirect_autosave.html",
"components/ILIAS/Test");
852 $this->tpl->setVariable(
"TEXT_REDIRECT", $this->
lng->txt(
"redirectAfterSave"));
853 $this->tpl->setVariable(
"URL",
$url);
858 return $this->test_sequence->getQuestionForSequence($this->testrequest->int(
'sequence'));
867 if (!$this->
access->checkAccess(
'read',
'', $this->ref_id)) {
868 echo $this->
lng->txt(
'autosave_failed') .
': ' . $this->
lng->txt(
'msg_no_perm_read_item');
871 $test_can_run = $this->
object->isExecutable($this->test_session, $this->test_session->getUserId());
872 if (!$test_can_run[
'executable']) {
873 echo $test_can_run[
'errormessage'];
876 if ($this->testrequest->getPostKeys() === []) {
887 echo $this->
lng->txt(
'autosave_success');
891 echo $this->
lng->txt(
'autosave_failed');
918 $this->test_session->getActiveId(),
919 $this->test_session->getPass()
922 $result[
'isAnswered'] = $state[
'authorized'];
923 $result[
'isAnswerChanged'] = $state[
'intermediate'];
925 echo json_encode($result);
950 $question_id = $this->test_sequence->getQuestionForSequence(
954 $this->
object->setQuestionSetSolved(1, $question_id, $this->test_session->getUserId());
972 $question_id = $this->test_sequence->getQuestionForSequence(
976 $this->
object->setQuestionSetSolved(0, $question_id, $this->test_session->getUserId());
986 if ($this->testrequest->strVal(
'finalization_confirmed') !==
'confirmed') {
999 if ($this->
logger->isLoggingEnabled()
1001 && ($interaction = $this->
logger->getInteractionFactory()->buildParticipantInteraction(
1004 $this->
user->getId(),
1005 $this->
logger->isIPLoggingEnabled() ?
$_SERVER[
'REMOTE_ADDR'] :
'',
1009 $this->
logger->logParticipantInteraction($interaction);
1018 $this->test_session,
1020 $this->test_result_repository
1021 ))->performFinishTasks($this->process_locker, $status_of_attempt);
1022 $this->test_result_repository->updateTestResultCache($this->test_session->getActiveId());
1025 $this->test_session->getActiveId(),
1026 $this->test_session->getPass()
1032 $notification_type = $this->
object->getMainSettings()->getFinishingSettings()->getMailNotificationContentType();
1034 if ($notification_type === 0
1035 || !$this->
object->getMainSettings()->getFinishingSettings()->getAlwaysSendMailNotification()
1036 && $pass !== $this->
object->getNrOfTries() - 1) {
1040 switch ($this->
object->getMainSettings()->getFinishingSettings()->getMailNotificationContentType()) {
1042 $this->
object->sendSimpleNotification($active_id);
1045 $this->
object->sendAdvancedNotification($active_id);
1053 if (!$this->testrequest->isset(
'skipfinalstatement')) {
1054 if ($this->
object->getMainSettings()->getFinishingSettings()->getConcludingRemarksEnabled()) {
1060 $redirection_url = $this->
object->getMainSettings()->getFinishingSettings()->getRedirectionUrl();
1061 if (empty($redirection_url)
1062 || $this->
object->canShowTestResults($this->test_session)
1064 || $this->
object->isRedirectModeKiosk() && !$this->
object->getKioskMode()) {
1073 $class = get_class($this);
1074 $this->
ctrl->setParameterByClass($class,
'finalization_confirmed',
'confirmed');
1076 $this->
ctrl->clearParameterByClass($class,
'finalization_confirmed');
1078 $message = $this->
lng->txt(
'tst_finish_confirmation_question');
1079 if (($this->
object->getNrOfTries() - 1) === $this->test_session->getPass()) {
1080 $message = $this->
lng->txt(
'tst_finish_confirmation_question_no_attempts_left');
1083 return $this->ui_factory->modal()->interruptive(
1084 $this->
lng->txt(
'finish_test'),
1087 )->withActionButtonLabel($this->
lng->txt(
'tst_finish_confirm_button'));
1093 $testPassesSelector->setActiveId($this->test_session->getActiveId());
1094 $testPassesSelector->setLastFinishedPass($this->test_session->getLastFinishedPass());
1096 if (count($testPassesSelector->getReportablePasses())) {
1098 $this->
ctrl->redirectByClass([
'ilTestResultsGUI',
'ilTestEvalObjectiveOrientedGUI']);
1101 $this->
ctrl->redirectByClass([ilTestResultsGUI::class, ilMyTestResultsGUI::class, ilTestEvaluationGUI::class]);
1104 $this->
ctrl->redirectByClass(TestScreenGUI::class, TestScreenGUI::DEFAULT_CMD);
1112 $this->global_screen->tool()->context()->current()->getAdditionalData()->replace(
1114 $this->
object->getTitle() .
' - ' . $this->
lng->txt(
'final_statement')
1117 $this->content_style->gui()->addCss($this->tpl, $this->ref_id);
1118 $this->
ctrl->setParameterByClass(ilTestPageGUI::class,
'page_type',
'concludingremarkspage');
1119 $this->
ctrl->setParameterByClass(static::class,
'skipfinalstatement', 1);
1120 $this->tpl->setVariable(
1122 $this->ui_renderer->render([
1123 $this->ui_factory->legacy()->content(
1124 $this->
object->prepareTextareaOutput($this->object->getFinalStatement(),
true)
1126 $this->ui_factory->button()->standard(
1127 $this->
lng->txt(
'btn_next'),
1136 $this->navigation_history->addItem(
1137 $this->test_session->getRefId(),
1151 if ($this->
object->endingTimeReached()) {
1157 $this->
ctrl->setParameter($this,
"sequence", $sequenceElement);
1162 $this->tpl->setVariable(
"TEST_ID", (
string) $this->
object->getTestId());
1163 $this->tpl->setVariable(
"LOGIN", $this->
user->getLogin());
1165 $this->tpl->setVariable(
"SEQ_ID", $sequenceElement);
1166 $this->tpl->setVariable(
"QUEST_ID", $question_id);
1168 if ($this->
object->getEnableProcessingTime()) {
1172 $this->tpl->setVariable(
"PAGETITLE",
"- " . $this->
object->getTitle());
1174 if ($this->
object->isShowExamIdInTestPassEnabled() && !$this->
object->getKioskMode()) {
1175 $this->tpl->setCurrentBlock(
'exam_id_footer');
1177 $this->test_session->getActiveId(),
1178 $this->test_session->getPass(),
1179 $this->
object->getId()
1181 $this->tpl->setVariable(
'EXAM_ID_TXT', $this->
lng->txt(
'exam_id'));
1182 $this->tpl->parseCurrentBlock();
1185 if ($this->
object->getListOfQuestions()) {
1192 if ($this->test_sequence->isAnsweringOptionalQuestionsConfirmed()) {
1196 $question_id = $this->test_sequence->getQuestionForSequence($sequence_key);
1198 if (!$this->test_sequence->isQuestionOptional($question_id)) {
1207 return $this->test_sequence->isPostponedQuestion($question_id);
1212 string $form_action,
1213 bool $is_question_worked_through,
1214 bool $instant_response
1217 $question_navigation_gui->setQuestionWorkedThrough($is_question_worked_through);
1222 $this->test_session->getActiveId(),
1223 $this->test_session->getPass(),
1227 $instant_response && $this->
object->getSpecificAnswerFeedback(),
1236 $this->test_session->getActiveId(),
1240 $this->tpl->setVariable(
1241 'LOCKSTATE_INFOBOX',
1242 $this->ui_renderer->render(
1243 $this->ui_factory->messageBox()->info($this->
lng->txt(
'tst_player_answer_saved_and_locked'))
1246 $this->tpl->parseCurrentBlock();
1247 $this->tpl->setVariable(
'QUESTION_OUTPUT', $pageoutput);
1248 $this->tpl->setVariable(
'FORMACTION', $form_action);
1249 $this->tpl->setVariable(
'ENCTYPE',
'enctype="' . $question_gui->
getFormEncodingType() .
'"');
1250 $this->tpl->setVariable(
'FORM_TIMESTAMP', time());
1256 string $form_action,
1257 bool $is_question_worked_through,
1258 bool $instant_response
1261 $question_navigation_gui->setQuestionWorkedThrough($is_question_worked_through);
1262 if ($is_question_worked_through) {
1263 $question_navigation_gui->setDiscardSolutionButtonEnabled(
true);
1265 } elseif ($this->
object->isPostponingEnabled()) {
1266 $question_navigation_gui->setSkipQuestionLinkTarget(
1272 $user_post_solution =
false;
1273 if ($this->testrequest->isset(
'save_error')
1274 && $this->testrequest->int(
'save_error') === 1
1280 $question_config = $question_gui->
getObject()->getTestPresentationConfig();
1283 $question_config->setWorkedThrough($is_question_worked_through);
1286 if ($question_config->isPreviousPassSolutionReuseAllowed()) {
1288 if ($pass_index < $this->test_session->getPass()) {
1289 $question_config->setSolutionInitiallyPrefilled(
true);
1292 $pass_index = $this->test_session->getPass();
1297 $question_navigation_gui->setShowDiscardModalSignal($this->modal_signals[self::DISCARD_MODAL]);
1301 $this->test_session->getActiveId(),
1304 $user_post_solution,
1305 $instant_response && $this->
object->getSpecificAnswerFeedback()
1313 if ($this->
object->isPreviousSolutionReuseEnabled($this->test_session->getActiveId())) {
1314 $currentSolutionAvailable = $question_gui->
getObject()->authorizedOrIntermediateSolutionExists(
1315 $this->test_session->getActiveId(),
1316 $this->test_session->getPass()
1319 if (!$currentSolutionAvailable) {
1320 $previousPass = $question_gui->
getObject()->getSolutionMaxPass(
1321 $this->test_session->getActiveId()
1324 $previousSolutionAvailable = $question_gui->
getObject()->authorizedSolutionExists(
1325 $this->test_session->getActiveId(),
1329 if ($previousSolutionAvailable) {
1330 return $previousPass;
1336 return $this->test_session->getPass();
1345 $this->
object->startWorkingTime(
1346 $this->test_session->getActiveId(),
1347 $this->test_session->getPass()
1351 $this->
help->setScreenIdComponent(
'tst');
1352 $this->
help->setScreenId(
'assessment');
1353 $this->
help->setSubScreenId(
'question');
1358 $sequence_element = $this->test_sequence->getFirstSequence();
1361 $this->test_session->setLastSequence($sequence_element ?? 0);
1362 $this->test_session->saveToDb();
1364 $question_id = $this->test_sequence->getQuestionForSequence($sequence_element ?? 0);
1365 if ($question_id ===
null && $this->test_session->isObjectiveOriented()) {
1369 if ($question_id !==
null && !$this->test_sequence->isQuestionPresented($question_id)) {
1370 $this->test_sequence->setQuestionPresented($question_id);
1371 $this->test_sequence->saveToDb();
1374 $question_worked_through = $this->questionrepository->lookupResultRecordExist(
1375 $this->test_session->getActiveId(),
1377 $this->test_session->getPass()
1380 $instant_response =
false;
1383 $s = $this->
object->getMainSettings()->getQuestionBehaviourSettings();
1384 if ($s->getInstantFeedbackGenericEnabled()
1385 || $s->getInstantFeedbackPointsEnabled()
1386 || $s->getInstantFeedbackSolutionEnabled()
1387 || $s->getInstantFeedbackSpecificEnabled()) {
1388 $instant_response =
true;
1392 if (!$this->
object->isInstantFeedbackAnswerFixationEnabled()) {
1403 $question_gui->setSequenceNumber($this->test_sequence->getPositionOfSequence($sequence_element));
1404 $question_gui->setQuestionCount($this->test_sequence->getUserQuestionCount());
1407 $header_block_builder->setHeaderMode($this->
object->getTitleOutput());
1408 $header_block_builder->setQuestionTitle($question_gui->getObject()->getTitleForHTMLOutput());
1409 $header_block_builder->setQuestionPoints($question_gui->getObject()->getPoints());
1410 $header_block_builder->setQuestionPosition($this->test_sequence->getPositionOfSequence($sequence_element));
1411 $header_block_builder->setQuestionCount($this->test_sequence->getUserQuestionCount());
1412 $header_block_builder->setQuestionPostponed($this->test_sequence->isPostponedQuestion($question_id));
1413 if ($this->test_session->isObjectiveOriented()) {
1415 $objectives_adapter->buildQuestionRelatedObjectiveList($this->test_sequence, $this->question_related_objectives_list);
1416 $this->question_related_objectives_list->loadObjectivesTitles();
1418 $header_block_builder->setQuestionRelatedObjectives(
1419 $this->question_related_objectives_list->getQuestionRelatedObjectiveTitles($question_id)
1422 $question_gui->setQuestionHeaderBlockBuilder($header_block_builder);
1424 $this->
prepareTestPage($presentation_mode, $sequence_element, $question_id);
1427 $navigation_toolbar_gui->setFinishTestButtonEnabled(
true);
1431 $this->
ctrl->setParameter($this,
'sequence', $sequence_element);
1432 $this->
ctrl->setParameter($this,
'pmode', $presentation_mode);
1435 switch ($presentation_mode) {
1437 $navigation_toolbar_gui->setDisabledStateEnabled(
false);
1441 $question_worked_through,
1445 if ($this->
ctrl->getCmd() !== self::FINISH_TEST_CMD
1446 && $this->
logger->isLoggingEnabled()
1447 && !$this->
getObject()->getAnonymity()) {
1448 $this->
logger->logParticipantInteraction(
1449 $this->
logger->getInteractionFactory()->buildParticipantInteraction(
1450 $this->
object->getRefId(),
1452 $this->
user->getId(),
1453 $this->
logger->isIPLoggingEnabled() ?
$_SERVER[
'REMOTE_ADDR'] :
'',
1454 TestParticipantInteractionTypes::QUESTION_SHOWN,
1462 if ($this->test_sequence->isQuestionOptional($question_gui->getObject()->getId())) {
1469 $question_worked_through,
1478 $navigation_toolbar_gui->build();
1482 if ($instant_response) {
1504 $question_id = $this->test_sequence->getQuestionForSequence(
1510 if ($this->
object->isForceInstantFeedbackEnabled()) {
1511 $this->
ctrl->setParameter($this,
'instresp', 1);
1513 $this->test_sequence->setQuestionChecked($question_id);
1514 $this->test_sequence->saveToDb();
1520 $this->
ctrl->setParameter($this,
'pmode',
'');
1539 $this->
ctrl->saveParameter($this,
'sequence');
1550 $this->
ctrl->saveParameter($this,
'sequence');
1560 $this->test_sequence->getQuestionForSequence($current_sequence_element)
1562 $current_question_obj->setTestId($this->
object->getId());
1564 $current_question_obj->resetUsersAnswer(
1565 $this->test_session->getActiveId(),
1566 $this->test_session->getPass()
1569 if ($this->
logger->isLoggingEnabled()
1570 && !$this->
getObject()->getAnonymity()) {
1571 $this->
logger->logParticipantInteraction(
1572 $this->
logger->getInteractionFactory()->buildParticipantInteraction(
1573 $this->
object->getRefId(),
1574 $this->test_sequence->getQuestionForSequence($current_sequence_element),
1575 $this->
user->getId(),
1576 $this->
logger->isIPLoggingEnabled() ?
$_SERVER[
'REMOTE_ADDR'] :
'',
1577 TestParticipantInteractionTypes::ANSWER_DELETED,
1583 $this->
ctrl->saveParameter($this,
'sequence');
1593 $next_sequence_element = $this->test_sequence->getNextSequence($current_sequence_element);
1596 $next_sequence_element = $this->test_sequence->getFirstSequence();
1599 if ($this->
object->isPostponingEnabled()) {
1600 $this->test_sequence->postponeSequence($current_sequence_element);
1601 $this->test_sequence->saveToDb();
1604 if ($this->
logger->isLoggingEnabled()
1605 && !$this->
getObject()->getAnonymity()) {
1606 $this->
logger->logParticipantInteraction(
1607 $this->
logger->getInteractionFactory()->buildParticipantInteraction(
1608 $this->
object->getRefId(),
1609 $this->test_sequence->getQuestionForSequence($current_sequence_element),
1610 $this->
user->getId(),
1611 $this->
logger->isIPLoggingEnabled() ?
$_SERVER[
'REMOTE_ADDR'] :
'',
1612 TestParticipantInteractionTypes::QUESTION_SKIPPED,
1618 $this->
ctrl->setParameter($this,
'sequence', $next_sequence_element);
1619 $this->
ctrl->setParameter($this,
'pmode',
'');
1629 $this->test_session->setUserId($this->
user->getId());
1631 if ($access_code !=
null && isset($access_code[$this->
object->getTestId()])) {
1632 $this->test_session->setAnonymousId($access_code[$this->
object->getTestId()]);
1637 $this->test_session->saveToDb();
1639 $active_id = $this->test_session->getActiveId();
1640 $this->
ctrl->setParameter($this,
"active_id", $active_id);
1642 $shuffle = $this->
object->getShuffleQuestions();
1643 if ($this->
object->isRandomTest()) {
1646 $this->
object->loadQuestions();
1650 $this->test_result_repository->updateTestAttemptResult(
1652 $this->test_session->getPass(),
1654 $this->
object->getId()
1658 if (!$this->test_sequence->hasSequence()) {
1659 $this->test_sequence->createNewSequence($this->
object->getQuestionCount(), $shuffle);
1660 $this->test_sequence->saveToDb();
1663 $this->test_sequence->loadFromDb();
1664 $this->test_sequence->loadQuestions();
1666 if ($this->test_session->isObjectiveOriented()) {
1669 $objectivesAdapter->notifyTestStart($this->test_session, $this->
object->getId());
1670 $objectivesAdapter->prepareTestPass($this->test_session, $this->test_sequence);
1672 $objectivesAdapter->buildQuestionRelatedObjectiveList(
1673 $this->test_sequence,
1674 $this->question_related_objectives_list
1677 if ($this->test_sequence->hasOptionalQuestions()) {
1680 $this->test_sequence->reorderOptionalQuestionsToSequenceEnd();
1681 $this->test_sequence->saveToDb();
1685 $active_time_id = $this->
object->startWorkingTime(
1686 $this->test_session->getActiveId(),
1687 $this->test_session->getPass()
1693 $sequence_element = $this->test_sequence->getFirstSequence();
1695 $this->
ctrl->setParameter($this,
'sequence', $sequence_element);
1696 $this->
ctrl->setParameter($this,
'pmode',
'');
1698 if ($this->
logger->isLoggingEnabled()
1699 && !$this->
getObject()->getAnonymity()) {
1700 $this->
logger->logParticipantInteraction(
1701 $this->
logger->getInteractionFactory()->buildParticipantInteraction(
1702 $this->
object->getRefId(),
1704 $this->
user->getId(),
1705 $this->
logger->isIPLoggingEnabled() ?
$_SERVER[
'REMOTE_ADDR'] :
'',
1706 TestParticipantInteractionTypes::TEST_RUN_STARTED,
1712 if ($this->
object->getListOfQuestionsStart()) {
1713 $this->
ctrl->setParameterByClass(static::class,
'first',
'1');
1727 and $this->
object->startingTimeReached()
1728 and !$this->
object->endingTimeReached();
1736 return $this->
object->hasNrOfTriesRestriction() && $this->
object->isNrOfTriesReached($this->test_session->getPass());
1747 $this->test_session->increasePass();
1748 $this->test_session->setLastSequence(0);
1749 $this->test_session->saveToDb();
1773 $this->tpl->addBlockFile($this->
getContentBlockName(),
"adm_content",
"tpl.il_as_tst_submit_answers_confirm.html",
"components/ILIAS/Test");
1774 $this->tpl->setCurrentBlock(
"adm_content");
1775 if ($this->
object->isTestFinished($this->test_session->getActiveId())) {
1776 $this->tpl->setCurrentBlock(
"not_submit_allowed");
1777 $this->tpl->setVariable(
"TEXT_ALREADY_SUBMITTED", $this->
lng->txt(
"tst_already_submitted"));
1778 $this->tpl->setVariable(
"BTN_OK", $this->
lng->txt(
"tst_show_answer_sheet"));
1780 $this->tpl->setCurrentBlock(
"submit_allowed");
1781 $this->tpl->setVariable(
"TEXT_CONFIRM_SUBMIT_RESULTS", $this->
lng->txt(
"tst_confirm_submit_answers"));
1782 $this->tpl->setVariable(
"BTN_OK", $this->
lng->txt(
"tst_submit_results"));
1784 $this->tpl->setVariable(
"BTN_BACK", $this->
lng->txt(
"back"));
1785 $this->tpl->setVariable(
"FORMACTION", $this->
ctrl->getFormAction($this,
"finalSubmission"));
1786 $this->tpl->parseCurrentBlock();
1791 $starting_time = $this->
object->getStartingTimeOfUser($active_id);
1797 $this->
object->getProcessingTimeInSeconds($active_id)
1800 $this->tpl->setCurrentBlock(
'enableprocessingtime');
1801 $this->tpl->setVariable(
'USER_WORKING_TIME_MESSAGE_BOX', $working_time->getMessageBox($verbose));
1802 $this->tpl->parseCurrentBlock();
1806 getdate($starting_time),
1807 $this->
ctrl->getLinkTarget($this,
'checkWorkingTime',
'',
true),
1811 $this->tpl->addOnLoadCode($working_time_js_template->get());
1823 $active_id = $this->test_session->getActiveId();
1824 echo (
string) $this->
object->getProcessingTimeInSeconds($active_id);
1830 $question_summary_data = $this->service->getQuestionSummaryData($this->test_sequence);
1834 foreach ($question_summary_data as $idx => $row) {
1835 $title = htmlspecialchars($row[
'title'], ENT_QUOTES,
null,
false);
1837 if ($row[
'description'] !==
'') {
1838 $description = htmlspecialchars($row[
'description'], ENT_QUOTES,
null,
false);
1841 if (!$row[
'disabled']) {
1842 $this->
ctrl->setParameter($this,
'pmode',
'');
1843 $this->
ctrl->setParameter($this,
'sequence', $row[
'sequence']);
1852 ($row[
'worked_through'] || $row[
'isAnswered'])
1853 && $row[
'has_authorized_answer']
1858 $questions[] = $this->ui_factory->listing()->workflow()
1859 ->step($title, $description, $action)
1860 ->withStatus($status);
1861 $active = $row[
'sequence'] == $current_sequence_element ? $idx : $active;
1864 $question_listing = $this->ui_factory->listing()->workflow()->linear(
1865 $this->
lng->txt(
'mainbar_button_label_questionlist'),
1867 )->withActive($active);
1870 $this->global_screen->tool()->context()->current()->addAdditionalData(
1881 $this->
help->setScreenIdComponent(
'tst');
1882 $this->
help->setScreenId(
'assessment');
1883 $this->
help->setSubScreenId(
'question_summary');
1885 $is_first_page = $this->testrequest->strVal(
'first') ===
'1';
1887 $this->tpl->addBlockFile(
1890 'tpl.il_as_tst_question_summary.html',
1891 'components/ILIAS/Test' 1894 $this->global_screen->tool()->context()->current()->getAdditionalData()->replace(
1899 $active_id = $this->test_session->getActiveId();
1900 $question_summary_data = $this->service->getQuestionSummaryData($this->test_sequence);
1902 $this->
ctrl->setParameter($this,
'sequence', $this->testrequest->raw(
'sequence'));
1912 $question_summary_data
1914 $this->tpl->setVariable(
'TABLE_LIST_OF_QUESTIONS', $this->ui_renderer->render($table->buildComponents($is_first_page)));
1916 if ($this->
object->getEnableProcessingTime()) {
1920 if ($this->
object->isShowExamIdInTestPassEnabled()) {
1921 $this->tpl->setCurrentBlock(
'exam_id_footer');
1923 $this->test_session->getActiveId(),
1924 $this->test_session->getPass(),
1925 $this->
object->getId()
1927 $this->tpl->setVariable(
'EXAM_ID_TXT', $this->
lng->txt(
'exam_id'));
1928 $this->tpl->parseCurrentBlock();
1942 $this->tpl->addBlockFile(
"ADM_CONTENT",
"adm_content",
"tpl.il_as_tst_correct_solution.html",
"components/ILIAS/Test");
1944 $this->tpl->setCurrentBlock(
"ContentStyle");
1946 $this->tpl->parseCurrentBlock();
1948 $this->tpl->setCurrentBlock(
"SyntaxStyle");
1950 $this->tpl->parseCurrentBlock();
1953 if ($this->
object->getShowSolutionAnswersOnly()) {
1957 $this->tpl->setCurrentBlock(
"adm_content");
1958 $solution = $this->
getCorrectSolutionOutput($this->testrequest->raw(
"evaluation"), $this->testrequest->raw(
"active_id"), $this->testrequest->raw(
"pass"));
1959 $this->tpl->setVariable(
"OUTPUT_SOLUTION", $solution);
1960 $this->tpl->setVariable(
"TEXT_BACK", $this->
lng->txt(
"back"));
1961 $this->
ctrl->saveParameter($this,
"pass");
1962 $this->
ctrl->saveParameter($this,
"active_id");
1963 $this->tpl->setVariable(
"URL_BACK", $this->
ctrl->getLinkTarget($this,
"outUserResultsOverview"));
1964 $this->tpl->parseCurrentBlock();
1978 $this->tpl->addBlockFile($this->
getContentBlockName(),
"adm_content",
"tpl.il_as_tst_finish_list_of_answers.html",
"components/ILIAS/Test");
1980 $result_array = $this->
object->getTestResult(
1989 foreach ($result_array as $question_data) {
1990 $question = $question_data[
"qid"];
1991 if (is_numeric($question)) {
1992 $this->tpl->setCurrentBlock(
"printview_question");
1993 $question_gui = $this->
object->createQuestionGUI(
"", $question);
1994 $template =
new ilTemplate(
"tpl.il_as_qpl_question_printview.html",
true,
true,
"components/ILIAS/TestQuestionPool");
1995 $template->setVariable(
"COUNTER_QUESTION", $counter .
". ");
1996 $template->setVariable(
"QUESTION_TITLE", $question_gui->getObject()->getTitleForHTMLOutput());
1998 $show_question_only = ($this->
object->getShowSolutionAnswersOnly()) ?
true :
false;
1999 $result_output = $question_gui->getSolutionOutput(
2004 $show_question_only,
2005 $this->
object->getShowSolutionFeedback()
2007 $template->setVariable(
"SOLUTION_OUTPUT", $result_output);
2008 $this->tpl->setVariable(
"QUESTION_OUTPUT", $template->get());
2009 $this->tpl->parseCurrentBlock();
2015 if ($this->
object->getShowSolutionAnswersOnly()) {
2018 if (strlen($top_data)) {
2019 $this->tpl->setCurrentBlock(
"top_data");
2020 $this->tpl->setVariable(
"TOP_DATA", $top_data);
2021 $this->tpl->parseCurrentBlock();
2024 if (strlen($bottom_data)) {
2025 $this->tpl->setCurrentBlock(
"bottom_data");
2026 $this->tpl->setVariable(
"FORMACTION", $this->
ctrl->getFormAction($this));
2027 $this->tpl->setVariable(
"BOTTOM_DATA", $bottom_data);
2028 $this->tpl->parseCurrentBlock();
2031 $this->tpl->setCurrentBlock(
"adm_content");
2032 $this->tpl->setVariable(
"TXT_ANSWER_SHEET", $this->
lng->txt(
"tst_list_of_answers"));
2035 $this->tpl->setVariable(
"USER_DETAILS", $user_data);
2036 $this->tpl->setVariable(
"SIGNATURE", $signature);
2037 $this->tpl->setVariable(
"TITLE", $this->
object->getTitle());
2038 $this->tpl->setVariable(
"TXT_TEST_PROLOG", $this->
lng->txt(
"tst_your_answers"));
2039 $invited_user = &$this->
object->getInvitedUsers($this->
user->getId());
2040 $pagetitle = $this->
object->getTitle() .
' - ' . $this->
lng->txt(
'clientip') .
2041 ': ' .
$_SERVER[
'REMOTE_ADDR'] .
' - ' .
2042 $this->
lng->txt(
'matriculation') .
': ' .
2043 $invited_user[$this->
user->getId()][
'matriculation'];
2044 $this->tpl->setVariable(
'PAGETITLE', $pagetitle);
2045 $this->tpl->parseCurrentBlock();
2055 return "ADM_CONTENT";
2057 if ($this->
object->getKioskMode()) {
2058 $this->tpl->setBodyClass(
"kiosk");
2059 $this->tpl->hideFooter();
2062 return "ADM_CONTENT";
2068 $this->
ctrl->redirectByClass(
2069 [ilRepositoryGUI::class, ilObjTestGUI::class, ilTestEvaluationGUI::class],
2070 "outUserResultsOverview" 2077 return $sequence_element == $this->test_sequence->getFirstSequence();
2082 return $sequence_element == $this->test_sequence->getLastSequence();
2087 $question_id = $this->test_sequence->getQuestionForSequence(
2104 $question_id = $this->test_sequence->getQuestionForSequence(
2115 $this->test_sequence->setQuestionChecked($question_id);
2116 $this->test_sequence->saveToDb();
2117 } elseif ($this->
object->isForceInstantFeedbackEnabled()) {
2118 $this->test_sequence->setQuestionChecked($question_id);
2119 $this->test_sequence->saveToDb();
2122 $this->
ctrl->setParameter($this,
'instresp', 1);
2137 $next_sequence_element = $this->test_sequence->getNextSequence($last_sequence_element);
2139 $question_id = $this->test_sequence->getQuestionForSequence($last_sequence_element);
2140 $is_worked_through = $this->questionrepository->lookupResultRecordExist(
2141 $this->test_session->getActiveId(),
2143 $this->test_session->getPass()
2146 if (!$is_worked_through) {
2147 if ($this->
logger->isLoggingEnabled()
2148 && !$this->
getObject()->getAnonymity()) {
2149 $this->
logger->logParticipantInteraction(
2150 $this->
logger->getInteractionFactory()->buildParticipantInteraction(
2151 $this->
object->getRefId(),
2153 $this->
user->getId(),
2154 $this->
logger->isIPLoggingEnabled() ?
$_SERVER[
'REMOTE_ADDR'] :
'',
2155 TestParticipantInteractionTypes::QUESTION_SKIPPED,
2160 if ($this->
object->isPostponingEnabled()) {
2166 $next_sequence_element = $this->test_sequence->getFirstSequence();
2169 $this->
ctrl->setParameter($this,
'sequence', $next_sequence_element);
2170 $this->
ctrl->setParameter($this,
'pmode',
'');
2179 $sequence_element = $this->test_sequence->getPreviousSequence(
2184 $sequence_element = $this->test_sequence->getLastSequence();
2187 $this->
ctrl->setParameter($this,
'sequence', $sequence_element);
2188 $this->
ctrl->setParameter($this,
'pmode',
'');
2195 $this->tpl->addBlockFile(
2198 'tpl.il_as_tst_question_summary.html',
2199 'components/ILIAS/Test' 2206 let key_event = (
event) => {
2207 if(
event.key === 13 &&
event.target.tagName.toLowerCase() ===
"a" ) {
2210 if (
event.key === 13 &&
2211 event.target.tagName.toLowerCase() !==
"textarea" &&
2212 (
event.target.tagName.toLowerCase() !==
"input" ||
event.target.type.toLowerCase() !==
"submit")) {
2213 event.preventDefault();
2217 let
form = document.getElementById(
'taForm');
2218 form.onkeyup = key_event;
2219 form.onkeydown = key_event;
2220 form.onkeypress = key_event;
2222 $this->tpl->addOnLoadCode($onload_js);
2223 $this->tpl->addBlockFile(
2226 'tpl.il_as_tst_output.html',
2227 'components/ILIAS/Test' 2239 if ($this->test_session->isPasswordChecked() ===
true) {
2243 if ($this->
ctrl->getNextClass() ===
'iltestpasswordprotectiongui') {
2247 if (!$this->password_checker->isPasswordProtectionPageRedirectRequired()) {
2248 $this->test_session->setPasswordChecked(
true);
2255 $this->
ctrl->setParameterByClass(ilTestPasswordProtectionGUI::class,
'nextCommand', $next_command);
2256 $this->
ctrl->redirectByClass(ilTestPasswordProtectionGUI::class,
'showPasswordForm');
2261 if ($this->
object->isInstantFeedbackAnswerFixationEnabled()) {
2262 return $this->test_sequence->isQuestionChecked($question_id);
2265 if ($this->
object->isFollowupQuestionAnswerFixationEnabled()) {
2277 return $this->
lng->txt(
"save_introduction");
2282 $this->ass_settings =
new ilSetting(
'assessment');
2293 $this->
object->getTestId(),
2294 $this->
object->getRefId(),
2295 $this->skills_service->profile(),
2296 $this->skills_service->personal()
2300 $skill_evaluation->setActiveId($test_session->
getActiveId());
2301 $skill_evaluation->setPass($test_session->
getPass());
2303 $skill_evaluation->setNumRequiredBookingsForSkillTriggering(
2304 $this->
object->getGlobalSettings()->getSkillTriggeringNumberOfAnswers()
2308 $question_list->load();
2309 $skill_evaluation->init($question_list);
2310 $skill_evaluation->evaluate(
2311 $this->
object->getTestResult(
2318 $skill_evaluation->handleSkillTriggering();
2325 $confirmation->setFormAction($this->
ctrl->getFormAction($this));
2326 $confirmation->setCancelCmd(
'cancelAnswerOptionalQuestions');
2327 $confirmation->setConfirmCmd(
'confirmAnswerOptionalQuestions');
2329 $confirmation->build($this->
object->isFixedTest());
2336 $this->test_sequence->setAnsweringOptionalQuestionsConfirmed(
true);
2337 $this->test_sequence->saveToDb();
2339 $this->
ctrl->setParameter($this,
'activecommand',
'gotoquestion');
2340 $this->
ctrl->redirect($this,
'redirectQuestion');
2345 if ($this->
object->getListOfQuestions()) {
2346 $this->
ctrl->setParameter($this,
'activecommand',
'summary');
2348 $this->
ctrl->setParameter($this,
'activecommand',
'previous');
2351 $this->
ctrl->redirect($this,
'redirectQuestion');
2365 $navigation_toolbar->setSuspendTestButtonEnabled($this->
object->getShowCancel());
2366 $navigation_toolbar->setUserPassOverviewEnabled($this->
object->getUsrPassOverviewEnabled());
2368 return $navigation_toolbar;
2383 if ($this->
object->getShowMarker()) {
2387 if (count($solved_array) > 0) {
2388 $solved = array_pop($solved_array);
2389 $solved = $solved[
"solved"];
2394 $navigationGUI->setQuestionMarked(
true);
2397 $navigationGUI->setQuestionMarked(
false);
2402 return $navigationGUI;
2416 if ($this->
object->getSpecificAnswerFeedback()
2417 || $this->
object->getGenericAnswerFeedback()
2418 || $this->
object->getAnswerFeedbackPoints()
2419 || $this->
object->getInstantFeedbackSolution()) {
2420 $navigation_gui->setAnswerFreezingEnabled($this->
object->isInstantFeedbackAnswerFixationEnabled());
2422 if ($this->
object->isForceInstantFeedbackEnabled()) {
2423 $navigation_gui->setForceInstantResponseEnabled(
true);
2430 if ($this->
object->getShowMarker()) {
2434 if (count($solved_array) > 0) {
2435 $solved = array_pop($solved_array);
2436 $solved = $solved[
'solved'];
2439 if ($solved === 1) {
2441 $navigation_gui->setQuestionMarked(
true);
2444 $navigation_gui->setQuestionMarked(
false);
2447 return $navigation_gui;
2452 if (!$this->
object->getListOfQuestionsEnd()) {
2464 $answer_feedback_enabled = $this->
object->getSpecificAnswerFeedback();
2467 $this->test_session->getActiveId(), #active_id
2468 $this->test_session->getPass(), #pass
2469 false, #graphical_output
2470 false, #result_output
2471 true, #show_question_only
2472 $answer_feedback_enabled, #show_feedback
2473 false, #show_correct_solution
2474 false, #show_manual_scoring
2475 true #show_question_text
2481 $this->test_session->getActiveId(),
2485 $tpl =
new ilTemplate(
'tpl.tst_player_response_modal.html',
true,
true,
'components/ILIAS/Test');
2491 $this->tpl = $saved_tpl;
2499 $modal = $this->ui_factory->modal()->roundtrip(
2500 $this->
lng->txt(
'tst_instant_feedback'),
2501 $this->ui_factory->legacy()->content($tpl->
get()),
2503 )->withActionButtons([
2504 $this->ui_factory->button()->standard($this->
lng->txt(
'proceed'), $nav_url)
2507 return $this->ui_renderer->render([
2508 $modal->withOnLoad($modal->getShowSignal())
2518 $response_available =
false;
2519 $jump_to_response =
false;
2523 if ($this->
object->getInstantFeedbackSolution()) {
2528 $this->test_session->getActiveId(), #active_id
2529 $this->test_session->getPass(), #pass
2530 false, #graphical_output
2531 $show_question_inline_score, #result_output
2532 true, #show_question_only
2533 false, #show_feedback
2534 true, #show_correct_solution
2535 false, #show_manual_scoring
2536 false #show_question_text
2538 $solutionoutput = str_replace(
'<h1 class="ilc_page_title_PageTitle"></h1>',
'', $solutionoutput);
2540 $response_available =
true;
2541 $jump_to_response =
true;
2544 $reachedPoints = $question_gui->
getObject()->getAdjustedReachedPoints(
2545 $this->test_session->getActiveId(),
2550 $maxPoints = $question_gui->
getObject()->getMaximumPoints();
2552 $solutionCorrect = ($reachedPoints == $maxPoints);
2556 if ($this->
object->getAnswerFeedbackPoints()) {
2558 $response_available =
true;
2559 $jump_to_response =
true;
2564 if ($this->
object->getGenericAnswerFeedback()) {
2566 $response_available =
true;
2567 $jump_to_response =
true;
2573 if ($this->
object->getSpecificAnswerFeedback()) {
2576 $jump_to_response =
false;
2578 $response_available =
true;
2579 $jump_to_response =
true;
2584 if (!$response_available) {
2595 if ($withFocusAnchor) {
2596 $this->tpl->setCurrentBlock(
'inst_resp_id');
2597 $this->tpl->setVariable(
'INSTANT_RESPONSE_FOCUS_ID',
'focus');
2598 $this->tpl->parseCurrentBlock();
2601 $this->tpl->setCurrentBlock(
'instant_response_header');
2602 $this->tpl->setVariable(
'INSTANT_RESPONSE_HEADER', $this->
lng->txt(
'tst_feedback'));
2603 $this->tpl->parseCurrentBlock();
2608 $this->tpl->setCurrentBlock(
'instant_response_message');
2609 $this->tpl->setVariable(
'INSTANT_RESPONSE_MESSAGE', $a_message);
2610 $this->tpl->parseCurrentBlock();
2620 return $this->test_session->getLastSequence();
2625 if ($this->testrequest->isset(
'sequence')) {
2626 return $this->testrequest->int(
'sequence');
2634 if ($this->testrequest->isset(
'pmode')) {
2635 return $this->testrequest->raw(
'pmode');
2643 return $this->testrequest->isInstanceResponseRequested();
2649 if ($this->testrequest->isset(
'nextcmd')) {
2650 $nextcmd = $this->testrequest->strVal(
'nextcmd');
2653 return $nextcmd !==
'' ? $nextcmd :
null;
2658 return $this->testrequest->int(
'nextseq');
2663 $navigation_url = $this->testrequest->strVal(
'test_player_navigation_url');
2664 if ($navigation_url !==
'') {
2665 $navigation_url_parts = parse_url($navigation_url);
2668 if (!isset($navigation_url_parts[
'host']) || ($ilias_url_parts[
'host'] === $navigation_url_parts[
'host'])) {
2669 return $navigation_url;
2677 return !empty($this->testrequest->raw(
'test_answer_changed'));
2682 $this->
ctrl->setParameter($this,
'test_answer_changed', $changed ?
'1' :
'0');
2697 if ($this->testrequest->retrieveBoolFromPost(
'save_on_navigation_prevent_confirmation')) {
2701 if ($this->testrequest->retrieveBoolFromPost(self::FOLLOWUP_QST_LOCKS_PREVENT_CONFIRMATION_PARAM)) {
2702 ilSession::set(self::FOLLOWUP_QST_LOCKS_PREVENT_CONFIRMATION_PARAM,
true);
2710 if (!$from_cache || !isset($this->cached_question_guis[$question_id])) {
2711 $question_gui = $this->
object->createQuestionGUI(
"", $question_id);
2712 $question_gui->setTargetGui($this);
2714 $question = $question_gui->getObject();
2715 $question->setShuffler($this->shuffler->getAnswerShuffleFor(
2717 $this->test_session->getActiveId(),
2718 $this->test_session->getPass()
2720 $question_gui->setObject($question);
2721 $question_gui->populateJavascriptFilesRequiredForWorkForm(
$tpl);
2727 $this->cached_question_guis[$question_id] = $question_gui;
2730 return $this->cached_question_guis[$question_id];
2735 if ($from_cache && isset($this->cached_question_objects[$question_id])) {
2736 return $this->cached_question_objects[$question_id];
2739 $ass_settings =
new ilSetting(
'assessment');
2742 $process_locker_factory->setQuestionId($question->getId());
2743 $process_locker_factory->setUserId($this->
user->getId());
2744 $question->setProcessLocker($process_locker_factory->getLocker());
2748 $this->cached_question_objects[$question_id] = $question;
2755 $this->
object->isPreviousSolutionReuseEnabled($this->test_session->getActiveId())
2763 .
"active={$this->test_session->getActiveId()} " 2764 .
"qId=$question_id seq=$sequence_element " 2765 . serialize($this->test_sequence)
2768 $this->
ctrl->setParameter($this,
'sequence', $this->test_sequence->getFirstSequence());
2774 if ($this->
object->getKioskMode()) {
2775 $this->tpl->addBlockfile($this->
getContentBlockName(),
'content',
"tpl.il_as_tst_kiosk_mode_content.html",
"components/ILIAS/Test");
2776 $this->tpl->setContent($content_html);
2789 if ($this->
object->isFollowupQuestionAnswerFixationEnabled()) {
2799 $modal = $this->ui_factory->modal()->interruptive(
2800 $this->
lng->txt(
'discard_answer'),
2801 $this->
lng->txt(
'discard_answer_confirmation'),
2803 )->withActionButtonLabel($this->
lng->txt(
'discard_answer'));
2805 $this->tpl->setCurrentBlock(
'discard_solution_modal');
2806 $this->tpl->setVariable(
'DISCARD_SOLUTION_MODAL', $this->ui_renderer->render($modal));
2807 $this->tpl->parseCurrentBlock();
2808 return $modal->getShowSignal();
2813 $modal = $this->ui_factory->modal()->interruptive(
2814 $this->
lng->txt(
'tst_nav_next_locks_empty_answer_header'),
2815 $this->
lng->txt(
'tst_nav_next_locks_empty_answer_confirm'),
2816 'javascript:il.TestPlayerQuestionEditControl.confirmNextLocksUnchanged()' 2817 )->withActionButtonLabel($this->
lng->txt(
'tst_proceed'));
2819 $this->tpl->setCurrentBlock(
'next_locks_unchanged_modal');
2820 $this->tpl->setVariable(
'NEXT_LOCKS_UNCHANGED_MODAL', $this->ui_renderer->render($modal));
2821 $this->tpl->parseCurrentBlock();
2822 return $modal->getShowSignal();
2827 $empty_signal = new \ILIAS\UI\Implementation\Component\Signal(
'');
2829 return $empty_signal;
2832 $modal_message = $this->ui_factory->messageBox()->confirmation(
2833 $this->
lng->txt(
'tst_nav_next_locks_current_answer_confirm')
2835 $modal_checkbox = $this->ui_factory->input()->field()->checkbox(
2836 $this->
lng->txt(
'tst_dont_show_msg_again_in_current_session')
2837 )->withDedicatedName(self::FOLLOWUP_QST_LOCKS_PREVENT_CONFIRMATION_PARAM);
2839 $modal = $this->ui_factory->modal()->roundtrip(
2840 $this->
lng->txt(
'tst_nav_next_locks_current_answer_header'),
2842 [ $modal_checkbox ],
2843 'javascript:il.TestPlayerQuestionEditControl.confirmNextLocksChanged()' 2844 )->withSubmitLabel($this->
lng->txt(
'tst_proceed'));
2846 $this->tpl->setCurrentBlock(
'next_locks_changed_modal');
2847 $this->tpl->setVariable(
'NEXT_LOCKS_CHANGED_MODAL', $this->ui_renderer->render($modal));
2848 $this->tpl->parseCurrentBlock();
2849 return $modal->getShowSignal();
2856 ilSession::set(self::FOLLOWUP_QST_LOCKS_PREVENT_CONFIRMATION_PARAM,
true);
2865 return ilSession::get(self::FOLLOWUP_QST_LOCKS_PREVENT_CONFIRMATION_PARAM);
2871 $state = $question_gui->
getObject()->lookupForExistingSolutions($this->test_session->getActiveId(), $this->test_session->getPass());
2872 $config[
'isAnswered'] = $state[
'authorized'];
2877 $config[
'autosaveUrl'] =
'';
2878 $config[
'autosaveInterval'] = 0;
2881 $config[
'autosaveInterval'] = $this->
object->getMainSettings()->getQuestionBehaviourSettings()->getAutosaveInterval();
2884 $question_config = $question_gui->
getObject()->getTestPresentationConfig();
2886 $config[
'withFormChangeDetection'] = $question_config->isFormChangeDetectionEnabled();
2889 $config[
'withBackgroundChangeDetection'] = $question_config->isBackgroundChangeDetectionEnabled();
2893 $config[
'forcedInstantFeedback'] = $this->
object->isForceInstantFeedbackEnabled();
2895 $config[
'nextQuestionLocks'] = $this->
object->isFollowupQuestionAnswerFixationEnabled();
2896 $config[
'autosaveFailureMessage'] = $this->
lng->txt(
'autosave_failed');
2900 $config[
'preventConfirmationParam'] = self::FOLLOWUP_QST_LOCKS_PREVENT_CONFIRMATION_PARAM;
2902 $this->tpl->addJavascript(
'assets/js/ilTestPlayerQuestionEditControl.js');
2903 $this->tpl->addOnLoadCode(
'il.TestPlayerQuestionEditControl.init(' . json_encode($config) .
')');
2909 return self::PRESENTATION_MODE_EDIT;
2917 $forced_feeback_navigation_url =
ilSession::get(
'forced_feedback_navigation_url');
2918 $forced_feeback_navigation_url[$this->test_session->getActiveId()] = $forced_feedback_nav_url;
2919 ilSession::set(
'forced_feedback_navigation_url', $forced_feeback_navigation_url);
2927 $forced_feedback_navigation_url =
ilSession::get(
'forced_feedback_navigation_url');
2928 if (!isset($forced_feedback_navigation_url[$this->test_session->getActiveId()])) {
2932 return $forced_feedback_navigation_url[$this->test_session->getActiveId()];
2942 $forced_feedback_navigation_url =
ilSession::get(
'forced_feedback_navigation_url');
2943 if (isset($forced_feedback_navigation_url[$this->test_session->getActiveId()])) {
2944 unset($forced_feedback_navigation_url[$this->test_session->getActiveId()]);
2945 ilSession::set(
'forced_feedback_navigation_url', $forced_feedback_navigation_url);
2963 if ($sequence_element ===
false) {
2967 if ($sequence_element < 1) {
2971 if (!$this->test_sequence->getPositionOfSequence($sequence_element)) {
2980 if ($this->
object->isForceInstantFeedbackEnabled()) {
2986 $this->test_sequence->getQuestionForSequence(
2995 $next_sequence_element = $this->test_sequence->getFirstSequence();
2998 $this->test_session->setLastSequence($next_sequence_element ?? 0);
2999 $this->test_session->saveToDb();
3001 $this->
ctrl->setParameter($this,
'sequence', $next_sequence_element);
3002 $this->
ctrl->setParameter($this,
'pmode',
'');
3011 $this->test_sequence->postponeQuestion($question_id);
3012 $this->test_sequence->saveToDb();
3017 $testObj =
new ilObjTest($this->ref_id,
true);
3019 $participants = $testObj->getActiveParticipantList();
3020 $participant = $participants->getParticipantByActiveId($this->testrequest->getActiveId());
3021 if ($participant && $participant->hasUnfinishedPasses()) {
3024 $this->tpl->setOnScreenMessage(
'failure', $this->
lng->txt(
'tst_current_run_no_longer_valid'),
true);
3025 if ($with_redirect) {
3026 $this->
ctrl->redirectByClass([
3027 ilRepositoryGUI::class,
3028 ilObjTestGUI::class,
3029 TestScreenGUI::class
3036 if ($this->test_session->getActiveId() > 0) {
3037 if ($this->test_sequence->hasRandomQuestionsForPass($this->test_session->getActiveId(), $this->test_session->getPass()) > 0) {
3039 __METHOD__ .
' Random Questions allready exists for user ' .
3040 $this->
user->getId() .
' in test ' . $this->
object->getTestId()
3046 $this->
logger->info(__METHOD__ .
' ' . sprintf(
3047 $this->
lng->txt(
"error_random_question_generation"),
3048 $this->
user->getId(),
3049 $this->
object->getTestId()
3065 $this->component_repository,
3067 $this->questionrepository
3069 $questionSetConfig->loadFromDb();
3074 $sourcePoolDefinitionList->loadDefinitions();
3076 $this->process_locker->executeRandomPassBuildOperation(
function () use ($questionSetConfig, $sourcePoolDefinitionList) {
3086 $sourcePoolDefinitionList,
3087 $stagingPoolQuestionList
3090 $questionSetBuilder->performBuild($this->test_session);
3092 }, $sourcePoolDefinitionList->hasTaxonomyFilters());
3097 $ass_settings =
new ilSetting(
'assessment');
3100 $userSolutionAdopter->setUserId($this->
user->getId());
3101 $userSolutionAdopter->setActiveId($this->test_session->getActiveId());
3102 $userSolutionAdopter->setTargetPass($this->test_sequence->getPass());
3103 $userSolutionAdopter->setQuestionIds($this->test_sequence->getOptionalQuestions());
3105 $userSolutionAdopter->perform();
3110 $this->tpl->setOnScreenMessage(
'failure', sprintf($this->
lng->txt(
'tst_objective_oriented_test_pass_without_questions'), $this->
object->getTitle()),
true);
3111 $this->
ctrl->redirectByClass(ilObjTestGUI::class);
3116 $is_next_primary =
true;
3118 if ($this->
object->isForceInstantFeedbackEnabled()) {
3119 $is_next_primary =
false;
3122 $questions_missing_result = $this->questionrepository->getQuestionsMissingResultRecord(
3123 $this->test_session->getActiveId(),
3124 $this->test_session->getPass(),
3125 $this->test_sequence->getOrderedSequenceQuestions()
3128 if ($questions_missing_result === []) {
3133 if (count($questions_missing_result) === 1
3134 && $current_question_id === current($questions_missing_result)) {
3139 return $is_next_primary;
3144 $title_content = $this->ui_factory->listing()->property();
3146 if ($this->
object->getShowKioskModeParticipant()) {
3147 $pax_name_label = $this->
lng->txt(
"conf_user_name");
3151 $pax_name_value =
"<span class='il-test-kiosk-head__participant-name'>" 3152 . $this->
user->getFullname() .
"</span>";
3153 $title_content = $title_content->withProperty($pax_name_label, $pax_name_value,
false);
3156 if ($this->
object->isShowExamIdInTestPassEnabled()) {
3157 $exam_id_label = $this->
lng->txt(
"exam_id_label");
3159 $this->test_session->getActiveId(),
3160 $this->test_session->getPass(),
3161 $this->
object->getId()
3163 $title_content = $title_content->withProperty($exam_id_label, $exam_id_value);
3166 if ($this->
object->getShowKioskModeTitle()) {
3167 $test_title_label = $this->
lng->txt(
"test");
3168 $test_title_value = $this->
object->getTitle();
3169 $title_content = $title_content->withProperty($test_title_label, $test_title_value,
false);
3172 return $this->ui_renderer->render($title_content);
outQuestionSummaryCmd()
Output of a summary of all test questions for test participants.
populateFeedbackBlockMessage(string $a_message)
showSideList($current_sequence_element)
isFirstQuestionInSequence($sequence_element)
getQuestionInstance(int $question_id, bool $from_cache=true)
populateSyntaxStyleBlock()
buildEditableStateQuestionNavigationGUI($question_id)
redirectAfterQuestionListCmd()
static get(string $a_var)
bool $max_processing_time_reached
populateNextButtons($primary_next)
redirectAfterAutosaveCmd()
Redirect the user after an automatic save when the time limit is reached.
performTearsAndAngerBrokenConfessionChecks()
static getStyleSheetLocation(string $mode="output", string $a_css_name="")
get full style sheet file name (path inclusive) of current user
buildNextButtonInstance($primaryNext)
submitIntermediateSolutionCmd()
startPlayerCmd()
Start a test for the first time.
prepareWorkingTimeJsTemplate(ilObjTest $object, array $date, string $check_url, string $redirect_url)
populateNextLocksUnchangedModal()
getOnLoadCodeForNavigationButtons(string $target, string $cmd)
const AFTER_TEST_PASS_FINISHED
populateDiscardSolutionModal()
removeIntermediateSolution()
Class ilTestPassFinishTasks.
showAnswerOptionalQuestionsConfirmation()
populateLowerNextButtonBlock($primary_next)
sendNewPassFinishedNotificationEmailIfActivated(int $active_id, int $pass)
getAdditionalUsrDataHtmlAndPopulateWindowTitle($testSession, $active_id, $overwrite_anonymity=false)
Returns the user data for a test results output.
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test.
ilTestSequence $test_sequence
showQuestionViewable(assQuestionGUI $question_gui, string $form_action, bool $is_question_worked_through, bool $instant_response)
populateSpecificFeedbackBlock(assQuestionGUI $question_gui)
populateContentStyleBlock()
handleQuestionActionCmd()
isShowingPostponeStatusReguired(int $question_id)
setAnswerChangedParameter(bool $changed=true)
get(string $part=ilGlobalTemplateInterface::DEFAULT_BLOCK)
populateInstantResponseModal(assQuestionGUI $question_gui, $nav_url)
const FOLLOWUP_QST_LOCKS_PREVENT_CONFIRMATION_PARAM
getAccessCodeFromSession()
markQuestionAndSaveIntermediateCmd()
setAnonymousIdCmd()
Sets a session variable with the test access code for an anonymous test user.
updateLearningProgressOnTestStart()
const SHOW_FINAL_STATMENT
getPresentationModeParameter()
autosaveCmd()
Automatically save a user answer while working on the test (called repeatedly by asynchronous posts i...
outUserResultsOverviewCmd()
getCorrectSolutionOutput($question_id, $active_id, $pass, ?ilTestQuestionRelatedObjectivesList $objectives_list=null)
Returns an output of the solution to an answer compared to the correct solution.
populateTestNavigationToolbar(ilTestNavigationToolbarGUI $toolbar_gui)
populatePreviousButtons()
getObjectiveOrientedContainer()
adoptUserSolutionsFromPreviousPass()
populateUpperPreviousButtonBlock()
confirmSubmitAnswers()
confirm submit results if confirm then results are submitted and the screen will be redirected to the...
updateWorkingTime()
updates working time and stores state saveresult to see if question has to be stored or not ...
saveTagsCmd()
Save tags for tagging gui.
ilGlobalTemplateInterface ilTemplate $tpl
sk 2023-08-01: We need this union type, even if it is wrong! To change this
populateHelperGuiContent($helperGui)
const AUTO_SAVE_ON_TIME_LIMIT
getNextCommandParameter()
buildReadOnlyStateQuestionNavigationGUI($question_id)
doesAccessCodeInSessionExists()
ilTestQuestionRelatedObjectivesList $question_related_objectives_list
static getInstance(ilDBInterface $db, ilLanguage $lng, TestLogger $logger, ilObjTest $testOBJ, ilTestRandomQuestionSetConfig $questionSetConfig, ilTestRandomQuestionSetSourcePoolDefinitionList $sourcePoolDefinitionList, ilTestRandomQuestionSetStagingPoolQuestionList $stagingPoolQuestionList)
max_processing_time_reached()
Outputs a message when the maximum processing time is reached.
getResultsSignature()
Returns HTML code for a signature field.
cancelAnswerOptionalQuestionsCmd()
isFollowUpQuestionLocksConfirmationPrevented()
persistWorkingState(int $active_id, $pass, bool $authorized=true)
persists the working state for current testactive and testpass
const CSS_CLASS_FEEDBACK_CORRECT
handleUserSettings()
Handles some form parameters on starting and resuming a test.
setVariable(string $variable, $value='')
Sets the given variable to the given value.
afterTestPassFinishedCmd()
getContentBlockName()
Returns the name of the current content block (depends on the kiosk mode setting) ...
populateQuestionOptionalMessage()
handleCheckTestPassValid(bool $with_redirect=false)
checkWorkingTimeCmd()
This is asynchronously called by tpl.workingtime.js to check for changes in the user's processing tim...
Base Exception for all Exceptions relating to Modules/Test.
populateLowerPreviousButtonBlock()
InterruptiveModal $finish_test_modal
setFollowUpQuestionLocksConfirmationPrevented()
getId()
Get the ID of this signal.
ilTestSession $test_session
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
unregisterForcedFeedbackNavUrl()
isNrOfTriesReached()
nr of tries exceeded
ilTestSequenceFactory $test_sequence_factory
const LOCKS_UNCHANGED_MODAL
checkTestSessionUser(ilTestSession $test_session)
showListOfAnswers($active_id, $pass=null, $top_data="", $bottom_data="")
Creates an output of the list of answers for a test participant during the test (only the actual pass...
static instantiateQuestion(int $question_id)
populateQuestionNavigation($sequence_element, $primary_next)
static getInstance(ilTestSession $a_test_session)
markQuestionCmd()
Set a question solved.
handleIntermediateSubmit()
isForcedFeedbackNavUrlRegistered()
static http()
Fetches the global http state from ILIAS.
getQuestionFeedbackModalHtml(ilTemplate $tpl, string $nav_url)
isValidSequenceElement($sequence_element)
getInstantResponseParameter()
buildTestPassQuestionList()
populateGenericFeedbackBlock(assQuestionGUI $question_gui, $solutionCorrect)
getRegisteredForcedFeedbackNavUrl()
outQuestionForTest(string $formaction, int $active_id, ?int $pass, bool $is_question_postponed=false, array|bool $user_post_solutions=false, bool $show_specific_inline_feedback=false)
readonly ilDBInterface $db
answerToParticipantInteraction(AdditionalInformationGenerator $additional_info, int $test_ref_id, int $active_id, int $pass, string $source_ip, TestParticipantInteractionTypes $interaction_type)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
array $cached_question_guis
const TEST_PLAYER_QUESTIONLIST
outCorrectSolution()
Creates an output of the solution of an answer compared to the correct solution.
static initjQuery(?ilGlobalTemplateInterface $a_tpl=null)
inits and adds the jQuery JS-File to the global or a passed template
ilTestPasswordChecker $password_checker
getIntroductionPageButtonLabel()
handleSkillTriggering(ilTestSession $test_session)
array $cached_question_objects
const PRESENTATION_MODE_EDIT
saveNavigationPreventConfirmation()
endingTimeReached()
handle endingTimeReached
buildPreviousButtonInstance()
prepareTestPage($presentationMode, $sequenceElement, $question_id)
const ACCESS_CODE_CONFIRMED
handleQuestionPostponing(int $question_id)
static _getSolvedQuestions($active_id, $question_fi=null)
get solved questions
const REDIRECT_ON_TIME_LIMIT
ensureExistingTestSession(ilTestSession $test_session)
performTestPassFinishedTasks(StatusOfAttempt $status_of_attempt)
outProcessingTime(int $active_id, bool $verbose)
const SHOW_INSTANT_RESPONSE
const TEST_PLAYER_KIOSK_MODE_ENABLED
static getSyntaxStylePath()
const CSS_CLASS_FEEDBACK_WRONG
generateRandomTestPassForActiveUser()
getAnswerChangedParameter()
getSequenceElementParameter()
populateNextLocksChangedModal()
detectChangesCmd()
Detect changes sent in the background to the server This is called by ajax from ilTestPlayerQuestionE...
const PRESENTATION_MODE_VIEW
submitSolutionAndNextCmd()
const LOCKS_CHANGED_MODAL
static getContentStylePath(int $a_style_id, bool $add_random=true, bool $add_token=true)
get content style path static (to avoid full reading)
const SUBMIT_INTERMEDIATE_SOLUTION
const PRESENTATION_CONTEXT_TEST
const REDIRECT_AFTER_QUESTION_LIST
initProcessLocker($activeId)
TestParticipantInteractionTypes
static redirect(string $a_script)
unmarkQuestionCmd()
Set a question unsolved.
populateQuestionEditControl(assQuestionGUI $question_gui)
isOptionalQuestionAnsweringConfirmationRequired(int $sequence_key)
const TEST_PLAYER_VIEW_TITLE
handlePrimaryButton(ilTestNavigationToolbarGUI $navigation_toolbar_gui, int $current_question_id)
handlePasswordProtectionRedirect()
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
const UNMARK_QUESTION_SAVE
populateInstantResponseBlocks(assQuestionGUI $question_gui, $authorizedSolution)
handleTearsAndAngerNoObjectiveOrientedQuestion()
form( $class_path, string $cmd, string $submit_caption="")
setAnonymousId(string $anonymous_id)
isLastQuestionInSequence($sequence_element)
getSpecificFeedbackOutput(array $userSolution)
Returns the answer specific feedback for the question.
populateUpperNextButtonBlock($primaryNext)
isTestAccessible()
test accessible returns true if the user can perform the test
const DISPLAY_ACCESS_CODE
outQuestionPage($a_temp_var, $a_postponed=false, $active_id="", $html="", $inlineFeedbackEnabled=false)
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
__construct(Container $dic, ilPlugin $plugin)
const TEST_PLAYER_SHORT_TITLE
populateMessageContent(string $content_html)
getNextSequenceParameter()
determineInlineScoreDisplay()
getTestPresentationConfig()
getNavigationUrlParameter()
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false, ?ilObjUser $user=null,)
getQuestionHeaderBlockBuilder()
static buildExamId($active_id, $pass, $test_obj_id=null)
registerForcedFeedbackNavUrl(string $forced_feedback_nav_url)
isParticipantsAnswerFixed($question_id)
const FIXED_SHUFFLER_SEED_MIN_LENGTH
__construct(ilObjTest $object)
getQuestionsDefaultPresentationMode()
unmarkQuestionAndSaveIntermediateCmd()
handleTearsAndAngerQuestionIsNull(int $question_id, $sequence_element)
Service GUI class for tests.
ilTestProcessLocker $process_locker
save(assQuestion $question_obj, bool $authorized)
showQuestionEditable(assQuestionGUI $question_gui, string $form_action, bool $is_question_worked_through, bool $instant_response)
initTestCmd()
Start a test for the first time after a redirect.
isMaxProcessingTimeReached()
getCurrentSequenceElement()
determineSolutionPassIndex(assQuestionGUI $question_gui)
confirmAnswerOptionalQuestionsCmd()
static clear(string $a_var)
bool $ending_time_reached
populateFeedbackBlockHeader($withFocusAnchor)
saveQuestionSolution(bool $authorized=true, bool $force=false)
getSolutionOutput(int $active_id, ?int $pass=null, bool $graphical_output=false, bool $result_output=false, bool $show_question_only=true, bool $show_feedback=false, bool $show_correct_solution=false, bool $show_manual_scoring=false, bool $show_question_text=true, bool $show_inline_feedback=true)
getTestNavigationToolbarGUI()
static set(string $a_var, $a_val)
Set a value.
initTestQuestionConfig(assQuestion $question_obj)
getQuestionGuiInstance(int $question_id, bool $from_cache=true)
populateSolutionBlock($solutionoutput)
static isTestExecutionCommand($cmd)
populateScoreBlock($reachedPoints, $maxPoints)
static _updateStatus(int $a_obj_id, int $a_usr_id, ?object $a_obj=null, bool $a_percentage=false, bool $a_force_raise=false)
setNavigationGUI(?ilTestQuestionNavigationGUI $navigationGUI)
autosaveOnTimeLimitCmd()
Automatically save a user answer when the limited duration of a test run is reached (called by synchr...
static lookupExamId($active_id, $pass)
getGenericFeedbackOutput(int $active_id, ?int $pass)