19 declare(strict_types=1);
24 require_once
'./Modules/Test/classes/inc.AssessmentConstants.php';
62 $this->ref_id = $this->testrequest->getRefId();
68 if (!$this->rbac_system->checkAccess(
'read', $this->object->getRefId())) {
69 return $this->
lng->txt(
'cannot_execute_test');
73 return $this->
lng->txt(
'user_wrong_clientip');
81 $executable = $this->
object->isExecutable($this->test_session, $this->test_session->getUserId());
83 if (!$executable[
'executable']) {
84 $this->tpl->setOnScreenMessage(
'info', $executable[
'errormessage'],
true);
92 throw new ilTestException(
'active id given does not relate to current user!');
119 $this->processLocker = $processLockerFactory->withContextId((
int) $activeId)->getLocker();
131 $tagging_gui->setObject($this->
object->getId(), $this->
object->getType());
132 $tagging_gui->saveInput();
133 $this->
ctrl->redirectByClass(
"ilobjtestgui",
"infoScreen");
142 $this->
object->updateWorkingTime(
ilSession::get(
"active_time_id"));
147 $this->
object->startWorkingTime(
148 $this->test_session->getActiveId(),
149 $this->test_session->getPass()
159 $this->test_session->getActiveId(),
160 $this->test_session->getPass()
178 $active_id = $this->test_session->getActiveId();
179 $starting_time = $this->
object->getStartingTimeOfUser($active_id);
180 if ($starting_time ===
false) {
183 return $this->
object->isMaxProcessingTimeReached($starting_time, $active_id);
189 $show_question_inline_score =
false;
190 if ($this->
object->getAnswerFeedbackPoints()) {
191 $show_question_inline_score =
true;
192 return $show_question_inline_score;
194 return $show_question_inline_score;
199 $this->tpl->setCurrentBlock(
'test_nav_toolbar');
200 $this->tpl->setVariable(
'TEST_NAV_TOOLBAR', $toolbar_gui->getHTML());
201 $this->tpl->parseCurrentBlock();
203 if ($this->finish_test_modal === null) {
207 $this->tpl->setCurrentBlock(
'finish_test_modal');
208 $this->tpl->setVariable(
210 $this->ui_renderer->render(
211 $this->finish_test_modal->withOnLoad($this->finish_test_modal->getShowSignal())
214 $this->tpl->parseCurrentBlock();
244 $this->tpl->setCurrentBlock(
"next_bottom");
245 $this->tpl->setVariable(
"BTN_NEXT_BOTTOM", $this->ui_renderer->render($button));
246 $this->tpl->parseCurrentBlock();
253 $this->tpl->setCurrentBlock(
"next");
254 $this->tpl->setVariable(
"BTN_NEXT", $this->ui_renderer->render($button));
255 $this->tpl->parseCurrentBlock();
262 $this->tpl->setCurrentBlock(
"prev_bottom");
263 $this->tpl->setVariable(
"BTN_PREV_BOTTOM", $this->ui_renderer->render($button));
264 $this->tpl->parseCurrentBlock();
271 $this->tpl->setCurrentBlock(
"prev");
272 $this->tpl->setVariable(
"BTN_PREV", $this->ui_renderer->render($button));
273 $this->tpl->parseCurrentBlock();
284 $button = $this->ui_factory->button()->primary(
285 $this->
lng->txt(
'next_question') .
'<span class="glyphicon glyphicon-arrow-right"></span> ',
287 )->withUnavailableAction(
true)
290 $button = $this->ui_factory->button()->standard(
291 $this->
lng->txt(
'next_question') .
'<span class="glyphicon glyphicon-arrow-right"></span> ',
293 )->withUnavailableAction(
true)
306 $button = $this->ui_factory->button()->standard(
307 '<span class="glyphicon glyphicon-arrow-left"></span> ' . $this->
lng->txt(
'previous_question'),
309 )->withUnavailableAction(
true)
316 return static function (
string $id) use ($target, $cmd):
string {
317 return "document.getElementById('{$id}').addEventListener('click', " 318 .
"(e) => {il.TestPlayerQuestionEditControl.checkNavigation('{$target}', '{$cmd}', e);}" 320 .
"document.getElementById('{$id}').removeAttribute('disabled');";
329 $solutionValues = $question_gui->object->getSolutionValues(
330 $this->test_session->getActiveId(),
335 $question_gui->object->fetchIndexedValuesFromValuePairs($solutionValues)
338 if (!empty($feedback)) {
339 $this->tpl->setCurrentBlock(
"specific_feedback");
340 $this->tpl->setVariable(
"SPECIFIC_FEEDBACK", $feedback);
341 $this->tpl->parseCurrentBlock();
353 $feedback = $question_gui->
getGenericFeedbackOutput($this->test_session->getActiveId(), $this->test_session->getPass());
355 if (strlen($feedback)) {
361 $this->tpl->setCurrentBlock(
"answer_feedback");
362 $this->tpl->setVariable(
"ANSWER_FEEDBACK", $feedback);
363 $this->tpl->setVariable(
"ILC_FB_CSS_CLASS", $cssClass);
364 $this->tpl->parseCurrentBlock();
372 $scoreInformation = sprintf(
373 $this->
lng->txt(
"you_received_a_of_b_points"),
378 $this->tpl->setCurrentBlock(
"received_points_information");
379 $this->tpl->setVariable(
"RECEIVED_POINTS_INFORMATION", $scoreInformation);
380 $this->tpl->parseCurrentBlock();
385 if (strlen($solutionoutput)) {
386 $this->tpl->setCurrentBlock(
"solution_output");
387 $this->tpl->setVariable(
"CORRECT_SOLUTION", $this->
lng->txt(
"tst_best_solution_is"));
388 $this->tpl->setVariable(
"QUESTION_FEEDBACK", $solutionoutput);
389 $this->tpl->parseCurrentBlock();
395 $this->tpl->setCurrentBlock(
"SyntaxStyle");
396 $this->tpl->setVariable(
397 "LOCATION_SYNTAX_STYLESHEET",
400 $this->tpl->parseCurrentBlock();
405 $this->tpl->setCurrentBlock(
"ContentStyle");
406 $this->tpl->setVariable(
407 "LOCATION_CONTENT_STYLESHEET",
410 $this->tpl->parseCurrentBlock();
420 if ($this->test_session->isAnonymousUser()) {
421 $this->test_session->setAccessCodeToSession($_POST[
'anonymous_id']);
424 $this->
ctrl->redirectByClass(
"ilobjtestgui",
"infoScreen");
436 $isFirstTestStartRequest =
false;
438 $this->processLocker->executeTestStartLockOperation(
function () use ($testStartLock, &$isFirstTestStartRequest) {
439 if ($this->test_session->lookupTestStartLock() !== $testStartLock) {
440 $this->test_session->persistTestStartLock($testStartLock);
441 $isFirstTestStartRequest =
true;
445 if ($isFirstTestStartRequest) {
450 $this->
ctrl->setParameterByClass(
'ilObjTestGUI',
'lock', $testStartLock);
451 $this->
ctrl->redirectByClass(
"ilobjtestgui",
"redirectToInfoScreen");
456 if ($this->testrequest->isset(
'lock') && strlen($this->testrequest->raw(
'lock'))) {
457 return $this->testrequest->raw(
'lock');
473 if ($this->test_session->isAnonymousUser()
474 && !$this->test_session->doesAccessCodeInSessionExists()) {
475 $accessCode = $this->test_session->createNewAccessCode();
477 $this->test_session->setAccessCodeToSession($accessCode);
478 $this->test_session->setAnonymousId($accessCode);
479 $this->test_session->saveToDb();
484 if (!$this->test_session->isAnonymousUser()) {
485 $this->test_session->unsetAccessCodeInSession();
492 $this->tpl->addBlockFile($this->
getContentBlockName(),
"adm_content",
"tpl.il_as_tst_anonymous_code_presentation.html",
"Modules/Test");
493 $this->tpl->setCurrentBlock(
"adm_content");
494 $this->tpl->setVariable(
"TEXT_ANONYMOUS_CODE_CREATED", $this->
lng->txt(
"tst_access_code_created"));
495 $this->tpl->setVariable(
"TEXT_ANONYMOUS_CODE", $this->test_session->getAccessCodeFromSession());
496 $this->tpl->setVariable(
"FORMACTION", $this->
ctrl->getFormAction($this));
498 $this->tpl->setVariable(
"TXT_CONFIRM", $this->
lng->txt(
"continue_work"));
499 $this->tpl->parseCurrentBlock();
512 if ($this->
object->getNrOfTries() != 1
513 && $this->
object->getUsePreviousAnswers() == 1
515 $chb_use_previous_answers = 0;
516 if ($this->post_wrapper->has(
'chb_use_previous_answers')) {
517 $chb_use_previous_answers = $this->post_wrapper->retrieve(
518 'chb_use_previous_answers',
522 $this->
user->writePref(
"tst_use_previous_answers", (
string) $chb_use_previous_answers);
546 $this->tpl->addBlockFile($this->
getContentBlockName(),
"adm_content",
"tpl.il_as_tst_redirect_autosave.html",
"Modules/Test");
547 $this->tpl->setVariable(
"TEXT_REDIRECT", $this->
lng->txt(
"redirectAfterSave"));
548 $this->tpl->setVariable(
"URL",
$url);
559 if (!$this->
access->checkAccess(
'read',
'', $this->ref_id)) {
560 echo $this->
lng->txt(
'autosave_failed') .
': ' . $this->
lng->txt(
'msg_no_perm_read_item');
563 $test_can_run = $this->
object->isExecutable($this->test_session, $this->test_session->getUserId());
564 if (!$test_can_run[
'executable']) {
565 echo $test_can_run[
'errormessage'];
568 if (!is_countable($_POST) || count($_POST) === 0) {
582 echo $this->
lng->txt(
"autosave_success");
586 echo $this->
lng->txt(
"autosave_failed");
613 $this->test_session->getActiveId(),
614 $this->test_session->getPass()
617 $result[
'isAnswered'] = $state[
'authorized'];
618 $result[
'isAnswerChanged'] = $state[
'intermediate'];
620 echo json_encode($result);
645 $questionId = $this->testSequence->getQuestionForSequence(
649 $this->
object->setQuestionSetSolved(1, $questionId, $this->test_session->getUserId());
667 $questionId = $this->testSequence->getQuestionForSequence(
671 $this->
object->setQuestionSetSolved(0, $questionId, $this->test_session->getUserId());
678 $this->handleCheckTestPassValid();
681 $all_obligations_answered = $this->
object->allObligationsAnswered();
695 if ($this->
object->areObligationsEnabled() && !$all_obligations_answered) {
696 if ($this->
object->getListOfQuestions()) {
705 if ($this->testrequest->strVal(
'finalization_confirmed') !==
'confirmed') {
723 (
new ilTestPassFinishTasks($this->test_session, $this->
object))->performFinishTasks($this->processLocker);
726 $this->test_session->getActiveId(),
727 $this->test_session->getPass()
733 $notification_type = $this->
object->getMainSettings()->getFinishingSettings()->getMailNotificationContentType();
735 if ($notification_type === 0
736 || !$this->
object->getMainSettings()->getFinishingSettings()->getAlwaysSendMailNotification()
737 && $pass !== $this->
object->getNrOfTries() - 1) {
741 switch ($this->
object->getMainSettings()->getFinishingSettings()->getMailNotificationContentType()) {
743 $this->
object->sendSimpleNotification($active_id);
746 $this->
object->sendAdvancedNotification($active_id);
754 if (!$this->testrequest->isset(
'skipfinalstatement')) {
755 if ($this->
object->getMainSettings()->getFinishingSettings()->getConcludingRemarksEnabled()) {
761 $redirection_url = $this->
object->getMainSettings()->getFinishingSettings()->getRedirectionUrl();
762 if (!empty($redirection_url)
763 && !$this->
object->canShowTestResults($this->test_session)
765 if ($this->
object->isRedirectModeKiosk()) {
766 if ($this->
object->getKioskMode()) {
780 $class = get_class($this);
781 $this->
ctrl->setParameterByClass($class,
'finalization_confirmed',
'confirmed');
783 $this->
ctrl->clearParameterByClass($class,
'finalization_confirmed');
785 $message = $this->
lng->txt(
'tst_finish_confirmation_question');
786 if (($this->
object->getNrOfTries() - 1) === $this->test_session->getPass()) {
787 $message = $this->
lng->txt(
'tst_finish_confirmation_question_no_attempts_left');
790 return $this->ui_factory->modal()->interruptive(
791 $this->
lng->txt(
'finish_test'),
794 )->withActionButtonLabel($this->
lng->txt(
'tst_finish_confirm_button'));
800 $testPassesSelector->setActiveId($this->test_session->getActiveId());
801 $testPassesSelector->setLastFinishedPass($this->test_session->getLastFinishedPass());
803 if (count($testPassesSelector->getReportablePasses())) {
805 $this->
ctrl->redirectByClass([
'ilTestResultsGUI',
'ilTestEvalObjectiveOrientedGUI']);
808 $this->
ctrl->redirectByClass([
'ilTestResultsGUI',
'ilMyTestResultsGUI',
'ilTestEvaluationGUI']);
819 $this->global_screen->tool()->context()->current()->getAdditionalData()->replace(
821 $this->
object->getTitle() .
' - ' . $this->
lng->txt(
'final_statement')
823 $this->content_style->gui()->addCss($this->tpl, $this->ref_id);
824 $this->
ctrl->setParameterByClass(ilTestPageGUI::class,
'page_type',
'concludingremarkspage');
825 $template =
new ilTemplate(
"tpl.il_as_tst_final_statement.html",
true,
true,
"Modules/Test");
826 $this->
ctrl->setParameter($this,
"skipfinalstatement", 1);
828 $template->setVariable(
"FINALSTATEMENT", $this->
object->getFinalStatement());
829 $template->setVariable(
"BUTTON_CONTINUE", $this->
lng->txt(
"btn_next"));
835 $this->navigation_history->addItem(
836 $this->test_session->getRefId(),
850 if ($this->
object->endingTimeReached()) {
856 $this->
ctrl->setParameter($this,
"sequence", $sequenceElement);
861 $this->tpl->setVariable(
"TEST_ID", (
string) $this->
object->getTestId());
862 $this->tpl->setVariable(
"LOGIN", $this->
user->getLogin());
864 $this->tpl->setVariable(
"SEQ_ID", $sequenceElement);
865 $this->tpl->setVariable(
"QUEST_ID", $questionId);
867 if ($this->
object->getEnableProcessingTime()) {
871 $this->tpl->setVariable(
"PAGETITLE",
"- " . $this->
object->getTitle());
873 if ($this->
object->isShowExamIdInTestPassEnabled() && !$this->
object->getKioskMode()) {
874 $this->tpl->setCurrentBlock(
'exam_id_footer');
876 $this->test_session->getActiveId(),
877 $this->test_session->getPass(),
878 $this->
object->getId()
880 $this->tpl->setVariable(
'EXAM_ID_TXT', $this->
lng->txt(
'exam_id'));
881 $this->tpl->parseCurrentBlock();
884 if ($this->
object->getListOfQuestions()) {
896 $questionNavigationGUI->setQuestionWorkedThrough($isQuestionWorkedThrough);
903 $answerFeedbackEnabled = (
904 $instantResponse && $this->
object->getSpecificAnswerFeedback()
908 $this->test_session->getActiveId(), #active_id
909 $this->test_session->getPass(), #pass
910 false, #graphical_output
911 false, #result_output
912 true, #show_question_only
913 $answerFeedbackEnabled, #show_feedback
914 false, #show_correct_solution
915 false, #show_manual_scoring
916 true #show_question_text
922 $this->test_session->getActiveId(),
926 $this->tpl->setVariable(
928 $this->ui_renderer->render(
929 $this->ui_factory->messageBox()->info($this->
lng->txt(
"tst_player_answer_saved_and_locked"))
932 $this->tpl->parseCurrentBlock();
934 $this->tpl->setVariable(
'QUESTION_OUTPUT', $pageoutput);
936 $this->tpl->setVariable(
"FORMACTION", $formAction);
937 $this->tpl->setVariable(
"ENCTYPE",
'enctype="' . $questionGui->
getFormEncodingType() .
'"');
938 $this->tpl->setVariable(
"FORM_TIMESTAMP", time());
939 $this->populateQuestionEditControl($questionGui);
945 if ($isQuestionWorkedThrough) {
946 $questionNavigationGUI->setDiscardSolutionButtonEnabled(
true);
950 } elseif ($this->
object->isPostponingEnabled()) {
951 $questionNavigationGUI->setSkipQuestionLinkTarget(
959 $answerFeedbackEnabled = (
960 $instantResponse && $this->
object->getSpecificAnswerFeedback()
963 if ($this->testrequest->isset(
'save_error') && $this->testrequest->raw(
'save_error') == 1 &&
ilSession::get(
'previouspost') != null) {
967 $userPostSolution =
false;
975 $qstConfig = $questionGui->object->getTestPresentationConfig();
978 $qstConfig->setWorkedThrough($isQuestionWorkedThrough);
981 if ($qstConfig->isPreviousPassSolutionReuseAllowed()) {
983 if ($passIndex < $this->test_session->getPass()) {
984 $qstConfig->setSolutionInitiallyPrefilled(
true);
987 $passIndex = $this->test_session->getPass();
994 $formAction, #form_action
995 $this->test_session->getActiveId(), #active_id
999 $isPostponed, #is_postponed
1000 $userPostSolution, #user_post_solution
1001 $answerFeedbackEnabled #answer_feedback == inline_specific_feedback
1012 $this->populateQuestionEditControl($questionGui);
1019 if ($this->
object->isPreviousSolutionReuseEnabled($this->test_session->getActiveId())) {
1020 $currentSolutionAvailable = $questionGui->object->authorizedOrIntermediateSolutionExists(
1021 $this->test_session->getActiveId(),
1022 $this->test_session->getPass()
1025 if (!$currentSolutionAvailable) {
1026 $previousPass = $questionGui->object->getSolutionMaxPass(
1027 $this->test_session->getActiveId()
1030 $previousSolutionAvailable = $questionGui->object->authorizedSolutionExists(
1031 $this->test_session->getActiveId(),
1035 if ($previousSolutionAvailable) {
1036 return $previousPass;
1042 return $this->test_session->getPass();
1057 $this->
ctrl->saveParameter($this,
'sequence');
1070 $user_filtered_for_invitation = $this->
object->getInvitedUsers($this->
user->getId());
1071 if ($user_filtered_for_invitation === []) {
1072 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'user_not_invited'),
true);
1073 $this->
ctrl->redirectByClass(
'ilobjtestgui',
'backToRepository');
1076 $client_ip = $user_filtered_for_invitation[
'client_ip'];
1077 if ($client_ip !==
'' 1078 && $client_ip !==
$_SERVER[
'REMOTE_ADDR']) {
1079 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'user_wrong_clientip'),
true);
1080 $this->
ctrl->redirectByClass(
'ilobjtestgui',
'backToRepository');
1092 and $this->
object->startingTimeReached()
1093 and !$this->
object->endingTimeReached();
1101 return $this->
object->hasNrOfTriesRestriction() && $this->
object->isNrOfTriesReached($this->test_session->getPass());
1112 $this->test_session->increasePass();
1113 $this->test_session->setLastSequence(0);
1114 $this->test_session->saveToDb();
1138 $this->tpl->addBlockFile($this->
getContentBlockName(),
"adm_content",
"tpl.il_as_tst_submit_answers_confirm.html",
"Modules/Test");
1139 $this->tpl->setCurrentBlock(
"adm_content");
1140 if ($this->
object->isTestFinished($this->test_session->getActiveId())) {
1141 $this->tpl->setCurrentBlock(
"not_submit_allowed");
1142 $this->tpl->setVariable(
"TEXT_ALREADY_SUBMITTED", $this->
lng->txt(
"tst_already_submitted"));
1143 $this->tpl->setVariable(
"BTN_OK", $this->
lng->txt(
"tst_show_answer_sheet"));
1145 $this->tpl->setCurrentBlock(
"submit_allowed");
1146 $this->tpl->setVariable(
"TEXT_CONFIRM_SUBMIT_RESULTS", $this->
lng->txt(
"tst_confirm_submit_answers"));
1147 $this->tpl->setVariable(
"BTN_OK", $this->
lng->txt(
"tst_submit_results"));
1149 $this->tpl->setVariable(
"BTN_BACK", $this->
lng->txt(
"back"));
1150 $this->tpl->setVariable(
"FORMACTION", $this->
ctrl->getFormAction($this,
"finalSubmission"));
1151 $this->tpl->parseCurrentBlock();
1156 $starting_time = $this->
object->getStartingTimeOfUser($active_id);
1162 $this->
object->getProcessingTimeInSeconds($active_id)
1165 $this->tpl->setCurrentBlock(
'enableprocessingtime');
1166 $this->tpl->setVariable(
'USER_WORKING_TIME_MESSAGE_BOX', $working_time->getMessageBox($verbose));
1167 $this->tpl->parseCurrentBlock();
1171 getdate($starting_time),
1172 $this->
ctrl->getLinkTarget($this,
'checkWorkingTime',
'',
true),
1176 $this->tpl->addOnLoadCode($working_time_js_template->get());
1188 $active_id = $this->test_session->getActiveId();
1189 echo (
string) $this->
object->getProcessingTimeInSeconds($active_id);
1195 $question_summary_data = $this->service->getQuestionSummaryData($this->testSequence,
false);
1199 foreach ($question_summary_data as $idx => $row) {
1200 $title = htmlspecialchars($row[
'title'], ENT_QUOTES, null,
false);
1202 if ($row[
'description'] !==
'') {
1203 $description = htmlspecialchars($row[
'description'], ENT_QUOTES, null,
false);
1206 if (!$row[
'disabled']) {
1207 $this->
ctrl->setParameter($this,
'pmode',
'');
1208 $this->
ctrl->setParameter($this,
'sequence', $row[
'sequence']);
1217 ($row[
'worked_through'] || $row[
'isAnswered'])
1218 && $row[
'has_authorized_answer']
1223 $questions[] = $this->ui_factory->listing()->workflow()
1224 ->step($title, $description, $action)
1225 ->withStatus($status);
1226 $active = $row[
'sequence'] == $current_sequence_element ? $idx : $active;
1229 $question_listing = $this->ui_factory->listing()->workflow()->linear(
1230 $this->
lng->txt(
'mainbar_button_label_questionlist'),
1232 )->withActive($active);
1235 $this->global_screen->tool()->context()->current()->addAdditionalData(
1247 bool $obligations_info =
false,
1248 bool $obligations_filter =
false 1250 $this->
help->setScreenIdComponent(
"tst");
1251 $this->
help->setScreenId(
"assessment");
1252 $this->
help->setSubScreenId(
"question_summary");
1254 $this->tpl->addBlockFile($this->
getContentBlockName(),
"adm_content",
"tpl.il_as_tst_question_summary.html",
"Modules/Test");
1256 $this->global_screen->tool()->context()->current()->getAdditionalData()->replace(
1258 $this->
getObject()->getTitle() .
' - ' . $this->
lng->txt(
'question_summary')
1261 if ($obligations_info
1262 && $this->
object->areObligationsEnabled()
1263 && !$this->
object->allObligationsAnswered()) {
1264 $this->tpl->setOnScreenMessage(
'failure', $this->
lng->txt(
'not_all_obligations_answered'));
1267 $active_id = $this->test_session->getActiveId();
1268 $question_summary_data = $this->service->getQuestionSummaryData($this->testSequence, $obligations_filter);
1270 $this->
ctrl->setParameter($this,
"sequence", $this->testrequest->raw(
"sequence"));
1278 if (($this->
object->getNrOfTries() - 1) === $this->test_session->getPass()) {
1279 $table_gui->setUserHasAttemptsLeft(
false);
1281 $table_gui->setShowPointsEnabled(!$this->
object->getTitleOutput());
1282 $table_gui->setShowMarkerEnabled($this->
object->getShowMarker());
1283 $table_gui->setObligationsNotAnswered(!$this->
object->allObligationsAnswered());
1284 $table_gui->setShowObligationsEnabled($this->
object->areObligationsEnabled());
1285 $table_gui->setObligationsFilterEnabled($obligations_filter);
1290 $table_gui->setData($question_summary_data);
1292 $this->tpl->setVariable(
'TABLE_LIST_OF_QUESTIONS', $table_gui->getHTML());
1294 if ($this->
object->getEnableProcessingTime()) {
1298 if ($this->
object->isShowExamIdInTestPassEnabled()) {
1299 $this->tpl->setCurrentBlock(
'exam_id_footer');
1301 $this->test_session->getActiveId(),
1302 $this->test_session->getPass(),
1303 $this->
object->getId()
1305 $this->tpl->setVariable(
'EXAM_ID_TXT', $this->
lng->txt(
'exam_id'));
1306 $this->tpl->parseCurrentBlock();
1330 $this->tpl->addBlockFile(
"ADM_CONTENT",
"adm_content",
"tpl.il_as_tst_correct_solution.html",
"Modules/Test");
1332 $this->tpl->setCurrentBlock(
"ContentStyle");
1334 $this->tpl->parseCurrentBlock();
1336 $this->tpl->setCurrentBlock(
"SyntaxStyle");
1338 $this->tpl->parseCurrentBlock();
1341 if ($this->
object->getShowSolutionAnswersOnly()) {
1345 $this->tpl->setCurrentBlock(
"adm_content");
1346 $solution = $this->
getCorrectSolutionOutput($this->testrequest->raw(
"evaluation"), $this->testrequest->raw(
"active_id"), $this->testrequest->raw(
"pass"));
1347 $this->tpl->setVariable(
"OUTPUT_SOLUTION", $solution);
1348 $this->tpl->setVariable(
"TEXT_BACK", $this->
lng->txt(
"back"));
1349 $this->
ctrl->saveParameter($this,
"pass");
1350 $this->
ctrl->saveParameter($this,
"active_id");
1351 $this->tpl->setVariable(
"URL_BACK", $this->
ctrl->getLinkTarget($this,
"outUserResultsOverview"));
1352 $this->tpl->parseCurrentBlock();
1366 $this->tpl->addBlockFile($this->
getContentBlockName(),
"adm_content",
"tpl.il_as_tst_finish_list_of_answers.html",
"Modules/Test");
1368 $result_array = &$this->
object->getTestResult(
1377 foreach ($result_array as $question_data) {
1378 $question = $question_data[
"qid"];
1379 if (is_numeric($question)) {
1380 $this->tpl->setCurrentBlock(
"printview_question");
1381 $question_gui = $this->
object->createQuestionGUI(
"", $question);
1382 $template =
new ilTemplate(
"tpl.il_as_qpl_question_printview.html",
true,
true,
"Modules/TestQuestionPool");
1383 $template->setVariable(
"COUNTER_QUESTION", $counter .
". ");
1384 $template->setVariable(
"QUESTION_TITLE", $question_gui->object->getTitleForHTMLOutput());
1386 $show_question_only = ($this->
object->getShowSolutionAnswersOnly()) ?
true :
false;
1387 $result_output = $question_gui->getSolutionOutput(
1392 $show_question_only,
1393 $this->
object->getShowSolutionFeedback()
1395 $template->setVariable(
"SOLUTION_OUTPUT", $result_output);
1396 $this->tpl->setVariable(
"QUESTION_OUTPUT", $template->get());
1397 $this->tpl->parseCurrentBlock();
1403 if ($this->
object->getShowSolutionAnswersOnly()) {
1406 if (strlen($top_data)) {
1407 $this->tpl->setCurrentBlock(
"top_data");
1408 $this->tpl->setVariable(
"TOP_DATA", $top_data);
1409 $this->tpl->parseCurrentBlock();
1412 if (strlen($bottom_data)) {
1413 $this->tpl->setCurrentBlock(
"bottom_data");
1414 $this->tpl->setVariable(
"FORMACTION", $this->
ctrl->getFormAction($this));
1415 $this->tpl->setVariable(
"BOTTOM_DATA", $bottom_data);
1416 $this->tpl->parseCurrentBlock();
1419 $this->tpl->setCurrentBlock(
"adm_content");
1420 $this->tpl->setVariable(
"TXT_ANSWER_SHEET", $this->
lng->txt(
"tst_list_of_answers"));
1423 $this->tpl->setVariable(
"USER_DETAILS", $user_data);
1424 $this->tpl->setVariable(
"SIGNATURE", $signature);
1425 $this->tpl->setVariable(
"TITLE", $this->
object->getTitle());
1426 $this->tpl->setVariable(
"TXT_TEST_PROLOG", $this->
lng->txt(
"tst_your_answers"));
1427 $invited_user = &$this->
object->getInvitedUsers($this->
user->getId());
1428 $pagetitle = $this->
object->getTitle() .
" - " . $this->
lng->txt(
"clientip") .
1429 ": " . $invited_user[$this->
user->getId()][
"clientip"] .
" - " .
1430 $this->
lng->txt(
"matriculation") .
": " .
1431 $invited_user[$this->
user->getId()][
"matriculation"];
1432 $this->tpl->setVariable(
"PAGETITLE", $pagetitle);
1433 $this->tpl->parseCurrentBlock();
1443 return "ADM_CONTENT";
1445 if ($this->
object->getKioskMode()) {
1446 $this->tpl->setBodyClass(
"kiosk");
1447 $this->tpl->hideFooter();
1450 return "ADM_CONTENT";
1456 $this->
ctrl->redirectByClass(
1457 [
'ilRepositoryGUI',
'ilObjTestGUI',
'ilTestEvaluationGUI'],
1458 "outUserResultsOverview" 1471 $this->
ctrl->setParameter($this,
'pmode', self::PRESENTATION_MODE_EDIT);
1485 $this->
ctrl->setParameter($this,
'pmode', self::PRESENTATION_MODE_EDIT);
1505 $this->tpl->addBlockFile(
1508 'tpl.il_as_tst_question_summary.html',
1516 let key_event = (
event) => {
1517 if(
event.key === 13 &&
event.target.tagName.toLowerCase() ===
"a" ) {
1520 if (
event.key === 13 &&
1521 event.target.tagName.toLowerCase() !==
"textarea" &&
1522 (
event.target.tagName.toLowerCase() !==
"input" ||
event.target.type.toLowerCase() !==
"submit")) {
1523 event.preventDefault();
1527 let
form = document.getElementById(
'taForm');
1528 form.onkeyup = key_event;
1529 form.onkeydown = key_event;
1530 form.onkeypress = key_event;
1532 $this->tpl->addOnLoadCode($onload_js);
1533 $this->tpl->addBlockFile(
1536 'tpl.il_as_tst_output.html',
1549 if ($this->test_session->isPasswordChecked() ===
true) {
1553 if ($this->
ctrl->getNextClass() ===
'iltestpasswordprotectiongui') {
1557 if (!$this->passwordChecker->isPasswordProtectionPageRedirectRequired()) {
1558 $this->test_session->setPasswordChecked(
true);
1565 $this->
ctrl->setParameterByClass(ilTestPasswordProtectionGUI::class,
'nextCommand', $next_command);
1566 $this->
ctrl->redirectByClass(ilTestPasswordProtectionGUI::class,
'showPasswordForm');
1571 if ($this->
object->isInstantFeedbackAnswerFixationEnabled() && $this->testSequence->isQuestionChecked($questionId)) {
1575 if ($this->
object->isFollowupQuestionAnswerFixationEnabled() && $this->testSequence->isNextQuestionPresented($questionId)) {
1587 return $this->
lng->txt(
"save_introduction");
1592 $this->assSettings =
new ilSetting(
'assessment');
1601 $questionList->load();
1603 $testResults = $this->
object->getTestResult($test_session->
getActiveId(), $test_session->
getPass(),
true);
1607 $this->logging_services,
1608 $this->
object->getTestId(),
1609 $this->
object->getRefId(),
1610 $this->skills_service->profile(),
1611 $this->skills_service->personal()
1615 $skillEvaluation->setActiveId($test_session->
getActiveId());
1616 $skillEvaluation->setPass($test_session->
getPass());
1618 $skillEvaluation->setNumRequiredBookingsForSkillTriggering((
int) $this->assSettings->get(
1619 'ass_skl_trig_num_answ_barrier',
1624 $skillEvaluation->init($questionList);
1625 $skillEvaluation->evaluate($testResults);
1627 $skillEvaluation->handleSkillTriggering();
1636 $confirmation->setFormAction($this->
ctrl->getFormAction($this));
1637 $confirmation->setCancelCmd(
'cancelAnswerOptionalQuestions');
1638 $confirmation->setConfirmCmd(
'confirmAnswerOptionalQuestions');
1640 $confirmation->build($this->
object->isFixedTest());
1647 $this->testSequence->setAnsweringOptionalQuestionsConfirmed(
true);
1648 $this->testSequence->saveToDb();
1650 $this->
ctrl->setParameter($this,
'activecommand',
'gotoquestion');
1651 $this->
ctrl->redirect($this,
'redirectQuestion');
1656 if ($this->
object->getListOfQuestions()) {
1657 $this->
ctrl->setParameter($this,
'activecommand',
'summary');
1659 $this->
ctrl->setParameter($this,
'activecommand',
'previous');
1662 $this->
ctrl->redirect($this,
'redirectQuestion');
1670 if ($this->
object->getKioskMode()) {
1672 $this->tpl->hideFooter();
1673 $this->tpl->addBlockfile(
'CONTENT',
'adm_content',
"tpl.il_as_tst_kiosk_mode_content.html",
"Modules/Test");
1674 $this->tpl->setContent($this->
ctrl->getHTML($helperGui));
1683 $navigation_toolbar->setSuspendTestButtonEnabled($this->
object->getShowCancel());
1684 $navigation_toolbar->setUserPassOverviewEnabled($this->
object->getUsrPassOverviewEnabled());
1686 return $navigation_toolbar;
1701 if ($this->
object->getShowMarker()) {
1705 if (count($solved_array) > 0) {
1706 $solved = array_pop($solved_array);
1707 $solved = $solved[
"solved"];
1712 $navigationGUI->setQuestionMarked(
true);
1715 $navigationGUI->setQuestionMarked(
false);
1720 return $navigationGUI;
1731 if ($this->
object->isForceInstantFeedbackEnabled()) {
1746 case $this->
object->getSpecificAnswerFeedback():
1747 case $this->
object->getGenericAnswerFeedback():
1748 case $this->
object->getAnswerFeedbackPoints():
1749 case $this->
object->getInstantFeedbackSolution():
1751 $navigationGUI->setAnswerFreezingEnabled($this->
object->isInstantFeedbackAnswerFixationEnabled());
1753 if ($this->
object->isForceInstantFeedbackEnabled()) {
1754 $navigationGUI->setForceInstantResponseEnabled(
true);
1762 if ($this->
object->isOfferingQuestionHintsEnabled()) {
1763 $activeId = $this->test_session->getActiveId();
1764 $pass = $this->test_session->getPass();
1768 if ($questionHintTracking->requestsPossible()) {
1772 if ($questionHintTracking->requestsExist()) {
1777 if ($this->
object->getShowMarker()) {
1781 if (count($solved_array) > 0) {
1782 $solved = array_pop($solved_array);
1783 $solved = $solved[
"solved"];
1789 $navigationGUI->setQuestionMarked(
true);
1792 $navigationGUI->setQuestionMarked(
false);
1796 return $navigationGUI;
1804 if (!$this->
object->getListOfQuestionsEnd()) {
1808 if ($this->
object->areObligationsEnabled()
1809 && !$this->
object->allObligationsAnswered()) {
1821 $answerFeedbackEnabled = $this->
object->getSpecificAnswerFeedback();
1824 $this->test_session->getActiveId(), #active_id
1825 $this->test_session->getPass(), #pass
1826 false, #graphical_output
1827 false, #result_output
1828 true, #show_question_only
1829 $answerFeedbackEnabled, #show_feedback
1830 false, #show_correct_solution
1831 false, #show_manual_scoring
1832 true #show_question_text
1838 $this->test_session->getActiveId(),
1842 $tpl =
new ilTemplate(
'tpl.tst_player_response_modal.html',
true,
true,
'Modules/Test');
1848 $this->tpl = $saved_tpl;
1852 $button = $this->ui_factory->button()->primary($this->
lng->txt(
'proceed'), $navUrl);
1857 $modal->setId(
'tst_question_feedback_modal');
1858 $modal->setHeading($this->
lng->txt(
'tst_instant_feedback'));
1861 $this->tpl->addOnLoadCode(
"$('#tst_question_feedback_modal').modal('show');");
1862 $this->tpl->setVariable(
'INSTANT_RESPONSE_MODAL', $modal->getHTML());
1871 $response_available =
false;
1872 $jump_to_response =
false;
1876 if ($this->
object->getInstantFeedbackSolution()) {
1881 $this->test_session->getActiveId(), #active_id
1882 $this->test_session->getPass(), #pass
1883 false, #graphical_output
1884 $show_question_inline_score, #result_output
1885 true, #show_question_only
1886 false, #show_feedback
1887 true, #show_correct_solution
1888 false, #show_manual_scoring
1889 false #show_question_text
1891 $solutionoutput = str_replace(
'<h1 class="ilc_page_title_PageTitle"></h1>',
'', $solutionoutput);
1893 $response_available =
true;
1894 $jump_to_response =
true;
1897 $reachedPoints = $questionGui->object->getAdjustedReachedPoints(
1898 $this->test_session->getActiveId(),
1903 $maxPoints = $questionGui->object->getMaximumPoints();
1905 $solutionCorrect = ($reachedPoints == $maxPoints);
1909 if ($this->
object->getAnswerFeedbackPoints()) {
1911 $response_available =
true;
1912 $jump_to_response =
true;
1917 if ($this->
object->getGenericAnswerFeedback()) {
1919 $response_available =
true;
1920 $jump_to_response =
true;
1926 if ($this->
object->getSpecificAnswerFeedback()) {
1929 $jump_to_response =
false;
1931 $response_available =
true;
1932 $jump_to_response =
true;
1937 if (!$response_available) {
1948 if ($withFocusAnchor) {
1949 $this->tpl->setCurrentBlock(
'inst_resp_id');
1950 $this->tpl->setVariable(
'INSTANT_RESPONSE_FOCUS_ID',
'focus');
1951 $this->tpl->parseCurrentBlock();
1954 $this->tpl->setCurrentBlock(
'instant_response_header');
1955 $this->tpl->setVariable(
'INSTANT_RESPONSE_HEADER', $this->
lng->txt(
'tst_feedback'));
1956 $this->tpl->parseCurrentBlock();
1961 $this->tpl->setCurrentBlock(
'instant_response_message');
1962 $this->tpl->setVariable(
'INSTANT_RESPONSE_MESSAGE', $a_message);
1963 $this->tpl->parseCurrentBlock();
1973 return $this->test_session->getLastSequence();
1978 if ($this->testrequest->isset(
'sequence')) {
1979 return $this->testrequest->int(
'sequence');
1987 if ($this->testrequest->isset(
'pmode')) {
1988 return $this->testrequest->raw(
'pmode');
1996 if ($this->testrequest->isset(
'instresp')) {
1997 return $this->testrequest->raw(
'instresp');
2006 if ($this->testrequest->isset(
'nextcmd')) {
2007 $nextcmd = $this->testrequest->strVal(
'nextcmd');
2010 return $nextcmd !==
'' ? $nextcmd : null;
2015 if (isset($_POST[
'nextseq']) && is_numeric($_POST[
'nextseq'])) {
2016 return (
int) $_POST[
'nextseq'];
2025 if (isset($_POST[
'test_player_navigation_url'])) {
2026 $navigation_url = $_POST[
'test_player_navigation_url'];
2028 $navigation_url_parts = parse_url($navigation_url);
2031 if (!isset($navigation_url_parts[
'host']) || ($ilias_url_parts[
'host'] === $navigation_url_parts[
'host'])) {
2032 return $navigation_url;
2048 return !empty($this->testrequest->raw(
'test_answer_changed'));
2057 $this->
ctrl->setParameter($this,
'test_answer_changed', $changed ?
'1' :
'0');
2083 if (!empty($_POST[
'save_on_navigation_prevent_confirmation'])) {
2087 if (!empty($_POST[self::FOLLOWUP_QST_LOCKS_PREVENT_CONFIRMATION_PARAM])) {
2088 ilSession::set(self::FOLLOWUP_QST_LOCKS_PREVENT_CONFIRMATION_PARAM,
true);
2107 if (!$fromCache || !isset($this->cachedQuestionGuis[$question_id])) {
2108 $question_gui = $this->
object->createQuestionGUI(
"", $question_id);
2109 $question_gui->setTargetGui($this);
2111 $question_gui->object->setObligationsToBeConsidered($this->
object->areObligationsEnabled());
2112 $question_gui->populateJavascriptFilesRequiredForWorkForm(
$tpl);
2113 $question_gui->object->setShuffler($this->shuffler->getAnswerShuffleFor(
2115 $this->test_session->getActiveId(),
2116 $this->test_session->getPass()
2123 $this->cachedQuestionGuis[$question_id] = $question_gui;
2126 return $this->cachedQuestionGuis[$question_id];
2133 if ($from_cache && isset($this->cachedQuestionObjects[$question_id])) {
2134 return $this->cachedQuestionObjects[$question_id];
2137 $ass_settings =
new ilSetting(
'assessment');
2140 $process_locker_factory->setQuestionId($question->getId());
2141 $process_locker_factory->setUserId($this->
user->getId());
2143 $question->setProcessLocker($process_locker_factory->getLocker());
2145 $question->setObligationsToBeConsidered($this->
object->areObligationsEnabled());
2149 $this->cachedQuestionObjects[$question_id] = $question;
2157 $this->
object->isPreviousSolutionReuseEnabled($this->test_session->getActiveId())
2163 $this->logging_services->root()->write(
2165 .
"active={$this->test_session->getActiveId()} " 2166 .
"qId=$question_id seq=$sequence_element " 2167 . serialize($this->testSequence)
2172 $this->
ctrl->setParameter($this,
'sequence', $this->testSequence->getFirstSequence());
2181 if ($this->
object->getKioskMode()) {
2182 $this->tpl->addBlockfile($this->
getContentBlockName(),
'content',
"tpl.il_as_tst_kiosk_mode_content.html",
"Modules/Test");
2183 $this->tpl->setContent($contentHTML);
2196 if ($this->
object->isFollowupQuestionAnswerFixationEnabled()) {
2205 $tpl =
new ilTemplate(
'tpl.tst_player_confirmation_modal.html',
true,
true,
'Modules/Test');
2207 $tpl->
setVariable(
'CONFIRMATION_TEXT', $this->
lng->txt(
'discard_answer_confirmation'));
2209 $button = $this->ui_factory->button()->standard($this->
lng->txt(
'discard_answer'),
'#')
2211 fn(
$id) =>
"document.getElementById('$id').addEventListener( 2214 event.target.name = 'cmd[discardSolution]'; 2215 event.target.form.requestSubmit(event.target); 2224 $button = $this->ui_factory->button()->primary($this->
lng->txt(
'cancel'),
'#')
2226 fn(
$id) =>
"document.getElementById('$id').addEventListener( 2228 ()=>$('#tst_discard_solution_modal').modal('hide') 2236 $modal->setId(
'tst_discard_solution_modal');
2237 $modal->setHeading($this->
lng->txt(
'discard_answer'));
2240 $this->tpl->setCurrentBlock(
'discard_solution_modal');
2241 $this->tpl->setVariable(
'DISCARD_SOLUTION_MODAL', $modal->getHTML());
2242 $this->tpl->parseCurrentBlock();
2249 if (
ilSession::get(
'save_on_navigation_prevent_confirmation') == null) {
2253 $tpl =
new ilTemplate(
'tpl.tst_player_confirmation_modal.html',
true,
true,
'Modules/Test');
2255 if ($this->
object->isInstantFeedbackAnswerFixationEnabled() && $this->
object->isForceInstantFeedbackEnabled()) {
2256 $text = $this->
lng->txt(
'save_on_navigation_locked_confirmation');
2258 $text = $this->
lng->txt(
'save_on_navigation_confirmation');
2260 if ($this->
object->isForceInstantFeedbackEnabled()) {
2261 $text .=
" " . $this->
lng->txt(
'save_on_navigation_forced_feedback_hint');
2272 $button = $this->ui_factory->button()->primary($this->
lng->txt(
'tst_save_and_proceed'),
'#');
2279 $button->setId(
'tst_cancel_on_navigation_button');
2280 $button->setUrl(
'#');
2281 $button->setCaption(
'cancel');
2282 $button->setPrimary(
false);
2288 $tpl->
setVariable(
'CONFIRMATION_CHECKBOX_NAME',
'save_on_navigation_prevent_confirmation');
2289 $tpl->
setVariable(
'CONFIRMATION_CHECKBOX_LABEL', $this->
lng->txt(
'tst_dont_show_msg_again_in_current_session'));
2293 $modal->setId(
'tst_save_on_navigation_modal');
2294 $modal->setHeading($this->
lng->txt(
'save_on_navigation'));
2297 $this->tpl->setCurrentBlock(
'nav_while_edit_modal');
2298 $this->tpl->setVariable(
'NAV_WHILE_EDIT_MODAL', $modal->getHTML());
2299 $this->tpl->parseCurrentBlock();
2306 $modal->setModalId(
'tst_next_locks_unchanged_modal');
2308 $modal->setHeaderText($this->
lng->txt(
'tst_nav_next_locks_empty_answer_header'));
2309 $modal->setConfirmationText($this->
lng->txt(
'tst_nav_next_locks_empty_answer_confirm'));
2311 $button = $this->ui_factory->button()->standard($this->
lng->txt(
'tst_proceed'),
'#');
2312 $modal->addButton($button);
2314 $button = $this->ui_factory->button()->primary($this->
lng->txt(
'cancel'),
'#');
2315 $modal->addButton($button);
2317 $this->tpl->setCurrentBlock(
'next_locks_unchanged_modal');
2318 $this->tpl->setVariable(
'NEXT_LOCKS_UNCHANGED_MODAL', $modal->getHTML());
2319 $this->tpl->parseCurrentBlock();
2329 $modal->setModalId(
'tst_next_locks_changed_modal');
2331 $modal->setHeaderText($this->
lng->txt(
'tst_nav_next_locks_current_answer_header'));
2332 $modal->setConfirmationText($this->
lng->txt(
'tst_nav_next_locks_current_answer_confirm'));
2334 $modal->setConfirmationCheckboxName(self::FOLLOWUP_QST_LOCKS_PREVENT_CONFIRMATION_PARAM);
2335 $modal->setConfirmationCheckboxLabel($this->
lng->txt(
'tst_dont_show_msg_again_in_current_session'));
2337 $button = $this->ui_factory->button()->primary($this->
lng->txt(
'tst_save_and_proceed'),
'#');
2338 $modal->addButton($button);
2340 $button = $this->ui_factory->button()->standard($this->
lng->txt(
'cancel'),
'#');
2341 $modal->addButton($button);
2343 $this->tpl->setCurrentBlock(
'next_locks_changed_modal');
2344 $this->tpl->setVariable(
'NEXT_LOCKS_CHANGED_MODAL', $modal->getHTML());
2345 $this->tpl->parseCurrentBlock();
2352 ilSession::set(self::FOLLOWUP_QST_LOCKS_PREVENT_CONFIRMATION_PARAM,
true);
2357 if (
ilSession::get(self::FOLLOWUP_QST_LOCKS_PREVENT_CONFIRMATION_PARAM) == null) {
2361 return ilSession::get(self::FOLLOWUP_QST_LOCKS_PREVENT_CONFIRMATION_PARAM);
2364 protected function populateQuestionEditControl(
assQuestionGUI $question_gui):
void 2368 $state = $question_gui->object->lookupForExistingSolutions($this->test_session->getActiveId(), $this->test_session->getPass());
2369 $config[
'isAnswered'] = $state[
'authorized'];
2374 $config[
'autosaveUrl'] =
'';
2375 $config[
'autosaveInterval'] = 0;
2378 $config[
'autosaveInterval'] = $this->
object->getMainSettings()->getQuestionBehaviourSettings()->getAutosaveInterval();
2383 $question_config = $question_gui->object->getTestPresentationConfig();
2387 $config[
'withFormChangeDetection'] = $question_config->isFormChangeDetectionEnabled();
2390 $config[
'withBackgroundChangeDetection'] = $question_config->isBackgroundChangeDetectionEnabled();
2394 $config[
'forcedInstantFeedback'] = $this->
object->isForceInstantFeedbackEnabled();
2396 $config[
'nextQuestionLocks'] = $this->
object->isFollowupQuestionAnswerFixationEnabled();
2397 $config[
'autosaveFailureMessage'] = $this->
lng->txt(
'autosave_failed');
2399 $this->tpl->addJavascript(
'./Modules/Test/js/ilTestPlayerQuestionEditControl.js');
2400 $this->tpl->addOnLoadCode(
'il.TestPlayerQuestionEditControl.init(' . json_encode($config) .
')');
2407 return self::PRESENTATION_MODE_EDIT;
2416 $forced_feeback_navigation_url =
ilSession::get(
'forced_feedback_navigation_url');
2417 $forced_feeback_navigation_url[$this->test_session->getActiveId()] = $forcedFeedbackNavUrl;
2418 ilSession::set(
'forced_feedback_navigation_url', $forced_feeback_navigation_url);
2426 $forced_feedback_navigation_url =
ilSession::get(
'forced_feedback_navigation_url');
2427 if (!isset($forced_feedback_navigation_url[$this->test_session->getActiveId()])) {
2431 return $forced_feedback_navigation_url[$this->test_session->getActiveId()];
2441 $forced_feedback_navigation_url =
ilSession::get(
'forced_feedback_navigation_url');
2442 if (isset($forced_feedback_navigation_url[$this->test_session->getActiveId()])) {
2443 unset($forced_feedback_navigation_url[$this->test_session->getActiveId()]);
2444 ilSession::set(
'forced_feedback_navigation_url', $forced_feedback_navigation_url);
populateFeedbackBlockMessage(string $a_message)
showSideList($current_sequence_element)
getQuestionInstance(int $question_id, bool $from_cache=true)
populateSyntaxStyleBlock()
redirectAfterQuestionListCmd()
static get(string $a_var)
populateNextButtons($primary_next)
redirectAfterAutosaveCmd()
Redirect the user after an automatic save when the time limit is reached.
saveQuestionSolution($authorized=true, $force=false)
saves the user input of a question
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
getQuestionGuiInstance($question_id, $fromCache=true)
populateDiscardSolutionModal()
removeIntermediateSolution()
const CMD_CONFIRM_REQUEST
isQuestionSummaryFinishTestButtonRequired()
outObligationsOnlySummaryCmd()
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.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
setAnswerChangedParameter($changed=true)
Set the 'answer changed' url parameter for generated links.
isFirstQuestionInSequence($sequenceElement)
populateSpecificFeedbackBlock(assQuestionGUI $question_gui)
populateContentStyleBlock()
handleQuestionActionCmd()
outQuestionSummaryCmd(bool $obligations_info=false, bool $obligations_filter=false)
Output of a summary of all test questions for test participants.
const FOLLOWUP_QST_LOCKS_PREVENT_CONFIRMATION_PARAM
getAccessCodeFromSession()
markQuestionAndSaveIntermediateCmd()
setAnonymousIdCmd()
Sets a session variable with the test access code for an anonymous test user.
determineSolutionPassIndex(assQuestionGUI $questionGui)
const QUESTION_SUMMARY_INC_OBLIGATIONS
const SHOW_FINAL_STATMENT
showQuestionEditable(assQuestionGUI $questionGui, $formAction, $isQuestionWorkedThrough, $instantResponse)
getPresentationModeParameter()
autosaveCmd()
Automatically save a user answer while working on the test (called repeatedly by asynchronous posts i...
outUserResultsOverviewCmd()
Abstract basic class which is to be extended by the concrete assessment question type classes...
isLastQuestionInSequence($sequenceElement)
populateTestNavigationToolbar(ilTestNavigationToolbarGUI $toolbar_gui)
populatePreviousButtons()
getObjectiveOrientedContainer()
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
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false)
withAdditionalOnLoadCode(Closure $binder)
populateHelperGuiContent($helperGui)
const AUTO_SAVE_ON_TIME_LIMIT
get(string $part=self::DEFAULT_BLOCK)
Renders the given block and returns the html string.
getNextCommandParameter()
doesAccessCodeInSessionExists()
getResultsSignature()
Returns HTML code for a signature field.
cancelAnswerOptionalQuestionsCmd()
isFollowUpQuestionLocksConfirmationPrevented()
setVariable(string $variable, $value='')
Sets the given variable to the given value.
const CSS_CLASS_FEEDBACK_CORRECT
const DEFAULT_SKL_TRIG_NUM_ANSWERS_BARRIER
handleUserSettings()
Handles some form parameters on starting and resuming a test.
afterTestPassFinishedCmd()
buildReadOnlyStateQuestionNavigationGUI($questionId)
static getStyleSheetLocation(string $mode="output", string $a_css_name="", string $a_css_location="")
get full style sheet file name (path inclusive) of current user
getContentBlockName()
Returns the name of the current content block (depends on the kiosk mode setting) ...
confirmHintRequestCmd()
Go to hint request confirmation.
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
maxProcessingTimeReached()
Outputs a message when the maximum processing time is reached.
setFollowUpQuestionLocksConfirmationPrevented()
showRequestedHintListCmd()
Go to requested hint list.
ilTestSession $test_session
populateNavWhenChangedModal()
unregisterForcedFeedbackNavUrl()
populateInstantResponseBlocks(assQuestionGUI $questionGui, $authorizedSolution)
isNrOfTriesReached()
nr of tries exceeded
checkTestSessionUser(ilTestSession $test_session)
static _lookupOnlineTestAccess($a_test_id, $a_user_id)
Checks if a user is allowd to run an online exam.
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)
initTestQuestionConfig(assQuestion $questionOBJ)
markQuestionCmd()
Set a question solved.
handleIntermediateSubmit()
Check the 'answer changed' parameter when a question form is intermediately submitted.
isForcedFeedbackNavUrlRegistered()
static _enabledAssessmentLogging()
getInstantResponseParameter()
buildTestPassQuestionList()
populateGenericFeedbackBlock(assQuestionGUI $question_gui, $solutionCorrect)
getRegisteredForcedFeedbackNavUrl()
buildEditableStateQuestionNavigationGUI($questionId)
outQuestionSummaryWithObligationsInfoCmd()
const TEST_PLAYER_QUESTIONLIST
outCorrectSolution()
Creates an output of the solution of an answer compared to the correct solution.
const CONFIRM_HINT_REQUEST
getIntroductionPageButtonLabel()
handleSkillTriggering(ilTestSession $test_session)
const PRESENTATION_MODE_EDIT
resumePlayerCmd()
Resume a test at the last position.
saveNavigationPreventConfirmation()
Save the save the switch to prevent the navigation confirmation.
endingTimeReached()
handle endingTimeReached
buildPreviousButtonInstance()
const ACCESS_CODE_CONFIRMED
static _getSolvedQuestions($active_id, $question_fi=null)
get solved questions
const REDIRECT_ON_TIME_LIMIT
ensureExistingTestSession(ilTestSession $test_session)
outProcessingTime(int $active_id, bool $verbose)
const SHOW_INSTANT_RESPONSE
static getSyntaxStylePath()
const CSS_CLASS_FEEDBACK_WRONG
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()
Get the 'answer changed' status from the current request It may be set by ilTestPlayerNavigationContr...
getSequenceElementParameter()
Basic GUI class for assessment questions.
ilTestSequence $testSequence
populateNextLocksChangedModal()
detectChangesCmd()
Detect changes sent in the background to the server This is called by ajax from ilTestPlayerQuestionE...
const PRESENTATION_MODE_VIEW
static getContentStylePath(int $a_style_id, bool $add_random=true, bool $add_token=true)
get content style path static (to avoid full reading)
const PRESENTATION_CONTEXT_TEST
const REDIRECT_AFTER_QUESTION_LIST
bool $maxProcessingTimeReached
initProcessLocker($activeId)
isShowingPostponeStatusReguired($questionId)
static redirect(string $a_script)
unmarkQuestionCmd()
Set a question unsolved.
setCurrentBlock(string $part=self::DEFAULT_BLOCK)
Sets the template to the given block.
const TEST_PLAYER_VIEW_TITLE
handlePasswordProtectionRedirect()
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
const UNMARK_QUESTION_SAVE
registerForcedFeedbackNavUrl($forcedFeedbackNavUrl)
const QUESTION_SUMMARY_OBLIGATIONS_ONLY
form( $class_path, string $cmd, string $submit_caption="")
setAnonymousId(string $anonymous_id)
isOptionalQuestionAnsweringConfirmationRequired($sequenceElement)
getSpecificFeedbackOutput(array $userSolution)
Returns the answer specific feedback for the question.
populateUpperNextButtonBlock($primaryNext)
showQuestionViewable(assQuestionGUI $questionGui, $formAction, $isQuestionWorkedThrough, $instantResponse)
isTestAccessible()
test accessible returns true if the user can perform the test
populateMessageContent($contentHTML)
const DISPLAY_ACCESS_CODE
outQuestionPage($a_temp_var, $a_postponed=false, $active_id="", $html="", $inlineFeedbackEnabled=false)
getSolutionOutput( $active_id, $pass=null, $graphicalOutput=false, $result_output=false, $show_question_only=true, $show_feedback=false, $show_correct_solution=false, $show_manual_scoring=false, $show_question_text=true)
populateInstantResponseModal(assQuestionGUI $questionGui, $navUrl)
getNextSequenceParameter()
determineInlineScoreDisplay()
getTestPresentationConfig()
getNavigationUrlParameter()
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
getQuestionHeaderBlockBuilder()
const FIXED_SHUFFLER_SEED_MIN_LENGTH
__construct(ilObjTest $object)
getQuestionsDefaultPresentationMode($isQuestionWorkedThrough)
unmarkQuestionAndSaveIntermediateCmd()
handleTearsAndAngerQuestionIsNull(int $question_id, $sequence_element)
Service GUI class for tests.
ilTestPasswordChecker $passwordChecker
initTestCmd()
Start a test for the first time after a redirect.
parseCurrentBlock(string $block_name=self::DEFAULT_BLOCK)
Parses the given block.
isMaxProcessingTimeReached()
getCurrentSequenceElement()
ilTestProcessLocker $processLocker
confirmAnswerOptionalQuestionsCmd()
static clear(string $a_var)
populateFeedbackBlockHeader($withFocusAnchor)
getTestNavigationToolbarGUI()
static set(string $a_var, $a_val)
Set a value.
performTestPassFinishedTasks()
outQuestionForTest(string $formaction, int $active_id, ?int $pass, bool $is_question_postponed=false, $user_post_solutions=false, bool $show_specific_inline_feedback=false)
populateSolutionBlock($solutionoutput)
populateScoreBlock($reachedPoints, $maxPoints)
setNavigationGUI(?ilTestQuestionNavigationGUI $navigationGUI)
isParticipantsAnswerFixed($questionId)
Output class for assessment test execution.
prepareTestPage($sequenceElement, $questionId)
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)