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 $ret = $this->
ctrl->forwardCommand($page_gui);
158 case 'iltestsubmissionreviewgui':
164 $ret = $this->
ctrl->forwardCommand($gui);
167 case 'ilassquestionhintrequestgui':
170 $question_gui = $this->
object->createQuestionGUI(
172 $this->test_sequence->getQuestionForSequence($this->getCurrentSequenceElement())
176 $question_gui->getObject()->getId(),
177 $this->test_session->getActiveId(),
178 $this->test_session->getPass()
185 $questionHintTracking,
196 $ret = $this->
ctrl->forwardCommand($gui);
200 case 'ilassspecfeedbackpagegui':
201 case 'ilassgenfeedbackpagegui':
202 $id = $this->testrequest->int(
'pg_id');
203 if ($this->
ctrl->getCmd() !==
'displayMediaFullscreen' 209 $next_class ===
'ilassgenfeedbackpagegui' ?
'qfbg' :
'qfbs',
211 ))->displayMediaFullscreen();
214 case 'iltestpasswordprotectiongui':
222 $this->password_checker,
226 $ret = $this->
ctrl->forwardCommand($gui);
234 if ($cmd ===
'outQuestionSummary' 235 || $cmd ===
'submitSolution') {
239 if ($cmd ===
'showQuestion') {
241 $testPassesSelector->setActiveId($this->test_session->getActiveId());
242 $testPassesSelector->setLastFinishedPass($this->test_session->getLastFinishedPass());
244 if (!$testPassesSelector->openPassExists()) {
245 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'tst_pass_finished'),
true);
246 $this->
ctrl->redirectByClass([ilRepositoryGUI::class, ilObjTestGUI::class, TestScreenGUI::class]);
251 $ret = $this->$cmd();
262 if (!$this->rbac_system->checkAccess(
'read', $this->object->getRefId())) {
263 return $this->
lng->txt(
'cannot_execute_test');
266 $participant_access = (
new ilTestAccess($this->
object->getRefId()))->isParticipantAllowed(
270 if ($participant_access !== ParticipantAccess::ALLOWED) {
271 return $participant_access->getAccessForbiddenMessage($this->
lng);
279 $executable = $this->
object->isExecutable($this->test_session, $this->test_session->getUserId());
281 if (!$executable[
'executable']) {
282 $this->tpl->setOnScreenMessage(
'info', $executable[
'errormessage'],
true);
283 $this->
ctrl->redirectByClass([ilRepositoryGUI::class, ilObjTestGUI::class, TestScreenGUI::class]);
290 throw new ilTestException(
'active id given does not relate to current user!');
317 $this->process_locker = $process_lockerFactory->withContextId((
int) $activeId)->getLocker();
329 $tagging_gui->setObject($this->
object->getId(), $this->
object->getType());
330 $tagging_gui->saveInput();
331 $this->
ctrl->redirectByClass([ilRepositoryGUI::class, ilObjTestGUI::class, ilInfoScreenGUI::class]);
340 $this->
object->updateWorkingTime(
ilSession::get(
"active_time_id"));
345 $this->
object->startWorkingTime(
346 $this->test_session->getActiveId(),
347 $this->test_session->getPass()
357 $this->test_session->getActiveId(),
358 $this->test_session->getPass()
363 bool $authorized =
true,
368 $formtimestamp = $this->testrequest->int(
'formtimestamp');
388 if ($question_obj === null) {
393 $saved = $this->
save($question_obj, $authorized);
400 $this->
ctrl->setParameter($this,
'save_error',
'1');
401 ilSession::set(
'previouspost', $this->testrequest->getParsedBody());
409 $q_id = $this->test_sequence->getQuestionForSequence($this->testrequest->int(
'sequence'));
416 if ($q_id === null) {
425 $active_id = $this->test_session->getActiveId();
435 if ($authorized && $this->test_session->isObjectiveOriented()) {
437 $objectivesAdapter->updateQuestionResult($this->test_session, $question_obj);
440 if ($authorized && $this->
object->isSkillServiceToBeConsidered()) {
444 if ($authorized && $this->
logger->isLoggingEnabled()
447 $this->
logger->getAdditionalInformationGenerator(),
451 $this->
logger->isIPLoggingEnabled() ?
$_SERVER[
'REMOTE_ADDR'] :
'',
452 TestParticipantInteractionTypes::ANSWER_SUBMITTED
454 $this->
logger->logParticipantInteraction($interaction);
466 $this->
ctrl->redirectByClass(TestScreenGUI::class, TestScreenGUI::DEFAULT_CMD);
471 $active_id = $this->test_session->getActiveId();
472 $starting_time = $this->
object->getStartingTimeOfUser($active_id);
473 if ($starting_time ===
false) {
476 return $this->
object->isMaxProcessingTimeReached($starting_time, $active_id);
482 $show_question_inline_score =
false;
483 if ($this->
object->getAnswerFeedbackPoints()) {
484 $show_question_inline_score =
true;
485 return $show_question_inline_score;
487 return $show_question_inline_score;
492 $this->tpl->setCurrentBlock(
'test_nav_toolbar');
493 $this->tpl->setVariable(
'TEST_NAV_TOOLBAR', $toolbar_gui->getHTML());
494 $this->tpl->parseCurrentBlock();
496 if ($this->finish_test_modal === null) {
500 $this->tpl->setCurrentBlock(
'finish_test_modal');
501 $this->tpl->setVariable(
503 $this->ui_renderer->render(
504 $this->finish_test_modal->withOnLoad($this->finish_test_modal->getShowSignal())
507 $this->tpl->parseCurrentBlock();
537 $this->tpl->setCurrentBlock(
"next_bottom");
538 $this->tpl->setVariable(
"BTN_NEXT_BOTTOM", $this->ui_renderer->render($button));
539 $this->tpl->parseCurrentBlock();
546 $this->tpl->setCurrentBlock(
"next");
547 $this->tpl->setVariable(
"BTN_NEXT", $this->ui_renderer->render($button));
548 $this->tpl->parseCurrentBlock();
555 $this->tpl->setCurrentBlock(
"prev_bottom");
556 $this->tpl->setVariable(
"BTN_PREV_BOTTOM", $this->ui_renderer->render($button));
557 $this->tpl->parseCurrentBlock();
564 $this->tpl->setCurrentBlock(
"prev");
565 $this->tpl->setVariable(
"BTN_PREV", $this->ui_renderer->render($button));
566 $this->tpl->parseCurrentBlock();
577 $button = $this->ui_factory->button()->primary(
578 $this->
lng->txt(
'next_question') .
'<span class="glyphicon glyphicon-arrow-right"></span> ',
580 )->withUnavailableAction(
true)
583 $button = $this->ui_factory->button()->standard(
584 $this->
lng->txt(
'next_question') .
'<span class="glyphicon glyphicon-arrow-right"></span> ',
586 )->withUnavailableAction(
true)
599 $button = $this->ui_factory->button()->standard(
600 '<span class="glyphicon glyphicon-arrow-left"></span> ' . $this->
lng->txt(
'previous_question'),
602 )->withUnavailableAction(
true)
609 return static function (
string $id) use ($target, $cmd):
string {
610 return "document.getElementById('{$id}').addEventListener('click', " 611 .
"(e) => {il.TestPlayerQuestionEditControl.checkNavigation('{$target}', '{$cmd}', e);}" 613 .
"document.getElementById('{$id}').removeAttribute('disabled');";
622 $solutionValues = $question_gui->
getObject()->getSolutionValues(
623 $this->test_session->getActiveId(),
628 $question_gui->
getObject()->fetchIndexedValuesFromValuePairs($solutionValues)
631 if (!empty($feedback)) {
632 $this->tpl->setCurrentBlock(
"specific_feedback");
633 $this->tpl->setVariable(
"SPECIFIC_FEEDBACK", $feedback);
634 $this->tpl->parseCurrentBlock();
646 $feedback = $question_gui->
getGenericFeedbackOutput($this->test_session->getActiveId(), $this->test_session->getPass());
648 if (strlen($feedback)) {
654 $this->tpl->setCurrentBlock(
"answer_feedback");
655 $this->tpl->setVariable(
"ANSWER_FEEDBACK", $feedback);
656 $this->tpl->setVariable(
"ILC_FB_CSS_CLASS", $cssClass);
657 $this->tpl->parseCurrentBlock();
665 $scoreInformation = sprintf(
666 $this->
lng->txt(
"you_received_a_of_b_points"),
671 $this->tpl->setCurrentBlock(
"received_points_information");
672 $this->tpl->setVariable(
"RECEIVED_POINTS_INFORMATION", $scoreInformation);
673 $this->tpl->parseCurrentBlock();
678 if (strlen($solutionoutput)) {
679 $this->tpl->setCurrentBlock(
"solution_output");
680 $this->tpl->setVariable(
"CORRECT_SOLUTION", $this->
lng->txt(
"tst_best_solution_is"));
681 $this->tpl->setVariable(
"QUESTION_FEEDBACK", $solutionoutput);
682 $this->tpl->parseCurrentBlock();
688 $this->tpl->setCurrentBlock(
"SyntaxStyle");
689 $this->tpl->setVariable(
690 "LOCATION_SYNTAX_STYLESHEET",
693 $this->tpl->parseCurrentBlock();
698 $this->tpl->setCurrentBlock(
"ContentStyle");
699 $this->tpl->setVariable(
700 "LOCATION_CONTENT_STYLESHEET",
703 $this->tpl->parseCurrentBlock();
713 if ($this->test_session->isAnonymousUser()) {
714 $this->test_session->setAccessCodeToSession($this->testrequest->strVal(
'anonymous_id'));
717 $this->
ctrl->redirectByClass([ilRepositoryGUI::class, ilObjTestGUI::class, ilInfoScreenGUI::class]);
729 $isFirstTestStartRequest =
false;
731 $this->process_locker->executeTestStartLockOperation(
function () use ($testStartLock, &$isFirstTestStartRequest) {
732 if ($this->test_session->lookupTestStartLock() !== $testStartLock) {
733 $this->test_session->persistTestStartLock($testStartLock);
734 $isFirstTestStartRequest =
true;
738 if ($isFirstTestStartRequest) {
743 $this->
ctrl->setParameterByClass(
'ilObjTestGUI',
'lock', $testStartLock);
744 $this->
ctrl->redirectByClass([ilRepositoryGUI::class, ilObjTestGUI::class, ilInfoScreenGUI::class]);
749 if ($this->testrequest->isset(
'lock') && strlen($this->testrequest->raw(
'lock'))) {
750 return $this->testrequest->raw(
'lock');
760 $active_id = $this->test_session->getActiveId();
761 $this->
ctrl->setParameter($this,
"active_id", $active_id);
763 $active_time_id = $this->
object->startWorkingTime($active_id, $this->test_session->getPass());
767 if ($this->
object->isRandomTest()) {
768 if (!$this->test_sequence->hasRandomQuestionsForPass($active_id, $this->test_session->getPass())) {
774 $shuffle = $this->
object->getShuffleQuestions();
775 if ($this->
object->isRandomTest()) {
779 $this->
object->updateTestPassResults(
781 $this->test_session->getPass(),
783 $this->
object->getId()
787 if (!$this->test_sequence->hasSequence()) {
788 $this->test_sequence->createNewSequence($this->
object->getQuestionCount(), $shuffle);
789 $this->test_sequence->saveToDb();
792 if ($this->
object->getListOfQuestionsStart()) {
796 $this->
ctrl->setParameter($this,
'sequence', $this->test_session->getLastSequence());
797 $this->
ctrl->setParameter($this,
'pmode',
'');
806 if ($this->test_session->isAnonymousUser()
807 && !$this->test_session->doesAccessCodeInSessionExists()) {
808 $access_code = $this->test_session->createNewAccessCode();
810 $this->test_session->setAccessCodeToSession($access_code);
811 $this->test_session->setAnonymousId($access_code);
812 $this->test_session->saveToDb();
817 if (!$this->test_session->isAnonymousUser()) {
818 $this->test_session->unsetAccessCodeInSession();
825 $this->tpl->addBlockFile($this->
getContentBlockName(),
"adm_content",
"tpl.il_as_tst_anonymous_code_presentation.html",
"components/ILIAS/Test");
826 $this->tpl->setCurrentBlock(
"adm_content");
827 $this->tpl->setVariable(
"TEXT_ANONYMOUS_CODE_CREATED", $this->
lng->txt(
"tst_access_code_created"));
828 $this->tpl->setVariable(
"TEXT_ANONYMOUS_CODE", $this->test_session->getAccessCodeFromSession());
829 $this->tpl->setVariable(
"FORMACTION", $this->
ctrl->getFormAction($this));
831 $this->tpl->setVariable(
"TXT_CONFIRM", $this->
lng->txt(
"continue_work"));
832 $this->tpl->parseCurrentBlock();
845 if ($this->
object->getNrOfTries() != 1
846 && $this->
object->getUsePreviousAnswers() == 1
848 $chb_use_previous_answers = 0;
849 if ($this->post_wrapper->has(
'chb_use_previous_answers')) {
850 $chb_use_previous_answers = $this->post_wrapper->retrieve(
851 'chb_use_previous_answers',
855 $this->
user->writePref(
"tst_use_previous_answers", (
string) $chb_use_previous_answers);
881 $this->tpl->addBlockFile($this->
getContentBlockName(),
"adm_content",
"tpl.il_as_tst_redirect_autosave.html",
"components/ILIAS/Test");
882 $this->tpl->setVariable(
"TEXT_REDIRECT", $this->
lng->txt(
"redirectAfterSave"));
883 $this->tpl->setVariable(
"URL",
$url);
888 return $this->test_sequence->getQuestionForSequence($this->testrequest->int(
'sequence'));
897 if (!$this->
access->checkAccess(
'read',
'', $this->ref_id)) {
898 echo $this->
lng->txt(
'autosave_failed') .
': ' . $this->
lng->txt(
'msg_no_perm_read_item');
901 $test_can_run = $this->
object->isExecutable($this->test_session, $this->test_session->getUserId());
902 if (!$test_can_run[
'executable']) {
903 echo $test_can_run[
'errormessage'];
906 if ($this->testrequest->getPostKeys() === []) {
917 echo $this->
lng->txt(
'autosave_success');
921 echo $this->
lng->txt(
'autosave_failed');
948 $this->test_session->getActiveId(),
949 $this->test_session->getPass()
952 $result[
'isAnswered'] = $state[
'authorized'];
953 $result[
'isAnswerChanged'] = $state[
'intermediate'];
955 echo json_encode($result);
980 $question_id = $this->test_sequence->getQuestionForSequence(
984 $this->
object->setQuestionSetSolved(1, $question_id, $this->test_session->getUserId());
1002 $question_id = $this->test_sequence->getQuestionForSequence(
1006 $this->
object->setQuestionSetSolved(0, $question_id, $this->test_session->getUserId());
1016 if ($this->testrequest->strVal(
'finalization_confirmed') !==
'confirmed') {
1029 if ($this->
logger->isLoggingEnabled()
1031 && ($interaction = $this->
logger->getInteractionFactory()->buildParticipantInteraction(
1034 $this->
user->getId(),
1035 $this->
logger->isIPLoggingEnabled() ?
$_SERVER[
'REMOTE_ADDR'] :
'',
1039 $this->
logger->logParticipantInteraction($interaction);
1048 $this->test_session,
1050 $this->test_pass_result_repository
1051 ))->performFinishTasks($this->process_locker, $status_of_attempt);
1052 $this->
object->updateTestResultCache($this->test_session->getActiveId(), null);
1055 $this->test_session->getActiveId(),
1056 $this->test_session->getPass()
1062 $notification_type = $this->
object->getMainSettings()->getFinishingSettings()->getMailNotificationContentType();
1064 if ($notification_type === 0
1065 || !$this->
object->getMainSettings()->getFinishingSettings()->getAlwaysSendMailNotification()
1066 && $pass !== $this->
object->getNrOfTries() - 1) {
1070 switch ($this->
object->getMainSettings()->getFinishingSettings()->getMailNotificationContentType()) {
1072 $this->
object->sendSimpleNotification($active_id);
1075 $this->
object->sendAdvancedNotification($active_id);
1083 if (!$this->testrequest->isset(
'skipfinalstatement')) {
1084 if ($this->
object->getMainSettings()->getFinishingSettings()->getConcludingRemarksEnabled()) {
1090 $redirection_url = $this->
object->getMainSettings()->getFinishingSettings()->getRedirectionUrl();
1091 if (!empty($redirection_url)
1092 && !$this->
object->canShowTestResults($this->test_session)
1094 if ($this->
object->isRedirectModeKiosk()) {
1095 if ($this->
object->getKioskMode()) {
1109 $class = get_class($this);
1110 $this->
ctrl->setParameterByClass($class,
'finalization_confirmed',
'confirmed');
1112 $this->
ctrl->clearParameterByClass($class,
'finalization_confirmed');
1114 $message = $this->
lng->txt(
'tst_finish_confirmation_question');
1115 if (($this->
object->getNrOfTries() - 1) === $this->test_session->getPass()) {
1116 $message = $this->
lng->txt(
'tst_finish_confirmation_question_no_attempts_left');
1119 return $this->ui_factory->modal()->interruptive(
1120 $this->
lng->txt(
'finish_test'),
1123 )->withActionButtonLabel($this->
lng->txt(
'tst_finish_confirm_button'));
1129 $testPassesSelector->setActiveId($this->test_session->getActiveId());
1130 $testPassesSelector->setLastFinishedPass($this->test_session->getLastFinishedPass());
1132 if (count($testPassesSelector->getReportablePasses())) {
1134 $this->
ctrl->redirectByClass([
'ilTestResultsGUI',
'ilTestEvalObjectiveOrientedGUI']);
1137 $this->
ctrl->redirectByClass([ilTestResultsGUI::class, ilMyTestResultsGUI::class, ilTestEvaluationGUI::class]);
1140 $this->
ctrl->redirectByClass(TestScreenGUI::class, TestScreenGUI::DEFAULT_CMD);
1148 $this->global_screen->tool()->context()->current()->getAdditionalData()->replace(
1150 $this->
object->getTitle() .
' - ' . $this->
lng->txt(
'final_statement')
1153 $this->content_style->gui()->addCss($this->tpl, $this->ref_id);
1154 $this->
ctrl->setParameterByClass(ilTestPageGUI::class,
'page_type',
'concludingremarkspage');
1155 $this->
ctrl->setParameterByClass(static::class,
'skipfinalstatement', 1);
1156 $this->tpl->setVariable(
1158 $this->ui_renderer->render([
1159 $this->ui_factory->legacy(
1160 $this->object->getFinalStatement()
1162 $this->ui_factory->button()->standard(
1163 $this->
lng->txt(
'btn_next'),
1172 $this->navigation_history->addItem(
1173 $this->test_session->getRefId(),
1187 if ($this->
object->endingTimeReached()) {
1193 $this->
ctrl->setParameter($this,
"sequence", $sequenceElement);
1198 $this->tpl->setVariable(
"TEST_ID", (
string) $this->
object->getTestId());
1199 $this->tpl->setVariable(
"LOGIN", $this->
user->getLogin());
1201 $this->tpl->setVariable(
"SEQ_ID", $sequenceElement);
1202 $this->tpl->setVariable(
"QUEST_ID", $question_id);
1204 if ($this->
object->getEnableProcessingTime()) {
1208 $this->tpl->setVariable(
"PAGETITLE",
"- " . $this->
object->getTitle());
1210 if ($this->
object->isShowExamIdInTestPassEnabled() && !$this->
object->getKioskMode()) {
1211 $this->tpl->setCurrentBlock(
'exam_id_footer');
1213 $this->test_session->getActiveId(),
1214 $this->test_session->getPass(),
1215 $this->
object->getId()
1217 $this->tpl->setVariable(
'EXAM_ID_TXT', $this->
lng->txt(
'exam_id'));
1218 $this->tpl->parseCurrentBlock();
1221 if ($this->
object->getListOfQuestions()) {
1228 if ($this->test_sequence->isAnsweringOptionalQuestionsConfirmed()) {
1232 $question_id = $this->test_sequence->getQuestionForSequence($sequence_key);
1234 if (!$this->test_sequence->isQuestionOptional($question_id)) {
1243 return $this->test_sequence->isPostponedQuestion($question_id);
1248 string $form_action,
1249 bool $is_question_worked_through,
1250 bool $instant_response
1253 $question_navigation_gui->setQuestionWorkedThrough($is_question_worked_through);
1258 $this->test_session->getActiveId(),
1259 $this->test_session->getPass(),
1263 $instant_response && $this->
object->getSpecificAnswerFeedback(),
1272 $this->test_session->getActiveId(),
1276 $this->tpl->setVariable(
1277 'LOCKSTATE_INFOBOX',
1278 $this->ui_renderer->render(
1279 $this->ui_factory->messageBox()->info($this->
lng->txt(
'tst_player_answer_saved_and_locked'))
1282 $this->tpl->parseCurrentBlock();
1283 $this->tpl->setVariable(
'QUESTION_OUTPUT', $pageoutput);
1284 $this->tpl->setVariable(
'FORMACTION', $form_action);
1285 $this->tpl->setVariable(
'ENCTYPE',
'enctype="' . $question_gui->
getFormEncodingType() .
'"');
1286 $this->tpl->setVariable(
'FORM_TIMESTAMP', time());
1292 string $form_action,
1293 bool $is_question_worked_through,
1294 bool $instant_response
1297 $question_navigation_gui->setQuestionWorkedThrough($is_question_worked_through);
1298 if ($is_question_worked_through) {
1299 $question_navigation_gui->setDiscardSolutionButtonEnabled(
true);
1301 } elseif ($this->
object->isPostponingEnabled()) {
1302 $question_navigation_gui->setSkipQuestionLinkTarget(
1308 $user_post_solution =
false;
1309 if ($this->testrequest->isset(
'save_error')
1310 && $this->testrequest->int(
'save_error') === 1
1316 $question_config = $question_gui->
getObject()->getTestPresentationConfig();
1319 $question_config->setWorkedThrough($is_question_worked_through);
1322 if ($question_config->isPreviousPassSolutionReuseAllowed()) {
1324 if ($pass_index < $this->test_session->getPass()) {
1325 $question_config->setSolutionInitiallyPrefilled(
true);
1328 $pass_index = $this->test_session->getPass();
1333 $question_navigation_gui->setShowDiscardModalSignal($this->modal_signals[self::DISCARD_MODAL]);
1337 $this->test_session->getActiveId(),
1340 $user_post_solution,
1341 $instant_response && $this->
object->getSpecificAnswerFeedback()
1349 if ($this->
object->isPreviousSolutionReuseEnabled($this->test_session->getActiveId())) {
1350 $currentSolutionAvailable = $question_gui->
getObject()->authorizedOrIntermediateSolutionExists(
1351 $this->test_session->getActiveId(),
1352 $this->test_session->getPass()
1355 if (!$currentSolutionAvailable) {
1356 $previousPass = $question_gui->
getObject()->getSolutionMaxPass(
1357 $this->test_session->getActiveId()
1360 $previousSolutionAvailable = $question_gui->
getObject()->authorizedSolutionExists(
1361 $this->test_session->getActiveId(),
1365 if ($previousSolutionAvailable) {
1366 return $previousPass;
1372 return $this->test_session->getPass();
1381 $this->
object->startWorkingTime(
1382 $this->test_session->getActiveId(),
1383 $this->test_session->getPass()
1387 $this->
help->setScreenIdComponent(
'tst');
1388 $this->
help->setScreenId(
'assessment');
1389 $this->
help->setSubScreenId(
'question');
1394 $sequence_element = $this->test_sequence->getFirstSequence();
1397 $this->test_session->setLastSequence($sequence_element ?? 0);
1398 $this->test_session->saveToDb();
1400 $question_id = $this->test_sequence->getQuestionForSequence($sequence_element ?? 0);
1401 if ($question_id === null && $this->test_session->isObjectiveOriented()) {
1405 if ($question_id !== null && !$this->test_sequence->isQuestionPresented($question_id)) {
1406 $this->test_sequence->setQuestionPresented($question_id);
1407 $this->test_sequence->saveToDb();
1410 $question_worked_through = $this->questionrepository->lookupResultRecordExist(
1411 $this->test_session->getActiveId(),
1413 $this->test_session->getPass()
1416 $instant_response =
false;
1419 $s = $this->
object->getMainSettings()->getQuestionBehaviourSettings();
1420 if ($s->getInstantFeedbackGenericEnabled()
1421 || $s->getInstantFeedbackPointsEnabled()
1422 || $s->getInstantFeedbackSolutionEnabled()
1423 || $s->getInstantFeedbackSpecificEnabled()) {
1424 $instant_response =
true;
1428 if (!$this->
object->isInstantFeedbackAnswerFixationEnabled()) {
1439 $question_gui->setSequenceNumber($this->test_sequence->getPositionOfSequence($sequence_element));
1440 $question_gui->setQuestionCount($this->test_sequence->getUserQuestionCount());
1443 $header_block_builder->setHeaderMode($this->
object->getTitleOutput());
1444 $header_block_builder->setQuestionTitle($question_gui->getObject()->getTitleForHTMLOutput());
1445 $header_block_builder->setQuestionPoints($question_gui->getObject()->getPoints());
1446 $header_block_builder->setQuestionPosition($this->test_sequence->getPositionOfSequence($sequence_element));
1447 $header_block_builder->setQuestionCount($this->test_sequence->getUserQuestionCount());
1448 $header_block_builder->setQuestionPostponed($this->test_sequence->isPostponedQuestion($question_id));
1449 if ($this->test_session->isObjectiveOriented()) {
1451 $objectives_adapter->buildQuestionRelatedObjectiveList($this->test_sequence, $this->question_related_objectives_list);
1452 $this->question_related_objectives_list->loadObjectivesTitles();
1454 $header_block_builder->setQuestionRelatedObjectives(
1455 $this->question_related_objectives_list->getQuestionRelatedObjectiveTitles($question_id)
1458 $question_gui->setQuestionHeaderBlockBuilder($header_block_builder);
1460 $this->
prepareTestPage($presentation_mode, $sequence_element, $question_id);
1463 $navigation_toolbar_gui->setFinishTestButtonEnabled(
true);
1467 $this->
ctrl->setParameter($this,
'sequence', $sequence_element);
1468 $this->
ctrl->setParameter($this,
'pmode', $presentation_mode);
1471 switch ($presentation_mode) {
1473 $navigation_toolbar_gui->setDisabledStateEnabled(
false);
1477 $question_worked_through,
1481 if ($this->
ctrl->getCmd() !== self::FINISH_TEST_CMD
1482 && $this->
logger->isLoggingEnabled()
1483 && !$this->
getObject()->getAnonymity()) {
1484 $this->
logger->logParticipantInteraction(
1485 $this->
logger->getInteractionFactory()->buildParticipantInteraction(
1486 $this->
object->getRefId(),
1488 $this->
user->getId(),
1489 $this->
logger->isIPLoggingEnabled() ?
$_SERVER[
'REMOTE_ADDR'] :
'',
1490 TestParticipantInteractionTypes::QUESTION_SHOWN,
1498 if ($this->test_sequence->isQuestionOptional($question_gui->getObject()->getId())) {
1505 $question_worked_through,
1514 $navigation_toolbar_gui->build();
1518 if ($instant_response) {
1540 $question_id = $this->test_sequence->getQuestionForSequence(
1546 if ($this->
object->isForceInstantFeedbackEnabled()) {
1547 $this->
ctrl->setParameter($this,
'instresp', 1);
1549 $this->test_sequence->setQuestionChecked($question_id);
1550 $this->test_sequence->saveToDb();
1556 $this->
ctrl->setParameter($this,
'pmode',
'');
1575 $this->
ctrl->saveParameter($this,
'sequence');
1586 $this->
ctrl->saveParameter($this,
'sequence');
1596 $this->test_sequence->getQuestionForSequence($current_sequence_element)
1598 $current_question_obj->setTestId($this->
object->getId());
1600 $current_question_obj->resetUsersAnswer(
1601 $this->test_session->getActiveId(),
1602 $this->test_session->getPass()
1605 if ($this->
logger->isLoggingEnabled()
1606 && !$this->
getObject()->getAnonymity()) {
1607 $this->
logger->logParticipantInteraction(
1608 $this->
logger->getInteractionFactory()->buildParticipantInteraction(
1609 $this->
object->getRefId(),
1610 $this->test_sequence->getQuestionForSequence($current_sequence_element),
1611 $this->
user->getId(),
1612 $this->
logger->isIPLoggingEnabled() ?
$_SERVER[
'REMOTE_ADDR'] :
'',
1613 TestParticipantInteractionTypes::ANSWER_DELETED,
1619 $this->
ctrl->saveParameter($this,
'sequence');
1629 $next_sequence_element = $this->test_sequence->getNextSequence($current_sequence_element);
1632 $next_sequence_element = $this->test_sequence->getFirstSequence();
1635 if ($this->
object->isPostponingEnabled()) {
1636 $this->test_sequence->postponeSequence($current_sequence_element);
1637 $this->test_sequence->saveToDb();
1640 if ($this->
logger->isLoggingEnabled()
1641 && !$this->
getObject()->getAnonymity()) {
1642 $this->
logger->logParticipantInteraction(
1643 $this->
logger->getInteractionFactory()->buildParticipantInteraction(
1644 $this->
object->getRefId(),
1645 $this->test_sequence->getQuestionForSequence($current_sequence_element),
1646 $this->
user->getId(),
1647 $this->
logger->isIPLoggingEnabled() ?
$_SERVER[
'REMOTE_ADDR'] :
'',
1648 TestParticipantInteractionTypes::QUESTION_SKIPPED,
1654 $this->
ctrl->setParameter($this,
'sequence', $next_sequence_element);
1655 $this->
ctrl->setParameter($this,
'pmode',
'');
1665 $this->test_session->setUserId($this->
user->getId());
1667 if ($access_code != null && isset($access_code[$this->
object->getTestId()])) {
1668 $this->test_session->setAnonymousId($access_code[$this->
object->getTestId()]);
1673 $this->test_session->saveToDb();
1675 $active_id = $this->test_session->getActiveId();
1676 $this->
ctrl->setParameter($this,
"active_id", $active_id);
1678 $shuffle = $this->
object->getShuffleQuestions();
1679 if ($this->
object->isRandomTest()) {
1682 $this->
object->loadQuestions();
1686 $this->
object->updateTestPassResults(
1688 $this->test_session->getPass(),
1690 $this->
object->getId()
1694 if (!$this->test_sequence->hasSequence()) {
1695 $this->test_sequence->createNewSequence($this->
object->getQuestionCount(), $shuffle);
1696 $this->test_sequence->saveToDb();
1699 $this->test_sequence->loadFromDb();
1700 $this->test_sequence->loadQuestions();
1702 if ($this->test_session->isObjectiveOriented()) {
1705 $objectivesAdapter->notifyTestStart($this->test_session, $this->
object->getId());
1706 $objectivesAdapter->prepareTestPass($this->test_session, $this->test_sequence);
1708 $objectivesAdapter->buildQuestionRelatedObjectiveList(
1709 $this->test_sequence,
1710 $this->question_related_objectives_list
1713 if ($this->test_sequence->hasOptionalQuestions()) {
1716 $this->test_sequence->reorderOptionalQuestionsToSequenceEnd();
1717 $this->test_sequence->saveToDb();
1721 $active_time_id = $this->
object->startWorkingTime(
1722 $this->test_session->getActiveId(),
1723 $this->test_session->getPass()
1729 $sequence_element = $this->test_sequence->getFirstSequence();
1731 $this->
ctrl->setParameter($this,
'sequence', $sequence_element);
1732 $this->
ctrl->setParameter($this,
'pmode',
'');
1734 if ($this->
logger->isLoggingEnabled()
1735 && !$this->
getObject()->getAnonymity()) {
1736 $this->
logger->logParticipantInteraction(
1737 $this->
logger->getInteractionFactory()->buildParticipantInteraction(
1738 $this->
object->getRefId(),
1740 $this->
user->getId(),
1741 $this->
logger->isIPLoggingEnabled() ?
$_SERVER[
'REMOTE_ADDR'] :
'',
1742 TestParticipantInteractionTypes::TEST_RUN_STARTED,
1748 if ($this->
object->getListOfQuestionsStart()) {
1749 $this->
ctrl->setParameterByClass(static::class,
'first',
'1');
1763 and $this->
object->startingTimeReached()
1764 and !$this->
object->endingTimeReached();
1772 return $this->
object->hasNrOfTriesRestriction() && $this->
object->isNrOfTriesReached($this->test_session->getPass());
1783 $this->test_session->increasePass();
1784 $this->test_session->setLastSequence(0);
1785 $this->test_session->saveToDb();
1809 $this->tpl->addBlockFile($this->
getContentBlockName(),
"adm_content",
"tpl.il_as_tst_submit_answers_confirm.html",
"components/ILIAS/Test");
1810 $this->tpl->setCurrentBlock(
"adm_content");
1811 if ($this->
object->isTestFinished($this->test_session->getActiveId())) {
1812 $this->tpl->setCurrentBlock(
"not_submit_allowed");
1813 $this->tpl->setVariable(
"TEXT_ALREADY_SUBMITTED", $this->
lng->txt(
"tst_already_submitted"));
1814 $this->tpl->setVariable(
"BTN_OK", $this->
lng->txt(
"tst_show_answer_sheet"));
1816 $this->tpl->setCurrentBlock(
"submit_allowed");
1817 $this->tpl->setVariable(
"TEXT_CONFIRM_SUBMIT_RESULTS", $this->
lng->txt(
"tst_confirm_submit_answers"));
1818 $this->tpl->setVariable(
"BTN_OK", $this->
lng->txt(
"tst_submit_results"));
1820 $this->tpl->setVariable(
"BTN_BACK", $this->
lng->txt(
"back"));
1821 $this->tpl->setVariable(
"FORMACTION", $this->
ctrl->getFormAction($this,
"finalSubmission"));
1822 $this->tpl->parseCurrentBlock();
1827 $starting_time = $this->
object->getStartingTimeOfUser($active_id);
1833 $this->
object->getProcessingTimeInSeconds($active_id)
1836 $this->tpl->setCurrentBlock(
'enableprocessingtime');
1837 $this->tpl->setVariable(
'USER_WORKING_TIME_MESSAGE_BOX', $working_time->getMessageBox($verbose));
1838 $this->tpl->parseCurrentBlock();
1842 getdate($starting_time),
1843 $this->
ctrl->getLinkTarget($this,
'checkWorkingTime',
'',
true),
1847 $this->tpl->addOnLoadCode($working_time_js_template->get());
1859 $active_id = $this->test_session->getActiveId();
1860 echo (
string) $this->
object->getProcessingTimeInSeconds($active_id);
1866 $question_summary_data = $this->service->getQuestionSummaryData($this->test_sequence);
1870 foreach ($question_summary_data as $idx => $row) {
1871 $title = htmlspecialchars($row[
'title'], ENT_QUOTES, null,
false);
1873 if ($row[
'description'] !==
'') {
1874 $description = htmlspecialchars($row[
'description'], ENT_QUOTES, null,
false);
1877 if (!$row[
'disabled']) {
1878 $this->
ctrl->setParameter($this,
'pmode',
'');
1879 $this->
ctrl->setParameter($this,
'sequence', $row[
'sequence']);
1888 ($row[
'worked_through'] || $row[
'isAnswered'])
1889 && $row[
'has_authorized_answer']
1894 $questions[] = $this->ui_factory->listing()->workflow()
1895 ->step($title, $description, $action)
1896 ->withStatus($status);
1897 $active = $row[
'sequence'] == $current_sequence_element ? $idx : $active;
1900 $question_listing = $this->ui_factory->listing()->workflow()->linear(
1901 $this->
lng->txt(
'mainbar_button_label_questionlist'),
1903 )->withActive($active);
1906 $this->global_screen->tool()->context()->current()->addAdditionalData(
1917 $this->
help->setScreenIdComponent(
'tst');
1918 $this->
help->setScreenId(
'assessment');
1919 $this->
help->setSubScreenId(
'question_summary');
1921 $is_first_page = $this->testrequest->strVal(
'first') ===
'1';
1923 $this->tpl->addBlockFile(
1926 'tpl.il_as_tst_question_summary.html',
1927 'components/ILIAS/Test' 1930 $this->global_screen->tool()->context()->current()->getAdditionalData()->replace(
1935 $active_id = $this->test_session->getActiveId();
1936 $question_summary_data = $this->service->getQuestionSummaryData($this->test_sequence);
1938 $this->
ctrl->setParameter($this,
'sequence', $this->testrequest->raw(
'sequence'));
1948 $question_summary_data
1950 $this->tpl->setVariable(
'TABLE_LIST_OF_QUESTIONS', $this->ui_renderer->render($table->buildComponents($is_first_page)));
1952 if ($this->
object->getEnableProcessingTime()) {
1956 if ($this->
object->isShowExamIdInTestPassEnabled()) {
1957 $this->tpl->setCurrentBlock(
'exam_id_footer');
1959 $this->test_session->getActiveId(),
1960 $this->test_session->getPass(),
1961 $this->
object->getId()
1963 $this->tpl->setVariable(
'EXAM_ID_TXT', $this->
lng->txt(
'exam_id'));
1964 $this->tpl->parseCurrentBlock();
1978 $this->tpl->addBlockFile(
"ADM_CONTENT",
"adm_content",
"tpl.il_as_tst_correct_solution.html",
"components/ILIAS/Test");
1980 $this->tpl->setCurrentBlock(
"ContentStyle");
1982 $this->tpl->parseCurrentBlock();
1984 $this->tpl->setCurrentBlock(
"SyntaxStyle");
1986 $this->tpl->parseCurrentBlock();
1989 if ($this->
object->getShowSolutionAnswersOnly()) {
1993 $this->tpl->setCurrentBlock(
"adm_content");
1994 $solution = $this->
getCorrectSolutionOutput($this->testrequest->raw(
"evaluation"), $this->testrequest->raw(
"active_id"), $this->testrequest->raw(
"pass"));
1995 $this->tpl->setVariable(
"OUTPUT_SOLUTION", $solution);
1996 $this->tpl->setVariable(
"TEXT_BACK", $this->
lng->txt(
"back"));
1997 $this->
ctrl->saveParameter($this,
"pass");
1998 $this->
ctrl->saveParameter($this,
"active_id");
1999 $this->tpl->setVariable(
"URL_BACK", $this->
ctrl->getLinkTarget($this,
"outUserResultsOverview"));
2000 $this->tpl->parseCurrentBlock();
2014 $this->tpl->addBlockFile($this->
getContentBlockName(),
"adm_content",
"tpl.il_as_tst_finish_list_of_answers.html",
"components/ILIAS/Test");
2016 $result_array = $this->
object->getTestResult(
2025 foreach ($result_array as $question_data) {
2026 $question = $question_data[
"qid"];
2027 if (is_numeric($question)) {
2028 $this->tpl->setCurrentBlock(
"printview_question");
2029 $question_gui = $this->
object->createQuestionGUI(
"", $question);
2030 $template =
new ilTemplate(
"tpl.il_as_qpl_question_printview.html",
true,
true,
"components/ILIAS/TestQuestionPool");
2031 $template->setVariable(
"COUNTER_QUESTION", $counter .
". ");
2032 $template->setVariable(
"QUESTION_TITLE", $question_gui->getObject()->getTitleForHTMLOutput());
2034 $show_question_only = ($this->
object->getShowSolutionAnswersOnly()) ?
true :
false;
2035 $result_output = $question_gui->getSolutionOutput(
2040 $show_question_only,
2041 $this->
object->getShowSolutionFeedback()
2043 $template->setVariable(
"SOLUTION_OUTPUT", $result_output);
2044 $this->tpl->setVariable(
"QUESTION_OUTPUT", $template->get());
2045 $this->tpl->parseCurrentBlock();
2051 if ($this->
object->getShowSolutionAnswersOnly()) {
2054 if (strlen($top_data)) {
2055 $this->tpl->setCurrentBlock(
"top_data");
2056 $this->tpl->setVariable(
"TOP_DATA", $top_data);
2057 $this->tpl->parseCurrentBlock();
2060 if (strlen($bottom_data)) {
2061 $this->tpl->setCurrentBlock(
"bottom_data");
2062 $this->tpl->setVariable(
"FORMACTION", $this->
ctrl->getFormAction($this));
2063 $this->tpl->setVariable(
"BOTTOM_DATA", $bottom_data);
2064 $this->tpl->parseCurrentBlock();
2067 $this->tpl->setCurrentBlock(
"adm_content");
2068 $this->tpl->setVariable(
"TXT_ANSWER_SHEET", $this->
lng->txt(
"tst_list_of_answers"));
2071 $this->tpl->setVariable(
"USER_DETAILS", $user_data);
2072 $this->tpl->setVariable(
"SIGNATURE", $signature);
2073 $this->tpl->setVariable(
"TITLE", $this->
object->getTitle());
2074 $this->tpl->setVariable(
"TXT_TEST_PROLOG", $this->
lng->txt(
"tst_your_answers"));
2075 $invited_user = &$this->
object->getInvitedUsers($this->
user->getId());
2076 $pagetitle = $this->
object->getTitle() .
' - ' . $this->
lng->txt(
'clientip') .
2077 ': ' .
$_SERVER[
'REMOTE_ADDR'] .
' - ' .
2078 $this->
lng->txt(
'matriculation') .
': ' .
2079 $invited_user[$this->
user->getId()][
'matriculation'];
2080 $this->tpl->setVariable(
'PAGETITLE', $pagetitle);
2081 $this->tpl->parseCurrentBlock();
2091 return "ADM_CONTENT";
2093 if ($this->
object->getKioskMode()) {
2094 $this->tpl->setBodyClass(
"kiosk");
2095 $this->tpl->hideFooter();
2098 return "ADM_CONTENT";
2104 $this->
ctrl->redirectByClass(
2105 [ilRepositoryGUI::class, ilObjTestGUI::class, ilTestEvaluationGUI::class],
2106 "outUserResultsOverview" 2119 $this->
ctrl->setParameter($this,
'pmode', self::PRESENTATION_MODE_EDIT);
2133 $this->
ctrl->setParameter($this,
'pmode', self::PRESENTATION_MODE_EDIT);
2140 return $sequence_element == $this->test_sequence->getFirstSequence();
2145 return $sequence_element == $this->test_sequence->getLastSequence();
2150 $question_id = $this->test_sequence->getQuestionForSequence(
2167 $question_id = $this->test_sequence->getQuestionForSequence(
2178 $this->test_sequence->setQuestionChecked($question_id);
2179 $this->test_sequence->saveToDb();
2180 } elseif ($this->
object->isForceInstantFeedbackEnabled()) {
2181 $this->test_sequence->setQuestionChecked($question_id);
2182 $this->test_sequence->saveToDb();
2185 $this->
ctrl->setParameter($this,
'instresp', 1);
2200 $next_sequence_element = $this->test_sequence->getNextSequence($last_sequence_element);
2202 $question_id = $this->test_sequence->getQuestionForSequence($last_sequence_element);
2203 $is_worked_through = $this->questionrepository->lookupResultRecordExist(
2204 $this->test_session->getActiveId(),
2206 $this->test_session->getPass()
2209 if (!$is_worked_through) {
2210 if ($this->
logger->isLoggingEnabled()
2211 && !$this->
getObject()->getAnonymity()) {
2212 $this->
logger->logParticipantInteraction(
2213 $this->
logger->getInteractionFactory()->buildParticipantInteraction(
2214 $this->
object->getRefId(),
2216 $this->
user->getId(),
2217 $this->
logger->isIPLoggingEnabled() ?
$_SERVER[
'REMOTE_ADDR'] :
'',
2218 TestParticipantInteractionTypes::QUESTION_SKIPPED,
2223 if ($this->
object->isPostponingEnabled()) {
2229 $next_sequence_element = $this->test_sequence->getFirstSequence();
2232 $this->
ctrl->setParameter($this,
'sequence', $next_sequence_element);
2233 $this->
ctrl->setParameter($this,
'pmode',
'');
2242 $sequence_element = $this->test_sequence->getPreviousSequence(
2247 $sequence_element = $this->test_sequence->getLastSequence();
2250 $this->
ctrl->setParameter($this,
'sequence', $sequence_element);
2251 $this->
ctrl->setParameter($this,
'pmode',
'');
2258 $this->tpl->addBlockFile(
2261 'tpl.il_as_tst_question_summary.html',
2262 'components/ILIAS/Test' 2269 let key_event = (
event) => {
2270 if(
event.key === 13 &&
event.target.tagName.toLowerCase() ===
"a" ) {
2273 if (
event.key === 13 &&
2274 event.target.tagName.toLowerCase() !==
"textarea" &&
2275 (
event.target.tagName.toLowerCase() !==
"input" ||
event.target.type.toLowerCase() !==
"submit")) {
2276 event.preventDefault();
2280 let
form = document.getElementById(
'taForm');
2281 form.onkeyup = key_event;
2282 form.onkeydown = key_event;
2283 form.onkeypress = key_event;
2285 $this->tpl->addOnLoadCode($onload_js);
2286 $this->tpl->addBlockFile(
2289 'tpl.il_as_tst_output.html',
2290 'components/ILIAS/Test' 2302 if ($this->test_session->isPasswordChecked() ===
true) {
2306 if ($this->
ctrl->getNextClass() ===
'iltestpasswordprotectiongui') {
2310 if (!$this->password_checker->isPasswordProtectionPageRedirectRequired()) {
2311 $this->test_session->setPasswordChecked(
true);
2318 $this->
ctrl->setParameterByClass(ilTestPasswordProtectionGUI::class,
'nextCommand', $next_command);
2319 $this->
ctrl->redirectByClass(ilTestPasswordProtectionGUI::class,
'showPasswordForm');
2324 if ($this->
object->isInstantFeedbackAnswerFixationEnabled()) {
2325 return $this->test_sequence->isQuestionChecked($question_id);
2328 if ($this->
object->isFollowupQuestionAnswerFixationEnabled()) {
2340 return $this->
lng->txt(
"save_introduction");
2345 $this->ass_settings =
new ilSetting(
'assessment');
2356 $this->
object->getTestId(),
2357 $this->
object->getRefId(),
2358 $this->skills_service->profile(),
2359 $this->skills_service->personal()
2363 $skill_evaluation->setActiveId($test_session->
getActiveId());
2364 $skill_evaluation->setPass($test_session->
getPass());
2366 $skill_evaluation->setNumRequiredBookingsForSkillTriggering(
2367 $this->
object->getGlobalSettings()->getSkillTriggeringNumberOfAnswers()
2371 $question_list->load();
2372 $skill_evaluation->init($question_list);
2373 $skill_evaluation->evaluate(
2374 $this->
object->getTestResult(
2381 $skill_evaluation->handleSkillTriggering();
2388 $confirmation->setFormAction($this->
ctrl->getFormAction($this));
2389 $confirmation->setCancelCmd(
'cancelAnswerOptionalQuestions');
2390 $confirmation->setConfirmCmd(
'confirmAnswerOptionalQuestions');
2392 $confirmation->build($this->
object->isFixedTest());
2399 $this->test_sequence->setAnsweringOptionalQuestionsConfirmed(
true);
2400 $this->test_sequence->saveToDb();
2402 $this->
ctrl->setParameter($this,
'activecommand',
'gotoquestion');
2403 $this->
ctrl->redirect($this,
'redirectQuestion');
2408 if ($this->
object->getListOfQuestions()) {
2409 $this->
ctrl->setParameter($this,
'activecommand',
'summary');
2411 $this->
ctrl->setParameter($this,
'activecommand',
'previous');
2414 $this->
ctrl->redirect($this,
'redirectQuestion');
2428 $navigation_toolbar->setSuspendTestButtonEnabled($this->
object->getShowCancel());
2429 $navigation_toolbar->setUserPassOverviewEnabled($this->
object->getUsrPassOverviewEnabled());
2431 return $navigation_toolbar;
2446 if ($this->
object->getShowMarker()) {
2450 if (count($solved_array) > 0) {
2451 $solved = array_pop($solved_array);
2452 $solved = $solved[
"solved"];
2457 $navigationGUI->setQuestionMarked(
true);
2460 $navigationGUI->setQuestionMarked(
false);
2465 return $navigationGUI;
2479 if ($this->
object->getSpecificAnswerFeedback()
2480 || $this->
object->getGenericAnswerFeedback()
2481 || $this->
object->getAnswerFeedbackPoints()
2482 || $this->
object->getInstantFeedbackSolution()) {
2483 $navigation_gui->setAnswerFreezingEnabled($this->
object->isInstantFeedbackAnswerFixationEnabled());
2485 if ($this->
object->isForceInstantFeedbackEnabled()) {
2486 $navigation_gui->setForceInstantResponseEnabled(
true);
2494 if ($this->
object->isOfferingQuestionHintsEnabled()) {
2495 $activeId = $this->test_session->getActiveId();
2496 $pass = $this->test_session->getPass();
2500 if ($questionHintTracking->requestsPossible()) {
2504 if ($questionHintTracking->requestsExist()) {
2509 if ($this->
object->getShowMarker()) {
2513 if (count($solved_array) > 0) {
2514 $solved = array_pop($solved_array);
2515 $solved = $solved[
'solved'];
2518 if ($solved === 1) {
2520 $navigation_gui->setQuestionMarked(
true);
2523 $navigation_gui->setQuestionMarked(
false);
2526 return $navigation_gui;
2531 if (!$this->
object->getListOfQuestionsEnd()) {
2543 $answer_feedback_enabled = $this->
object->getSpecificAnswerFeedback();
2546 $this->test_session->getActiveId(), #active_id
2547 $this->test_session->getPass(), #pass
2548 false, #graphical_output
2549 false, #result_output
2550 true, #show_question_only
2551 $answer_feedback_enabled, #show_feedback
2552 false, #show_correct_solution
2553 false, #show_manual_scoring
2554 true #show_question_text
2560 $this->test_session->getActiveId(),
2564 $tpl =
new ilTemplate(
'tpl.tst_player_response_modal.html',
true,
true,
'components/ILIAS/Test');
2570 $this->tpl = $saved_tpl;
2578 $modal = $this->ui_factory->modal()->roundtrip(
2579 $this->
lng->txt(
'tst_instant_feedback'),
2580 $this->ui_factory->legacy($tpl->
get()),
2582 )->withActionButtons([
2583 $this->ui_factory->button()->standard($this->
lng->txt(
'proceed'), $nav_url)
2586 return $this->ui_renderer->render([
2587 $modal->withOnLoad($modal->getShowSignal())
2597 $response_available =
false;
2598 $jump_to_response =
false;
2602 if ($this->
object->getInstantFeedbackSolution()) {
2607 $this->test_session->getActiveId(), #active_id
2608 $this->test_session->getPass(), #pass
2609 false, #graphical_output
2610 $show_question_inline_score, #result_output
2611 true, #show_question_only
2612 false, #show_feedback
2613 true, #show_correct_solution
2614 false, #show_manual_scoring
2615 false #show_question_text
2617 $solutionoutput = str_replace(
'<h1 class="ilc_page_title_PageTitle"></h1>',
'', $solutionoutput);
2619 $response_available =
true;
2620 $jump_to_response =
true;
2623 $reachedPoints = $question_gui->
getObject()->getAdjustedReachedPoints(
2624 $this->test_session->getActiveId(),
2629 $maxPoints = $question_gui->
getObject()->getMaximumPoints();
2631 $solutionCorrect = ($reachedPoints == $maxPoints);
2635 if ($this->
object->getAnswerFeedbackPoints()) {
2637 $response_available =
true;
2638 $jump_to_response =
true;
2643 if ($this->
object->getGenericAnswerFeedback()) {
2645 $response_available =
true;
2646 $jump_to_response =
true;
2652 if ($this->
object->getSpecificAnswerFeedback()) {
2655 $jump_to_response =
false;
2657 $response_available =
true;
2658 $jump_to_response =
true;
2663 if (!$response_available) {
2674 if ($withFocusAnchor) {
2675 $this->tpl->setCurrentBlock(
'inst_resp_id');
2676 $this->tpl->setVariable(
'INSTANT_RESPONSE_FOCUS_ID',
'focus');
2677 $this->tpl->parseCurrentBlock();
2680 $this->tpl->setCurrentBlock(
'instant_response_header');
2681 $this->tpl->setVariable(
'INSTANT_RESPONSE_HEADER', $this->
lng->txt(
'tst_feedback'));
2682 $this->tpl->parseCurrentBlock();
2687 $this->tpl->setCurrentBlock(
'instant_response_message');
2688 $this->tpl->setVariable(
'INSTANT_RESPONSE_MESSAGE', $a_message);
2689 $this->tpl->parseCurrentBlock();
2699 return $this->test_session->getLastSequence();
2704 if ($this->testrequest->isset(
'sequence')) {
2705 return $this->testrequest->int(
'sequence');
2713 if ($this->testrequest->isset(
'pmode')) {
2714 return $this->testrequest->raw(
'pmode');
2722 return $this->testrequest->isInstanceResponseRequested();
2728 if ($this->testrequest->isset(
'nextcmd')) {
2729 $nextcmd = $this->testrequest->strVal(
'nextcmd');
2732 return $nextcmd !==
'' ? $nextcmd : null;
2737 return $this->testrequest->int(
'nextseq');
2742 $navigation_url = $this->testrequest->strVal(
'test_player_navigation_url');
2743 if ($navigation_url !==
'') {
2744 $navigation_url_parts = parse_url($navigation_url);
2747 if (!isset($navigation_url_parts[
'host']) || ($ilias_url_parts[
'host'] === $navigation_url_parts[
'host'])) {
2748 return $navigation_url;
2756 return !empty($this->testrequest->raw(
'test_answer_changed'));
2761 $this->
ctrl->setParameter($this,
'test_answer_changed', $changed ?
'1' :
'0');
2776 if ($this->testrequest->retrieveBoolFromPost(
'save_on_navigation_prevent_confirmation')) {
2780 if ($this->testrequest->retrieveBoolFromPost(self::FOLLOWUP_QST_LOCKS_PREVENT_CONFIRMATION_PARAM)) {
2781 ilSession::set(self::FOLLOWUP_QST_LOCKS_PREVENT_CONFIRMATION_PARAM,
true);
2789 if (!$from_cache || !isset($this->cached_question_guis[$question_id])) {
2790 $question_gui = $this->
object->createQuestionGUI(
"", $question_id);
2791 $question_gui->setTargetGui($this);
2793 $question = $question_gui->getObject();
2794 $question->setShuffler($this->shuffler->getAnswerShuffleFor(
2796 $this->test_session->getActiveId(),
2797 $this->test_session->getPass()
2799 $question_gui->setObject($question);
2800 $question_gui->populateJavascriptFilesRequiredForWorkForm(
$tpl);
2806 $this->cached_question_guis[$question_id] = $question_gui;
2809 return $this->cached_question_guis[$question_id];
2814 if ($from_cache && isset($this->cached_question_objects[$question_id])) {
2815 return $this->cached_question_objects[$question_id];
2818 $ass_settings =
new ilSetting(
'assessment');
2821 $process_locker_factory->setQuestionId($question->getId());
2822 $process_locker_factory->setUserId($this->
user->getId());
2823 $question->setProcessLocker($process_locker_factory->getLocker());
2827 $this->cached_question_objects[$question_id] = $question;
2834 $this->
object->isPreviousSolutionReuseEnabled($this->test_session->getActiveId())
2842 .
"active={$this->test_session->getActiveId()} " 2843 .
"qId=$question_id seq=$sequence_element " 2844 . serialize($this->test_sequence)
2847 $this->
ctrl->setParameter($this,
'sequence', $this->test_sequence->getFirstSequence());
2853 if ($this->
object->getKioskMode()) {
2854 $this->tpl->addBlockfile($this->
getContentBlockName(),
'content',
"tpl.il_as_tst_kiosk_mode_content.html",
"components/ILIAS/Test");
2855 $this->tpl->setContent($content_html);
2868 if ($this->
object->isFollowupQuestionAnswerFixationEnabled()) {
2878 $modal = $this->ui_factory->modal()->interruptive(
2879 $this->
lng->txt(
'discard_answer'),
2880 $this->
lng->txt(
'discard_answer_confirmation'),
2882 )->withActionButtonLabel($this->
lng->txt(
'discard_answer'));
2884 $this->tpl->setCurrentBlock(
'discard_solution_modal');
2885 $this->tpl->setVariable(
'DISCARD_SOLUTION_MODAL', $this->ui_renderer->render($modal));
2886 $this->tpl->parseCurrentBlock();
2887 return $modal->getShowSignal();
2892 $modal = $this->ui_factory->modal()->interruptive(
2893 $this->
lng->txt(
'tst_nav_next_locks_empty_answer_header'),
2894 $this->
lng->txt(
'tst_nav_next_locks_empty_answer_confirm'),
2895 'javascript:il.TestPlayerQuestionEditControl.confirmNextLocksUnchanged()' 2896 )->withActionButtonLabel($this->
lng->txt(
'tst_proceed'));
2898 $this->tpl->setCurrentBlock(
'next_locks_unchanged_modal');
2899 $this->tpl->setVariable(
'NEXT_LOCKS_UNCHANGED_MODAL', $this->ui_renderer->render($modal));
2900 $this->tpl->parseCurrentBlock();
2901 return $modal->getShowSignal();
2906 $empty_signal = new \ILIAS\UI\Implementation\Component\Signal(
'');
2908 return $empty_signal;
2911 $modal_message = $this->ui_factory->messageBox()->confirmation(
2912 $this->
lng->txt(
'tst_nav_next_locks_current_answer_confirm')
2914 $modal_checkbox = $this->ui_factory->input()->field()->checkbox(
2915 $this->
lng->txt(
'tst_dont_show_msg_again_in_current_session')
2916 )->withDedicatedName(self::FOLLOWUP_QST_LOCKS_PREVENT_CONFIRMATION_PARAM);
2918 $modal = $this->ui_factory->modal()->roundtrip(
2919 $this->
lng->txt(
'tst_nav_next_locks_current_answer_header'),
2921 [ $modal_checkbox ],
2922 'javascript:il.TestPlayerQuestionEditControl.confirmNextLocksChanged()' 2923 )->withSubmitLabel($this->
lng->txt(
'tst_proceed'));
2925 $this->tpl->setCurrentBlock(
'next_locks_changed_modal');
2926 $this->tpl->setVariable(
'NEXT_LOCKS_CHANGED_MODAL', $this->ui_renderer->render($modal));
2927 $this->tpl->parseCurrentBlock();
2928 return $modal->getShowSignal();
2935 ilSession::set(self::FOLLOWUP_QST_LOCKS_PREVENT_CONFIRMATION_PARAM,
true);
2940 if (
ilSession::get(self::FOLLOWUP_QST_LOCKS_PREVENT_CONFIRMATION_PARAM) == null) {
2944 return ilSession::get(self::FOLLOWUP_QST_LOCKS_PREVENT_CONFIRMATION_PARAM);
2950 $state = $question_gui->
getObject()->lookupForExistingSolutions($this->test_session->getActiveId(), $this->test_session->getPass());
2951 $config[
'isAnswered'] = $state[
'authorized'];
2956 $config[
'autosaveUrl'] =
'';
2957 $config[
'autosaveInterval'] = 0;
2960 $config[
'autosaveInterval'] = $this->
object->getMainSettings()->getQuestionBehaviourSettings()->getAutosaveInterval();
2963 $question_config = $question_gui->
getObject()->getTestPresentationConfig();
2965 $config[
'withFormChangeDetection'] = $question_config->isFormChangeDetectionEnabled();
2968 $config[
'withBackgroundChangeDetection'] = $question_config->isBackgroundChangeDetectionEnabled();
2972 $config[
'forcedInstantFeedback'] = $this->
object->isForceInstantFeedbackEnabled();
2974 $config[
'nextQuestionLocks'] = $this->
object->isFollowupQuestionAnswerFixationEnabled();
2975 $config[
'autosaveFailureMessage'] = $this->
lng->txt(
'autosave_failed');
2979 $config[
'preventConfirmationParam'] = self::FOLLOWUP_QST_LOCKS_PREVENT_CONFIRMATION_PARAM;
2981 $this->tpl->addJavascript(
'assets/js/ilTestPlayerQuestionEditControl.js');
2982 $this->tpl->addOnLoadCode(
'il.TestPlayerQuestionEditControl.init(' . json_encode($config) .
')');
2988 return self::PRESENTATION_MODE_EDIT;
2996 $forced_feeback_navigation_url =
ilSession::get(
'forced_feedback_navigation_url');
2997 $forced_feeback_navigation_url[$this->test_session->getActiveId()] = $forced_feedback_nav_url;
2998 ilSession::set(
'forced_feedback_navigation_url', $forced_feeback_navigation_url);
3006 $forced_feedback_navigation_url =
ilSession::get(
'forced_feedback_navigation_url');
3007 if (!isset($forced_feedback_navigation_url[$this->test_session->getActiveId()])) {
3011 return $forced_feedback_navigation_url[$this->test_session->getActiveId()];
3021 $forced_feedback_navigation_url =
ilSession::get(
'forced_feedback_navigation_url');
3022 if (isset($forced_feedback_navigation_url[$this->test_session->getActiveId()])) {
3023 unset($forced_feedback_navigation_url[$this->test_session->getActiveId()]);
3024 ilSession::set(
'forced_feedback_navigation_url', $forced_feedback_navigation_url);
3042 if ($sequence_element ===
false) {
3046 if ($sequence_element < 1) {
3050 if (!$this->test_sequence->getPositionOfSequence($sequence_element)) {
3059 if ($this->
object->isForceInstantFeedbackEnabled()) {
3065 $this->test_sequence->getQuestionForSequence(
3074 $next_sequence_element = $this->test_sequence->getFirstSequence();
3077 $this->test_session->setLastSequence($next_sequence_element ?? 0);
3078 $this->test_session->saveToDb();
3080 $this->
ctrl->setParameter($this,
'sequence', $next_sequence_element);
3081 $this->
ctrl->setParameter($this,
'pmode',
'');
3090 $this->test_sequence->postponeQuestion($question_id);
3091 $this->test_sequence->saveToDb();
3096 $testObj =
new ilObjTest($this->ref_id,
true);
3098 $participants = $testObj->getActiveParticipantList();
3099 $participant = $participants->getParticipantByActiveId($this->testrequest->getActiveId());
3100 if ($participant && $participant->hasUnfinishedPasses()) {
3103 $this->tpl->setOnScreenMessage(
'failure', $this->
lng->txt(
'tst_current_run_no_longer_valid'),
true);
3104 if ($with_redirect) {
3105 $this->
ctrl->redirectByClass([
3106 ilRepositoryGUI::class,
3107 ilObjTestGUI::class,
3108 TestScreenGUI::class
3115 if ($this->test_session->getActiveId() > 0) {
3116 if ($this->test_sequence->hasRandomQuestionsForPass($this->test_session->getActiveId(), $this->test_session->getPass()) > 0) {
3118 __METHOD__ .
' Random Questions allready exists for user ' .
3119 $this->
user->getId() .
' in test ' . $this->
object->getTestId()
3125 $this->
logger->info(__METHOD__ .
' ' . sprintf(
3126 $this->
lng->txt(
"error_random_question_generation"),
3127 $this->
user->getId(),
3128 $this->
object->getTestId()
3144 $this->component_repository,
3146 $this->questionrepository
3148 $questionSetConfig->loadFromDb();
3153 $sourcePoolDefinitionList->loadDefinitions();
3155 $this->process_locker->executeRandomPassBuildOperation(
function () use ($questionSetConfig, $sourcePoolDefinitionList) {
3165 $sourcePoolDefinitionList,
3166 $stagingPoolQuestionList
3169 $questionSetBuilder->performBuild($this->test_session);
3171 }, $sourcePoolDefinitionList->hasTaxonomyFilters());
3176 $ass_settings =
new ilSetting(
'assessment');
3179 $userSolutionAdopter->setUserId($this->
user->getId());
3180 $userSolutionAdopter->setActiveId($this->test_session->getActiveId());
3181 $userSolutionAdopter->setTargetPass($this->test_sequence->getPass());
3182 $userSolutionAdopter->setQuestionIds($this->test_sequence->getOptionalQuestions());
3184 $userSolutionAdopter->perform();
3189 $this->tpl->setOnScreenMessage(
'failure', sprintf($this->
lng->txt(
'tst_objective_oriented_test_pass_without_questions'), $this->
object->getTitle()),
true);
3190 $this->
ctrl->redirectByClass(ilObjTestGUI::class);
3195 $is_next_primary =
true;
3197 if ($this->
object->isForceInstantFeedbackEnabled()) {
3198 $is_next_primary =
false;
3201 $questions_missing_result = $this->questionrepository->getQuestionsMissingResultRecord(
3202 $this->test_session->getActiveId(),
3203 $this->test_session->getPass(),
3204 $this->test_sequence->getOrderedSequenceQuestions()
3207 if ($questions_missing_result === []) {
3212 if (count($questions_missing_result) === 1
3213 && $current_question_id === current($questions_missing_result)) {
3218 return $is_next_primary;
3223 $title_content = $this->ui_factory->listing()->property();
3225 if ($this->
object->getShowKioskModeParticipant()) {
3226 $pax_name_label = $this->
lng->txt(
"conf_user_name");
3230 $pax_name_value =
"<span class='il-test-kiosk-head__participant-name'>" 3231 . $this->
user->getFullname() .
"</span>";
3232 $title_content = $title_content->withProperty($pax_name_label, $pax_name_value,
false);
3235 if ($this->
object->isShowExamIdInTestPassEnabled()) {
3236 $exam_id_label = $this->
lng->txt(
"exam_id_label");
3238 $this->test_session->getActiveId(),
3239 $this->test_session->getPass(),
3240 $this->
object->getId()
3242 $title_content = $title_content->withProperty($exam_id_label, $exam_id_value);
3245 if ($this->
object->getShowKioskModeTitle()) {
3246 $test_title_label = $this->
lng->txt(
"test");
3247 $test_title_value = $this->
object->getTitle();
3248 $title_content = $title_content->withProperty($test_title_label, $test_title_value,
false);
3251 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)
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false, ilObjUser $user=null,)
const AFTER_TEST_PASS_FINISHED
populateDiscardSolutionModal()
removeIntermediateSolution()
const CMD_CONFIRM_REQUEST
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.
const SHOW_REQUESTED_HINTS_LIST
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()
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()
setVariable(string $variable, $value='')
Sets the given variable to the given value.
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.
afterTestPassFinishedCmd()
getContentBlockName()
Returns the name of the current content block (depends on the kiosk mode setting) ...
populateQuestionOptionalMessage()
confirmHintRequestCmd()
Go to hint request confirmation.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
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.
showRequestedHintListCmd()
Go to requested hint list.
ilTestSession $test_session
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.
const CONFIRM_HINT_REQUEST
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()
getCorrectSolutionOutput($question_id, $active_id, $pass, ilTestQuestionRelatedObjectivesList $objectives_list=null)
Returns an output of the solution to an answer compared to the correct solution.
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)
static initjQuery(ilGlobalTemplateInterface $a_tpl=null)
inits and adds the jQuery JS-File to the global or a passed template
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
__construct(Container $dic, ilPlugin $plugin)
const TEST_PLAYER_SHORT_TITLE
populateMessageContent(string $content_html)
getNextSequenceParameter()
determineInlineScoreDisplay()
getTestPresentationConfig()
getNavigationUrlParameter()
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)