4 require_once
'./Modules/Test/classes/inc.AssessmentConstants.php';
5 require_once
'./Modules/Test/classes/class.ilTestPlayerCommands.php';
6 require_once
'./Modules/Test/classes/class.ilTestServiceGUI.php';
7 require_once
'./Modules/TestQuestionPool/classes/class.assQuestion.php';
8 require_once
'./Services/UIComponent/Button/classes/class.ilSubmitButton.php';
9 require_once
'Modules/Test/classes/class.ilTestPlayerNavButton.php';
71 parent::__construct($a_object);
72 $this->ref_id =
$_GET[
"ref_id"];
75 $rbacsystem = $DIC[
'rbacsystem'];
78 require_once
'Modules/Test/classes/class.ilTestPasswordChecker.php';
81 $this->processLocker = null;
82 $this->testSession = null;
83 $this->assSettings = null;
89 $rbacsystem = $DIC[
'rbacsystem'];
91 if (!$rbacsystem->checkAccess(
"read", $this->object->getRefId())) {
93 $this->
ilias->raiseError($this->lng->txt(
"cannot_execute_test"), $this->
ilias->error_obj->MESSAGE);
99 $executable = $this->
object->isExecutable($this->testSession, $this->testSession->getUserId());
101 if (!$executable[
'executable']) {
103 $this->ctrl->redirectByClass(
"ilobjtestgui",
"infoScreen");
111 if ($testSession->
getUserId() != $DIC->user()->getId()) {
112 throw new ilTestException(
'active id given does not relate to current user!');
141 $ilDB = $DIC[
'ilDB'];
143 require_once
'Modules/Test/classes/class.ilTestProcessLockerFactory.php';
146 $processLockerFactory->setActiveId($activeId);
148 $this->processLocker = $processLockerFactory->getLocker();
159 include_once(
"./Services/Tagging/classes/class.ilTaggingGUI.php");
161 $tagging_gui->setObject($this->object->getId(), $this->
object->getType());
162 $tagging_gui->saveInput();
163 $this->ctrl->redirectByClass(
"ilobjtestgui",
"infoScreen");
172 $this->
object->updateWorkingTime(
$_SESSION[
"active_time_id"]);
175 $_SESSION[
"active_time_id"] = $this->
object->startWorkingTime(
176 $this->testSession->getActiveId(),
177 $this->testSession->getPass()
191 $this->testSession->getActiveId(),
192 $this->testSession->getPass()
206 $this->ctrl->redirectByClass(
"ilobjtestgui",
"infoScreen");
220 $active_id = $this->testSession->getActiveId();
221 $starting_time = $this->
object->getStartingTimeOfUser($active_id);
222 if ($starting_time ===
false) {
225 return $this->
object->isMaxProcessingTimeReached($starting_time, $active_id);
231 $show_question_inline_score =
false;
232 if ($this->object->getAnswerFeedbackPoints()) {
233 $show_question_inline_score =
true;
234 return $show_question_inline_score;
236 return $show_question_inline_score;
241 $this->tpl->setCurrentBlock(
'test_nav_toolbar');
242 $this->tpl->setVariable(
'TEST_NAV_TOOLBAR', $toolbarGUI->getHTML());
243 $this->tpl->parseCurrentBlock();
272 $button->setId(
'bottomnextbutton');
274 $this->tpl->setCurrentBlock(
"next_bottom");
275 $this->tpl->setVariable(
"BTN_NEXT", $button->render());
276 $this->tpl->parseCurrentBlock();
282 $button->setId(
'nextbutton');
284 $this->tpl->setCurrentBlock(
"next");
285 $this->tpl->setVariable(
"BTN_NEXT", $button->render());
286 $this->tpl->parseCurrentBlock();
292 $button->setId(
'bottomprevbutton');
294 $this->tpl->setCurrentBlock(
"prev_bottom");
295 $this->tpl->setVariable(
"BTN_PREV", $button->render());
296 $this->tpl->parseCurrentBlock();
302 $button->setId(
'prevbutton');
304 $this->tpl->setCurrentBlock(
"prev");
305 $this->tpl->setVariable(
"BTN_PREV", $button->render());
306 $this->tpl->parseCurrentBlock();
318 $button->setPrimary($primaryNext);
319 $button->setRightGlyph(
'glyphicon glyphicon-arrow-right');
323 $button->setCaption(
'next_question');
324 $button->addCSSClass(
'ilTstNavElem');
337 $button->setLeftGlyph(
'glyphicon glyphicon-arrow-left');
341 $button->setCaption(
'previous_question');
342 $button->addCSSClass(
'ilTstNavElem');
349 $solutionValues = $question_gui->object->getSolutionValues(
350 $this->testSession->getActiveId(),
355 $question_gui->object->fetchIndexedValuesFromValuePairs($solutionValues)
358 $this->tpl->setCurrentBlock(
"specific_feedback");
359 $this->tpl->setVariable(
"SPECIFIC_FEEDBACK", $feedback);
360 $this->tpl->parseCurrentBlock();
367 if (strlen($feedback)) {
373 $this->tpl->setCurrentBlock(
"answer_feedback");
374 $this->tpl->setVariable(
"ANSWER_FEEDBACK", $feedback);
375 $this->tpl->setVariable(
"ILC_FB_CSS_CLASS", $cssClass);
376 $this->tpl->parseCurrentBlock();
382 $scoreInformation = sprintf(
383 $this->lng->txt(
"you_received_a_of_b_points"),
388 $this->tpl->setCurrentBlock(
"received_points_information");
389 $this->tpl->setVariable(
"RECEIVED_POINTS_INFORMATION", $scoreInformation);
390 $this->tpl->parseCurrentBlock();
395 if (strlen($solutionoutput)) {
396 $this->tpl->setCurrentBlock(
"solution_output");
397 $this->tpl->setVariable(
"CORRECT_SOLUTION", $this->lng->txt(
"tst_best_solution_is"));
398 $this->tpl->setVariable(
"QUESTION_FEEDBACK", $solutionoutput);
399 $this->tpl->parseCurrentBlock();
405 $this->tpl->setCurrentBlock(
"SyntaxStyle");
406 $this->tpl->setVariable(
407 "LOCATION_SYNTAX_STYLESHEET",
410 $this->tpl->parseCurrentBlock();
415 include_once(
"./Services/Style/Content/classes/class.ilObjStyleSheet.php");
416 $this->tpl->setCurrentBlock(
"ContentStyle");
417 $this->tpl->setVariable(
418 "LOCATION_CONTENT_STYLESHEET",
421 $this->tpl->parseCurrentBlock();
431 if ($this->testSession->isAnonymousUser()) {
432 $this->testSession->setAccessCodeToSession(
$_POST[
'anonymous_id']);
435 $this->ctrl->redirectByClass(
"ilobjtestgui",
"infoScreen");
447 $isFirstTestStartRequest =
false;
449 $this->processLocker->executeTestStartLockOperation(
function () use ($testStartLock, &$isFirstTestStartRequest) {
450 if ($this->testSession->lookupTestStartLock() != $testStartLock) {
451 $this->testSession->persistTestStartLock($testStartLock);
452 $isFirstTestStartRequest =
true;
456 if ($isFirstTestStartRequest) {
461 $this->ctrl->setParameterByClass(
'ilObjTestGUI',
'lock', $testStartLock);
462 $this->ctrl->redirectByClass(
"ilobjtestgui",
"redirectToInfoScreen");
469 } elseif (isset(
$_GET[
'lock']) && strlen(
$_GET[
'lock'])) {
470 return $_GET[
'lock'];
486 if ($this->object->checkMaximumAllowedUsers() ==
false) {
490 if ($this->testSession->isAnonymousUser() && !$this->testSession->getActiveId()) {
491 $accessCode = $this->testSession->createNewAccessCode();
493 $this->testSession->setAccessCodeToSession($accessCode);
494 $this->testSession->setAnonymousId($accessCode);
495 $this->testSession->saveToDb();
500 $this->testSession->unsetAccessCodeInSession();
506 $this->tpl->addBlockFile($this->
getContentBlockName(),
"adm_content",
"tpl.il_as_tst_anonymous_code_presentation.html",
"Modules/Test");
507 $this->tpl->setCurrentBlock(
"adm_content");
508 $this->tpl->setVariable(
"TEXT_ANONYMOUS_CODE_CREATED", $this->lng->txt(
"tst_access_code_created"));
509 $this->tpl->setVariable(
"TEXT_ANONYMOUS_CODE", $this->testSession->getAccessCodeFromSession());
510 $this->tpl->setVariable(
"FORMACTION", $this->ctrl->getFormAction($this));
512 $this->tpl->setVariable(
"TXT_CONFIRM", $this->lng->txt(
"continue_work"));
513 $this->tpl->parseCurrentBlock();
529 if (
$_POST[
"chb_javascript"]) {
530 $ilUser->writePref(
"tst_javascript", 1);
532 $ilUser->writePref(
"tst_javascript", 0);
536 if ($this->object->getNrOfTries() != 1) {
537 if ($this->object->getUsePreviousAnswers() == 1) {
538 if (
$_POST[
"chb_use_previous_answers"]) {
539 $ilUser->writePref(
"tst_use_previous_answers", 1);
541 $ilUser->writePref(
"tst_use_previous_answers", 0);
553 $active_id = $this->testSession->getActiveId();
558 $this->testSession->setLastFinishedPass($this->testSession->getPass());
559 $this->testSession->increaseTestPass();
563 $this->tpl->addBlockFile($this->
getContentBlockName(),
"adm_content",
"tpl.il_as_tst_redirect_autosave.html",
"Modules/Test");
564 $this->tpl->setVariable(
"TEXT_REDIRECT", $this->lng->txt(
"redirectAfterSave"));
565 $this->tpl->setCurrentBlock(
"HeadContent");
566 $this->tpl->setVariable(
"CONTENT_BLOCK",
"<meta http-equiv=\"refresh\" content=\"5; url=" .
$url .
"\">");
567 $this->tpl->parseCurrentBlock();
572 $active_id = $this->testSession->getActiveId();
577 $this->testSession->setLastFinishedPass($this->testSession->getPass());
578 $this->testSession->increaseTestPass();
582 $this->tpl->addBlockFile($this->
getContentBlockName(),
"adm_content",
"tpl.il_as_tst_redirect_autosave.html",
"Modules/Test");
583 $this->tpl->setVariable(
"TEXT_REDIRECT", $this->lng->txt(
"redirectAfterSave"));
584 $this->tpl->setVariable(
"URL",
$url);
607 $res = is_int($db_res);
610 $result = $this->lng->txt(
"autosave_success");
612 $result = $this->lng->txt(
"autosave_failed");
644 $this->testSession->getActiveId(),
645 $this->testSession->getPass()
673 $show_side_list =
$ilUser->getPref(
'side_list_of_questions');
674 $ilUser->writePref(
'side_list_of_questions', !$show_side_list);
691 $questionId = $this->testSequence->getQuestionForSequence(
695 $this->
object->setQuestionSetSolved(1, $questionId, $this->testSession->getUserId());
713 $questionId = $this->testSequence->getQuestionForSequence(
717 $this->
object->setQuestionSetSolved(0, $questionId, $this->testSession->getUserId());
733 protected function confirmFinishTestCmd()
741 require_once
'Services/Utilities/classes/class.ilConfirmationGUI.php';
743 $confirmation->setFormAction($this->ctrl->getFormAction($this,
'confirmFinish'));
744 $confirmation->setHeaderText($this->lng->txt(
"tst_finish_confirmation_question"));
745 $confirmation->setConfirm($this->lng->txt(
"tst_finish_confirm_button"),
'confirmFinish');
755 $active_id = $this->testSession->getActiveId();
773 if ($this->object->areObligationsEnabled() && !$allObligationsAnswered) {
774 if ($this->object->getListOfQuestions()) {
784 if ($this->object->getEnableExamview() && !isset(
$_GET[
'reviewed']) && $requires_confirmation) {
785 $this->ctrl->redirectByClass(
'ilTestSubmissionReviewGUI',
"show");
790 if (($requires_confirmation) && ($actualpass == $this->object->getNrOfTries() - 1)) {
792 return $this->confirmFinishTestCmd();
796 if (($actualpass == $this->object->getNrOfTries() - 1) && (!$requires_confirmation)) {
798 #$ilAuth->setIdle(ilSession::getIdleValue(), false); 799 #$ilAuth->setExpire(0); 800 switch ($this->object->getMailNotification()) {
802 $this->
object->sendSimpleNotification($active_id);
805 $this->
object->sendAdvancedNotification($active_id);
815 if ($this->object->getMailNotificationType() == 1) {
816 switch ($this->object->getMailNotification()) {
818 $this->
object->sendSimpleNotification($active_id);
821 $this->
object->sendAdvancedNotification($active_id);
836 require_once
'Modules/Test/classes/class.ilTestPassFinishTasks.php';
844 $activeId = $this->testSession->getActiveId();
845 $lastFinishedPass = $this->testSession->getLastFinishedPass();
849 $this->ctrl->redirectByClass(
'ilTestSignatureGUI',
'invokeSignaturePlugin');
853 if (!
$_GET[
'skipfinalstatement']) {
854 if ($this->object->getShowFinalStatement()) {
860 $redirection_mode = $this->
object->getRedirectionMode();
861 $redirection_url = $this->
object->getRedirectionUrl();
862 if ($redirection_url && $redirection_mode) {
864 if ($this->object->getKioskMode()) {
878 if (!$this->object->getSignSubmission()) {
882 if (!is_null(
ilSession::get(
"signed_{$activeId}_{$lastFinishedPass}"))) {
887 $ilPluginAdmin = $DIC[
'ilPluginAdmin'];
889 $activePlugins = $ilPluginAdmin->getActivePluginsForSlot(
IL_COMP_MODULE,
'Test',
'tsig');
891 if (!count($activePlugins)) {
906 $ilObjDataCache = $DIC[
'ilObjDataCache'];
908 require_once
'Modules/Test/classes/class.ilTestResultHeaderLabelBuilder.php';
911 $objectivesList = null;
914 $testSequence = $this->testSequenceFactory->getSequenceByActiveIdAndPass($this->testSession->getActiveId(), $this->testSession->getPass());
918 require_once
'Modules/Course/classes/Objectives/class.ilLOTestQuestionAdapter.php';
922 $objectivesList->loadObjectivesTitles();
924 $testResultHeaderLabelBuilder->setObjectiveOrientedContainerId($this->testSession->getObjectiveOrientedContainerId());
925 $testResultHeaderLabelBuilder->setUserId($this->testSession->getUserId());
926 $testResultHeaderLabelBuilder->setTestObjId($this->object->getId());
927 $testResultHeaderLabelBuilder->setTestRefId($this->object->getRefId());
928 $testResultHeaderLabelBuilder->initObjectiveOrientedMode();
931 $results = $this->
object->getTestResult(
938 require_once
'class.ilTestEvaluationGUI.php';
940 $results_output = $testevaluationgui->getPassListOfAnswers(
950 $testResultHeaderLabelBuilder
953 require_once
'./Modules/Test/classes/class.ilTestArchiver.php';
960 if (!is_dir($path)) {
963 $filename = realpath($path) .
'/exam_N' . $inst_id .
'-' . $this->
object->getId()
964 .
'-' . $active .
'-' .
$pass .
'.pdf';
966 require_once
'Modules/Test/classes/class.ilTestPDFGenerator.php';
970 $archiver->handInParticipantSubmission($active,
$pass,
$filename, $results_output);
976 $questions = $this->
object->getQuestions();
977 foreach ($questions as $question_id) {
978 $question_object = $this->
object->getQuestionDataset($question_id);
979 if ($question_object->type_tag ==
'assFileUpload') {
998 $handle = opendir($candidate_path);
999 while ($handle !==
false && ($file = readdir($handle)) !==
false) {
1000 if ($file != null) {
1001 $filename_start =
'file_' . $active .
'_' .
$pass .
'_';
1003 if (strpos($file, $filename_start) === 0) {
1004 $archiver->handInParticipantQuestionMaterial($active,
$pass, $question_id, $file, $file);
1010 $passdata = $this->
object->getTestResult(
1016 $overview = $testevaluationgui->getPassListOfAnswers(
1026 $testResultHeaderLabelBuilder
1039 require_once
'Modules/Test/classes/class.ilTestPassesSelector.php';
1041 $testPassesSelector->setActiveId($this->testSession->getActiveId());
1042 $testPassesSelector->setLastFinishedPass($this->testSession->getLastFinishedPass());
1044 if (count($testPassesSelector->getReportablePasses())) {
1046 $this->ctrl->redirectByClass(array(
'ilTestResultsGUI',
'ilTestEvalObjectiveOrientedGUI'));
1049 $this->ctrl->redirectByClass(array(
'ilTestResultsGUI',
'ilMyTestResultsGUI',
'ilTestEvaluationGUI'));
1057 $this->ctrl->redirectByClass(
'ilObjTestGUI',
'redirectToInfoScreen');
1065 $template =
new ilTemplate(
"tpl.il_as_tst_final_statement.html",
true,
true,
"Modules/Test");
1066 $this->ctrl->setParameter($this,
"skipfinalstatement", 1);
1068 $template->setVariable(
"FINALSTATEMENT", $this->object->prepareTextareaOutput($this->object->getFinalStatement(),
true));
1069 $template->setVariable(
"BUTTON_CONTINUE", $this->lng->txt(
"btn_next"));
1079 if ($this->object->getShowKioskModeTitle()) {
1080 $template->setCurrentBlock(
"kiosk_show_title");
1081 $template->setVariable(
"TEST_TITLE", $this->object->getTitle());
1084 if ($this->object->getShowKioskModeParticipant()) {
1085 $template->setCurrentBlock(
"kiosk_show_participant");
1086 $template->setVariable(
"PARTICIPANT_NAME_TXT", $this->lng->txt(
"login_as"));
1089 $template->setVariable(
"PARTICIPANT_MATRICULATION",
$ilUser->getMatriculation());
1093 if ($this->object->isShowExamIdInTestPassEnabled()) {
1095 $this->testSession->getActiveId(),
1096 $this->testSession->getPass(),
1097 $this->
object->getId()
1100 $template->setCurrentBlock(
"kiosk_show_exam_id");
1101 $template->setVariable(
"EXAM_ID_TXT", $this->lng->txt(
"exam_id"));
1102 $template->setVariable(
"EXAM_ID", $exam_id);
1115 $ilNavigationHistory = $DIC[
'ilNavigationHistory'];
1117 $ilNavigationHistory->addItem(
1118 $this->testSession->getRefId(),
1132 if ($this->object->endingTimeReached()) {
1138 $this->ctrl->setParameter($this,
"sequence", $sequenceElement);
1143 if ($this->object->getKioskMode()) {
1147 $this->tpl->setVariable(
"TEST_ID", $this->object->getTestId());
1148 $this->tpl->setVariable(
"LOGIN",
$ilUser->getLogin());
1149 $this->tpl->setVariable(
"SEQ_ID", $sequenceElement);
1150 $this->tpl->setVariable(
"QUEST_ID", $questionId);
1152 if ($this->object->getEnableProcessingTime()) {
1156 $this->tpl->setVariable(
"PAGETITLE",
"- " . $this->object->getTitle());
1158 if ($this->object->isShowExamIdInTestPassEnabled() && !$this->
object->getKioskMode()) {
1159 $this->tpl->setCurrentBlock(
'exam_id_footer');
1161 $this->testSession->getActiveId(),
1162 $this->testSession->getPass(),
1163 $this->
object->getId()
1165 $this->tpl->setVariable(
'EXAM_ID_TXT', $this->lng->txt(
'exam_id'));
1166 $this->tpl->parseCurrentBlock();
1169 if ($this->object->getListOfQuestions()) {
1170 $this->
showSideList($presentationMode, $sequenceElement);
1181 $questionNavigationGUI->setQuestionWorkedThrough($isQuestionWorkedThrough);
1188 $answerFeedbackEnabled = (
1189 $instantResponse && $this->
object->getSpecificAnswerFeedback()
1193 $this->testSession->getActiveId(), #active_id
1194 $this->testSession->getPass(), #pass
1195 false, #graphical_output
1196 false, #result_output
1197 true, #show_question_only
1198 $answerFeedbackEnabled, #show_feedback
1199 false, #show_correct_solution
1200 false, #show_manual_scoring
1201 true #show_question_text
1207 $this->testSession->getActiveId(),
1211 $this->tpl->setCurrentBlock(
'readonly_css_class');
1212 $this->tpl->touchBlock(
'readonly_css_class');
1213 $this->tpl->parseCurrentBlock();
1215 $this->tpl->setVariable(
'QUESTION_OUTPUT', $pageoutput);
1217 $this->tpl->setVariable(
"FORMACTION", $formAction);
1218 $this->tpl->setVariable(
"ENCTYPE",
'enctype="' . $questionGui->
getFormEncodingType() .
'"');
1219 $this->tpl->setVariable(
"FORM_TIMESTAMP", time());
1225 $questionGui->object->getId(),
1228 if ($isQuestionWorkedThrough) {
1229 $questionNavigationGUI->setDiscardSolutionButtonEnabled(
true);
1233 } elseif ($this->object->isPostponingEnabled()) {
1234 $questionNavigationGUI->setSkipQuestionLinkTarget(
1242 $answerFeedbackEnabled = (
1243 $instantResponse && $this->
object->getSpecificAnswerFeedback()
1246 if (isset(
$_GET[
'save_error']) &&
$_GET[
'save_error'] == 1 && isset(
$_SESSION[
'previouspost'])) {
1247 $userPostSolution =
$_SESSION[
'previouspost'];
1250 $userPostSolution =
false;
1258 $qstConfig = $questionGui->object->getTestPresentationConfig();
1261 $qstConfig->setWorkedThrough($isQuestionWorkedThrough);
1262 $qstConfig->setIsUnchangedAnswerPossible($this->object->getMCScoring());
1265 if ($qstConfig->isPreviousPassSolutionReuseAllowed()) {
1267 if ($passIndex < $this->testSession->getPass()) {
1268 $qstConfig->setSolutionInitiallyPrefilled(
true);
1271 $passIndex = $this->testSession->getPass();
1278 $formAction, #form_action
1279 $this->testSession->getActiveId(), #active_id
1283 $isPostponed, #is_postponed
1284 $userPostSolution, #user_post_solution
1285 $answerFeedbackEnabled #answer_feedback == inline_specific_feedback
1296 $this->populateQuestionEditControl($questionGui);
1303 require_once
'./Modules/Test/classes/class.ilObjTest.php';
1306 $currentSolutionAvailable = $questionGui->object->authorizedOrIntermediateSolutionExists(
1307 $this->testSession->getActiveId(),
1308 $this->testSession->getPass()
1311 if (!$currentSolutionAvailable) {
1312 $previousPass = $questionGui->object->getSolutionMaxPass(
1313 $this->testSession->getActiveId()
1316 $previousSolutionAvailable = $questionGui->object->authorizedSolutionExists(
1317 $this->testSession->getActiveId(),
1321 if ($previousSolutionAvailable) {
1322 return $previousPass;
1327 return $this->testSession->getPass();
1342 $this->ctrl->saveParameter($this,
'sequence');
1365 $user = $this->
object->getInvitedUsers(
$ilUser->getId());
1368 $this->ctrl->redirectByClass(
"ilobjtestgui",
"backToRepository");
1373 if (strcmp(
$user[
"clientip"],
"") != 0 && strcmp(
$user[
"clientip"],
$_SERVER[
"REMOTE_ADDR"]) != 0) {
1375 $this->ctrl->redirectByClass(
"ilobjtestgui",
"backToRepository");
1387 and $this->
object->startingTimeReached()
1388 and !$this->
object->endingTimeReached();
1396 return $this->
object->hasNrOfTriesRestriction() && $this->
object->isNrOfTriesReached($this->testSession->getPass());
1407 $this->testSession->increasePass();
1408 $this->testSession->setLastSequence(0);
1409 $this->testSession->saveToDb();
1433 $this->tpl->addBlockFile($this->
getContentBlockName(),
"adm_content",
"tpl.il_as_tst_submit_answers_confirm.html",
"Modules/Test");
1434 $this->tpl->setCurrentBlock(
"adm_content");
1435 if ($this->object->isTestFinished($this->testSession->getActiveId())) {
1436 $this->tpl->setCurrentBlock(
"not_submit_allowed");
1437 $this->tpl->setVariable(
"TEXT_ALREADY_SUBMITTED", $this->lng->txt(
"tst_already_submitted"));
1438 $this->tpl->setVariable(
"BTN_OK", $this->lng->txt(
"tst_show_answer_sheet"));
1440 $this->tpl->setCurrentBlock(
"submit_allowed");
1441 $this->tpl->setVariable(
"TEXT_CONFIRM_SUBMIT_RESULTS", $this->lng->txt(
"tst_confirm_submit_answers"));
1442 $this->tpl->setVariable(
"BTN_OK", $this->lng->txt(
"tst_submit_results"));
1444 $this->tpl->setVariable(
"BTN_BACK", $this->lng->txt(
"back"));
1445 $this->tpl->setVariable(
"FORMACTION", $this->ctrl->getFormAction($this,
"finalSubmission"));
1446 $this->tpl->parseCurrentBlock();
1454 $starting_time = $this->
object->getStartingTimeOfUser($active_id);
1455 $processing_time = $this->
object->getProcessingTimeInSeconds($active_id);
1456 $processing_time_minutes = floor($processing_time / 60);
1457 $processing_time_seconds = $processing_time - $processing_time_minutes * 60;
1458 $str_processing_time =
"";
1459 if ($processing_time_minutes > 0) {
1460 $str_processing_time = $processing_time_minutes .
" " . ($processing_time_minutes == 1 ? $this->lng->txt(
"minute") : $this->lng->txt(
"minutes"));
1462 if ($processing_time_seconds > 0) {
1463 if (strlen($str_processing_time) > 0) {
1464 $str_processing_time .=
" " . $this->lng->txt(
"and") .
" ";
1466 $str_processing_time .= $processing_time_seconds .
" " . ($processing_time_seconds == 1 ? $this->lng->txt(
"second") : $this->lng->txt(
"seconds"));
1468 $time_left = $starting_time + $processing_time - time();
1469 $time_left_minutes = floor($time_left / 60);
1470 $time_left_seconds = $time_left - $time_left_minutes * 60;
1471 $str_time_left =
"";
1472 if ($time_left_minutes > 0) {
1473 $str_time_left = $time_left_minutes .
" " . ($time_left_minutes == 1 ? $this->lng->txt(
"minute") : $this->lng->txt(
"minutes"));
1475 if ($time_left < 300) {
1476 if ($time_left_seconds > 0) {
1477 if (strlen($str_time_left) > 0) {
1478 $str_time_left .=
" " . $this->lng->txt(
"and") .
" ";
1480 $str_time_left .= $time_left_seconds .
" " . ($time_left_seconds == 1 ? $this->lng->txt(
"second") : $this->lng->txt(
"seconds"));
1483 $date = getdate($starting_time);
1485 $datenow = getdate();
1486 $this->tpl->setCurrentBlock(
"enableprocessingtime");
1487 $this->tpl->setVariable(
1488 "USER_WORKING_TIME",
1490 $this->lng->txt(
"tst_time_already_spent"),
1491 $formattedStartingTime,
1492 $str_processing_time
1495 $this->tpl->setVariable(
"USER_REMAINING_TIME", sprintf($this->lng->txt(
"tst_time_already_spent_left"), $str_time_left));
1496 $this->tpl->parseCurrentBlock();
1498 $template->setVariable(
"STRING_MINUTE", $this->lng->txt(
"minute"));
1499 $template->setVariable(
"STRING_MINUTES", $this->lng->txt(
"minutes"));
1500 $template->setVariable(
"STRING_SECOND", $this->lng->txt(
"second"));
1501 $template->setVariable(
"STRING_SECONDS", $this->lng->txt(
"seconds"));
1502 $template->setVariable(
"STRING_TIMELEFT", $this->lng->txt(
"tst_time_already_spent_left"));
1503 $template->setVariable(
"AND", strtolower($this->lng->txt(
"and")));
1504 $template->setVariable(
"YEAR", $date[
"year"]);
1505 $template->setVariable(
"MONTH", $date[
"mon"] - 1);
1506 $template->setVariable(
"DAY", $date[
"mday"]);
1507 $template->setVariable(
"HOUR", $date[
"hours"]);
1508 $template->setVariable(
"MINUTE", $date[
"minutes"]);
1509 $template->setVariable(
"SECOND", $date[
"seconds"]);
1510 if ($this->object->isEndingTimeEnabled()) {
1512 preg_match(
"/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $date_time->get(
IL_CAL_TIMESTAMP), $matches);
1513 $template->setVariable(
"ENDYEAR", $matches[1]);
1514 $template->setVariable(
"ENDMONTH", $matches[2] - 1);
1515 $template->setVariable(
"ENDDAY", $matches[3]);
1516 $template->setVariable(
"ENDHOUR", $matches[4]);
1517 $template->setVariable(
"ENDMINUTE", $matches[5]);
1518 $template->setVariable(
"ENDSECOND", $matches[6]);
1520 $template->setVariable(
"YEARNOW", $datenow[
"year"]);
1521 $template->setVariable(
"MONTHNOW", $datenow[
"mon"] - 1);
1522 $template->setVariable(
"DAYNOW", $datenow[
"mday"]);
1523 $template->setVariable(
"HOURNOW", $datenow[
"hours"]);
1524 $template->setVariable(
"MINUTENOW", $datenow[
"minutes"]);
1525 $template->setVariable(
"SECONDNOW", $datenow[
"seconds"]);
1526 $template->setVariable(
"PTIME_M", $processing_time_minutes);
1527 $template->setVariable(
"PTIME_S", $processing_time_seconds);
1529 if($this->ctrl->getCmd() ==
'outQuestionSummary') {
1530 $a = $this->ctrl->getFormAction($this,
'redirectAfterDashboardCmd');
1531 $template->setVariable(
"REDIRECT_URL", $this->ctrl->getFormAction($this,
'redirectAfterDashboardCmd',
'',
false,
false));
1533 $template->setVariable(
"REDIRECT_URL",
"");
1536 $this->tpl->setCurrentBlock(
"HeadContent");
1537 $this->tpl->setVariable(
"CONTENT_BLOCK",
$template->get());
1538 $this->tpl->parseCurrentBlock();
1542 protected function showSideList($presentationMode, $currentSequenceElement)
1547 $sideListActive =
$ilUser->getPref(
'side_list_of_questions');
1549 if ($sideListActive) {
1555 $questionSummaryData = $this->service->getQuestionSummaryData($this->testSequence,
false);
1557 require_once
'Modules/Test/classes/class.ilTestQuestionSideListGUI.php';
1559 $questionSideListGUI->setTargetGUI($this);
1560 $questionSideListGUI->setQuestionSummaryData($questionSummaryData);
1561 $questionSideListGUI->setCurrentSequenceElement($currentSequenceElement);
1564 $questionSideListGUI->setDisabled(
false);
1568 $this->tpl->setVariable(
'LIST_OF_QUESTIONS', $questionSideListGUI->getHTML());
1577 public function outQuestionSummaryCmd($fullpage =
true, $contextFinishTest =
false, $obligationsInfo =
false, $obligationsFilter =
false)
1580 $this->tpl->addBlockFile($this->
getContentBlockName(),
"adm_content",
"tpl.il_as_tst_question_summary.html",
"Modules/Test");
1584 $this->object->getId(),
1585 $this->testSession->getActiveId(),
1586 $this->testSession->getPass()
1589 if ($obligationsInfo && $this->object->areObligationsEnabled() && !$obligationsFulfilled) {
1593 if ($this->object->getKioskMode() && $fullpage) {
1595 if (strlen($head)) {
1596 $this->tpl->setCurrentBlock(
"kiosk_options");
1597 $this->tpl->setVariable(
"KIOSK_HEAD", $head);
1598 $this->tpl->parseCurrentBlock();
1603 $active_id = $this->testSession->getActiveId();
1604 $questionSummaryData = $this->service->getQuestionSummaryData($this->testSequence, $obligationsFilter);
1606 $this->ctrl->setParameter($this,
"sequence",
$_GET[
"sequence"]);
1609 include_once
"./Modules/Test/classes/tables/class.ilListOfQuestionsTableGUI.php";
1612 $table_gui->setShowPointsEnabled(!$this->object->getTitleOutput());
1613 $table_gui->setShowMarkerEnabled($this->object->getShowMarker());
1614 $table_gui->setObligationsNotAnswered(!$obligationsFulfilled);
1615 $table_gui->setShowObligationsEnabled($this->object->areObligationsEnabled());
1616 $table_gui->setObligationsFilterEnabled($obligationsFilter);
1621 $table_gui->setData($questionSummaryData);
1623 $this->tpl->setVariable(
'TABLE_LIST_OF_QUESTIONS', $table_gui->getHTML());
1625 if ($this->object->getEnableProcessingTime()) {
1629 if ($this->object->isShowExamIdInTestPassEnabled()) {
1630 $this->tpl->setCurrentBlock(
'exam_id_footer');
1632 $this->testSession->getActiveId(),
1633 $this->testSession->getPass(),
1634 $this->
object->getId()
1636 $this->tpl->setVariable(
'EXAM_ID_TXT', $this->lng->txt(
'exam_id'));
1637 $this->tpl->parseCurrentBlock();
1654 $this->tpl->addBlockFile($this->
getContentBlockName(),
"adm_content",
"tpl.il_as_tst_max_allowed_users_reached.html",
"Modules/Test");
1655 $this->tpl->setCurrentBlock(
"adm_content");
1656 $this->tpl->setVariable(
"MAX_ALLOWED_USERS_MESSAGE", sprintf($this->lng->txt(
"tst_max_allowed_users_message"), $this->
object->getAllowedUsersTimeGap()));
1657 $this->tpl->setVariable(
"MAX_ALLOWED_USERS_HEADING", sprintf($this->lng->txt(
"tst_max_allowed_users_heading"), $this->
object->getAllowedUsersTimeGap()));
1659 $this->tpl->setVariable(
"TXT_BACK_TO_INFOSCREEN", $this->lng->txt(
"tst_results_back_introduction"));
1660 $this->tpl->setVariable(
"FORMACTION", $this->ctrl->getFormAction($this));
1661 $this->tpl->parseCurrentBlock();
1676 $this->tpl->addBlockFile(
"ADM_CONTENT",
"adm_content",
"tpl.il_as_tst_correct_solution.html",
"Modules/Test");
1678 include_once(
"./Services/Style/Content/classes/class.ilObjStyleSheet.php");
1679 $this->tpl->setCurrentBlock(
"ContentStyle");
1681 $this->tpl->parseCurrentBlock();
1683 $this->tpl->setCurrentBlock(
"SyntaxStyle");
1685 $this->tpl->parseCurrentBlock();
1688 if ($this->object->getShowSolutionAnswersOnly()) {
1692 $this->tpl->setCurrentBlock(
"adm_content");
1694 $this->tpl->setVariable(
"OUTPUT_SOLUTION", $solution);
1695 $this->tpl->setVariable(
"TEXT_BACK", $this->lng->txt(
"back"));
1696 $this->ctrl->saveParameter($this,
"pass");
1697 $this->ctrl->saveParameter($this,
"active_id");
1698 $this->tpl->setVariable(
"URL_BACK", $this->ctrl->getLinkTarget($this,
"outUserResultsOverview"));
1699 $this->tpl->parseCurrentBlock();
1716 $this->tpl->addBlockFile($this->
getContentBlockName(),
"adm_content",
"tpl.il_as_tst_finish_list_of_answers.html",
"Modules/Test");
1718 $result_array = &$this->
object->getTestResult(
1727 foreach ($result_array as $question_data) {
1728 $question = $question_data[
"qid"];
1729 if (is_numeric($question)) {
1730 $this->tpl->setCurrentBlock(
"printview_question");
1731 $question_gui = $this->
object->createQuestionGUI(
"", $question);
1732 $template =
new ilTemplate(
"tpl.il_as_qpl_question_printview.html",
true,
true,
"Modules/TestQuestionPool");
1733 $template->setVariable(
"COUNTER_QUESTION", $counter .
". ");
1734 $template->setVariable(
"QUESTION_TITLE", $question_gui->object->getTitle());
1736 $show_question_only = ($this->
object->getShowSolutionAnswersOnly()) ?
true :
false;
1737 $result_output = $question_gui->getSolutionOutput($active_id,
$pass,
false,
false, $show_question_only, $this->object->getShowSolutionFeedback());
1738 $template->setVariable(
"SOLUTION_OUTPUT", $result_output);
1739 $this->tpl->setVariable(
"QUESTION_OUTPUT",
$template->get());
1740 $this->tpl->parseCurrentBlock();
1746 if ($this->object->getShowSolutionAnswersOnly()) {
1749 if (strlen($top_data)) {
1750 $this->tpl->setCurrentBlock(
"top_data");
1751 $this->tpl->setVariable(
"TOP_DATA", $top_data);
1752 $this->tpl->parseCurrentBlock();
1755 if (strlen($bottom_data)) {
1756 $this->tpl->setCurrentBlock(
"bottom_data");
1757 $this->tpl->setVariable(
"FORMACTION", $this->ctrl->getFormAction($this));
1758 $this->tpl->setVariable(
"BOTTOM_DATA", $bottom_data);
1759 $this->tpl->parseCurrentBlock();
1762 $this->tpl->setCurrentBlock(
"adm_content");
1763 $this->tpl->setVariable(
"TXT_ANSWER_SHEET", $this->lng->txt(
"tst_list_of_answers"));
1766 $this->tpl->setVariable(
"USER_DETAILS", $user_data);
1767 $this->tpl->setVariable(
"SIGNATURE", $signature);
1768 $this->tpl->setVariable(
"TITLE", $this->object->getTitle());
1769 $this->tpl->setVariable(
"TXT_TEST_PROLOG", $this->lng->txt(
"tst_your_answers"));
1770 $invited_user = &$this->
object->getInvitedUsers(
$ilUser->getId());
1771 $pagetitle = $this->
object->getTitle() .
" - " . $this->lng->txt(
"clientip") .
1772 ": " . $invited_user[
$ilUser->getId()][
"clientip"] .
" - " .
1773 $this->lng->txt(
"matriculation") .
": " .
1774 $invited_user[
$ilUser->getId()][
"matriculation"];
1775 $this->tpl->setVariable(
"PAGETITLE", $pagetitle);
1776 $this->tpl->parseCurrentBlock();
1786 if ($this->object->getKioskMode()) {
1787 $this->tpl->setBodyClass(
"kiosk");
1788 $this->tpl->setAddFooter(
false);
1791 return "ADM_CONTENT";
1797 $this->ctrl->redirectByClass(
1798 array(
'ilRepositoryGUI',
'ilObjTestGUI',
'ilTestEvaluationGUI'),
1799 "outUserResultsOverview" 1812 $this->ctrl->setParameter($this,
'pmode', self::PRESENTATION_MODE_EDIT);
1814 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintRequestGUI.php';
1827 $this->ctrl->setParameter($this,
'pmode', self::PRESENTATION_MODE_EDIT);
1829 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintRequestGUI.php';
1848 $this->tpl->addBlockFile(
1851 'tpl.il_as_tst_question_summary.html',
1855 if ($this->object->getKioskMode()) {
1862 $this->tpl->addBlockFile(
1865 'tpl.il_as_tst_output.html',
1876 if (strlen($head)) {
1877 $this->tpl->setCurrentBlock(
"kiosk_options");
1878 $this->tpl->setVariable(
"KIOSK_HEAD", $head);
1879 $this->tpl->parseCurrentBlock();
1885 if ($this->ctrl->getNextClass() ==
'iltestpasswordprotectiongui') {
1889 if (!$this->passwordChecker->isPasswordProtectionPageRedirectRequired()) {
1895 $nextCommand = $this->ctrl->getCmdClass() .
'::' . $this->ctrl->getCmd();
1896 $this->ctrl->setParameterByClass(
'ilTestPasswordProtectionGUI',
'nextCommand', $nextCommand);
1897 $this->ctrl->redirectByClass(
'ilTestPasswordProtectionGUI',
'showPasswordForm');
1902 if ($this->object->isInstantFeedbackAnswerFixationEnabled() && $this->testSequence->isQuestionChecked($questionId)) {
1906 if ($this->object->isFollowupQuestionAnswerFixationEnabled() && $this->testSequence->isNextQuestionPresented($questionId)) {
1918 return $this->lng->txt(
"save_introduction");
1923 $this->assSettings =
new ilSetting(
'assessment');
1932 $questionList->load();
1934 $testResults = $this->
object->getTestResult($testSession->
getActiveId(), $testSession->
getPass(),
true);
1936 require_once
'Modules/Test/classes/class.ilTestSkillEvaluation.php';
1937 $skillEvaluation =
new ilTestSkillEvaluation($this->db, $this->object->getTestId(), $this->
object->getRefId());
1940 $skillEvaluation->setActiveId($testSession->
getActiveId());
1941 $skillEvaluation->setPass($testSession->
getPass());
1943 $skillEvaluation->setNumRequiredBookingsForSkillTriggering($this->assSettings->get(
1944 'ass_skl_trig_num_answ_barrier',
1949 $skillEvaluation->init($questionList);
1950 $skillEvaluation->evaluate($testResults);
1952 $skillEvaluation->handleSkillTriggering();
1959 require_once
'Modules/Test/classes/confirmations/class.ilTestAnswerOptionalQuestionsConfirmationGUI.php';
1962 $confirmation->setFormAction($this->ctrl->getFormAction($this));
1963 $confirmation->setCancelCmd(
'cancelAnswerOptionalQuestions');
1964 $confirmation->setConfirmCmd(
'confirmAnswerOptionalQuestions');
1966 $confirmation->build($this->object->isFixedTest());
1973 $this->testSequence->setAnsweringOptionalQuestionsConfirmed(
true);
1974 $this->testSequence->saveToDb();
1976 $this->ctrl->setParameter($this,
'activecommand',
'gotoquestion');
1977 $this->ctrl->redirect($this,
'redirectQuestion');
1982 if ($this->object->getListOfQuestions()) {
1983 $this->ctrl->setParameter($this,
'activecommand',
'summary');
1985 $this->ctrl->setParameter($this,
'activecommand',
'previous');
1988 $this->ctrl->redirect($this,
'redirectQuestion');
1996 if ($this->object->getKioskMode()) {
1997 $this->tpl->setBodyClass(
"kiosk");
1999 $this->tpl->addBlockfile(
'CONTENT',
'content',
"tpl.il_as_tst_kiosk_mode_content.html",
"Modules/Test");
2000 $this->tpl->setContent($this->ctrl->getHTML($helperGui));
2014 if (
$ilSetting->get(
'char_selector_availability') > 0) {
2015 require_once
'Services/UIComponent/CharSelector/classes/class.ilCharSelectorGUI.php';
2018 $char_selector->addToPage();
2019 $this->tpl->setCurrentBlock(
'char_selector');
2020 $this->tpl->setVariable(
"CHAR_SELECTOR_TEMPLATE", $char_selector->getSelectorHtml());
2021 $this->tpl->parseCurrentBlock();
2035 require_once
'Modules/Test/classes/class.ilTestNavigationToolbarGUI.php';
2038 $navigationToolbarGUI->setSuspendTestButtonEnabled($this->object->getShowCancel());
2039 $navigationToolbarGUI->setQuestionTreeButtonEnabled($this->object->getListOfQuestions());
2040 $navigationToolbarGUI->setQuestionTreeVisible(
$ilUser->getPref(
'side_list_of_questions'));
2041 $navigationToolbarGUI->setQuestionListButtonEnabled($this->object->getListOfQuestions());
2044 return $navigationToolbarGUI;
2049 require_once
'Modules/Test/classes/class.ilTestQuestionNavigationGUI.php';
2056 if ($this->object->getShowMarker()) {
2057 include_once
"./Modules/Test/classes/class.ilObjTest.php";
2061 if (count($solved_array) > 0) {
2062 $solved = array_pop($solved_array);
2063 $solved = $solved[
"solved"];
2068 $navigationGUI->setQuestionMarked(
true);
2071 $navigationGUI->setQuestionMarked(
false);
2076 return $navigationGUI;
2081 require_once
'Modules/Test/classes/class.ilTestQuestionNavigationGUI.php';
2084 if ($this->object->isForceInstantFeedbackEnabled()) {
2099 case $this->
object->getSpecificAnswerFeedback():
2100 case $this->
object->getGenericAnswerFeedback():
2101 case $this->
object->getAnswerFeedbackPoints():
2102 case $this->
object->getInstantFeedbackSolution():
2104 $navigationGUI->setAnswerFreezingEnabled($this->object->isInstantFeedbackAnswerFixationEnabled());
2106 if ($this->object->isForceInstantFeedbackEnabled()) {
2107 $navigationGUI->setForceInstantResponseEnabled(
true);
2115 if ($this->object->isOfferingQuestionHintsEnabled()) {
2116 $activeId = $this->testSession->getActiveId();
2117 $pass = $this->testSession->getPass();
2119 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintTracking.php';
2122 if ($questionHintTracking->requestsPossible()) {
2126 if ($questionHintTracking->requestsExist()) {
2131 $navigationGUI->setCharSelectorEnabled($charSelectorAvailable);
2133 if ($this->object->getShowMarker()) {
2134 include_once
"./Modules/Test/classes/class.ilObjTest.php";
2138 if (count($solved_array) > 0) {
2139 $solved = array_pop($solved_array);
2140 $solved = $solved[
"solved"];
2146 $navigationGUI->setQuestionMarked(
true);
2149 $navigationGUI->setQuestionMarked(
false);
2153 return $navigationGUI;
2161 if (!$this->object->getListOfQuestionsEnd()) {
2162 return 'finishTest';
2165 if ($this->object->areObligationsEnabled()) {
2167 $this->testSession->getTestId(),
2168 $this->testSession->getActiveId(),
2169 $this->testSession->getPass()
2172 if (!$allObligationsAnswered) {
2173 return 'outQuestionSummaryWithObligationsInfo';
2177 return 'outQuestionSummary';
2209 $answerFeedbackEnabled = $this->
object->getSpecificAnswerFeedback();
2212 $this->testSession->getActiveId(), #active_id
2213 $this->testSession->getPass(), #pass
2214 false, #graphical_output
2215 false, #result_output
2216 true, #show_question_only
2217 $answerFeedbackEnabled, #show_feedback
2218 false, #show_correct_solution
2219 false, #show_manual_scoring
2220 true #show_question_text
2226 $this->testSession->getActiveId(),
2230 $tpl =
new ilTemplate(
'tpl.tst_player_response_modal.html',
true,
true,
'Modules/Test');
2236 $this->tpl = $saved_tpl;
2238 $tpl->setVariable(
'QUESTION_OUTPUT', $pageoutput);
2241 $button->setId(
'tst_confirm_feedback');
2242 $button->setUrl($navUrl);
2243 $button->setCaption(
'proceed');
2244 $button->setPrimary(
true);
2245 $tpl->setVariable(
'BUTTON', $button->render());
2248 require_once(
'Services/UIComponent/Modal/classes/class.ilModalGUI.php');
2251 $modal->setId(
'tst_question_feedback_modal');
2252 $modal->setHeading($this->lng->txt(
'tst_instant_feedback'));
2253 $modal->setBody(
$tpl->get());
2255 $this->tpl->addOnLoadCode(
"$('#tst_question_feedback_modal').modal('show');");
2256 $this->tpl->setVariable(
'INSTANT_RESPONSE_MODAL', $modal->getHTML());
2267 !$this->object->getSpecificAnswerFeedback() || !$questionGui->
hasInlineFeedback()
2272 if ($this->object->getInstantFeedbackSolution()) {
2277 $this->testSession->getActiveId(), #active_id
2279 false, #graphical_output
2280 $show_question_inline_score, #result_output
2281 true, #show_question_only
2282 false, #show_feedback
2283 true, #show_correct_solution
2284 false, #show_manual_scoring
2285 false #show_question_text
2287 $solutionoutput = str_replace(
'<h1 class="ilc_page_title_PageTitle"></h1>',
'', $solutionoutput);
2291 $reachedPoints = $questionGui->object->getAdjustedReachedPoints(
2292 $this->testSession->getActiveId(),
2297 $maxPoints = $questionGui->object->getMaximumPoints();
2299 $solutionCorrect = ($reachedPoints == $maxPoints);
2303 if ($this->object->getAnswerFeedbackPoints()) {
2309 if ($this->object->getGenericAnswerFeedback()) {
2315 if ($this->object->getSpecificAnswerFeedback()) {
2322 if ($withFocusAnchor) {
2323 $this->tpl->setCurrentBlock(
'inst_resp_id');
2324 $this->tpl->setVariable(
'INSTANT_RESPONSE_FOCUS_ID',
'focus');
2325 $this->tpl->parseCurrentBlock();
2328 $this->tpl->setCurrentBlock(
'instant_response_header');
2329 $this->tpl->setVariable(
'INSTANT_RESPONSE_HEADER', $this->lng->txt(
'tst_feedback'));
2330 $this->tpl->parseCurrentBlock();
2339 return $this->testSession->getLastSequence();
2344 unset(
$_GET[
'sequence']);
2345 $this->ctrl->setParameter($this,
'sequence', null);
2350 if (isset(
$_GET[
'sequence'])) {
2351 return $_GET[
'sequence'];
2359 if (isset(
$_GET[
'pmode'])) {
2360 return $_GET[
'pmode'];
2368 if (isset(
$_GET[
'instresp'])) {
2369 return $_GET[
'instresp'];
2377 if (isset(
$_POST[
'nextcmd']) && strlen(
$_POST[
'nextcmd'])) {
2378 return $_POST[
'nextcmd'];
2386 if (isset(
$_POST[
'nextseq']) && is_numeric(
$_POST[
'nextseq'])) {
2387 return (
int)
$_POST[
'nextseq'];
2396 if (isset(
$_POST[
'test_player_navigation_url'])) {
2397 return $_POST[
'test_player_navigation_url'];
2411 return !empty(
$_GET[
'test_answer_changed']);
2420 $this->ctrl->setParameter($this,
'test_answer_changed',
$changed ?
'1' :
'0');
2446 if (!empty(
$_POST[
'save_on_navigation_prevent_confirmation'])) {
2447 $_SESSION[
'save_on_navigation_prevent_confirmation'] =
true;
2450 if (!empty(
$_POST[self::FOLLOWUP_QST_LOCKS_PREVENT_CONFIRMATION_PARAM])) {
2451 $_SESSION[self::FOLLOWUP_QST_LOCKS_PREVENT_CONFIRMATION_PARAM] =
true;
2471 if (!$fromCache || !isset($this->cachedQuestionGuis[$questionId])) {
2472 $questionGui = $this->
object->createQuestionGUI(
"", $questionId);
2473 $questionGui->setTargetGui($this);
2475 $questionGui->object->setObligationsToBeConsidered($this->object->areObligationsEnabled());
2476 $questionGui->populateJavascriptFilesRequiredForWorkForm(
$tpl);
2484 $this->cachedQuestionGuis[$questionId] = $questionGui;
2487 return $this->cachedQuestionGuis[$questionId];
2502 $ilDB = $DIC[
'ilDB'];
2505 if (!$fromCache || !isset($this->cachedQuestionObjects[$questionId])) {
2509 require_once
'Modules/TestQuestionPool/classes/class.ilAssQuestionProcessLockerFactory.php';
2511 $processLockerFactory->setQuestionId($questionOBJ->getId());
2512 $processLockerFactory->setUserId(
$ilUser->getId());
2513 include_once(
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
2515 $questionOBJ->setProcessLocker($processLockerFactory->getLocker());
2517 $questionOBJ->setObligationsToBeConsidered($this->object->areObligationsEnabled());
2524 $this->cachedQuestionObjects[$questionId] = $questionOBJ;
2527 return $this->cachedQuestionObjects[$questionId];
2534 $this->object->isPreviousSolutionReuseEnabled($this->testSession->getActiveId())
2545 require_once
'Services/Randomization/classes/class.ilArrayElementShuffler.php';
2549 $shuffler->setSeed($fixedSeed);
2566 .
"active={$this->testSession->getActiveId()} " 2567 .
"qId=$questionId seq=$sequenceElement " 2568 . serialize($this->testSequence)
2571 $ilLog->logStack(
'INV SEQ');
2573 $this->ctrl->setParameter($this,
'sequence', $this->testSequence->getFirstSequence());
2582 if ($this->object->getKioskMode()) {
2583 $this->tpl->addBlockfile($this->
getContentBlockName(),
'content',
"tpl.il_as_tst_kiosk_mode_content.html",
"Modules/Test");
2584 $this->tpl->setContent($contentHTML);
2592 require_once
'Services/UIComponent/Button/classes/class.ilSubmitButton.php';
2593 require_once
'Services/UIComponent/Button/classes/class.ilLinkButton.php';
2594 require_once
'Services/UIComponent/Modal/classes/class.ilModalGUI.php';
2601 if ($this->object->isFollowupQuestionAnswerFixationEnabled()) {
2607 if ($this->object->getKioskMode()) {
2614 $tpl =
new ilTemplate(
'tpl.tst_player_confirmation_modal.html',
true,
true,
'Modules/Test');
2616 $tpl->setVariable(
'CONFIRMATION_TEXT', $this->lng->txt(
'discard_answer_confirmation'));
2620 $button->setCaption(
'discard_answer');
2621 $tpl->setCurrentBlock(
'buttons');
2622 $tpl->setVariable(
'BUTTON', $button->render());
2623 $tpl->parseCurrentBlock();
2626 $button->setId(
'tst_cancel_discard_button');
2627 $button->setCaption(
'cancel');
2628 $button->setPrimary(
true);
2629 $tpl->setCurrentBlock(
'buttons');
2630 $tpl->setVariable(
'BUTTON', $button->render());
2631 $tpl->parseCurrentBlock();
2634 $modal->setId(
'tst_discard_solution_modal');
2635 $modal->setHeading($this->lng->txt(
'discard_answer'));
2636 $modal->setBody(
$tpl->get());
2638 $this->tpl->setCurrentBlock(
'discard_solution_modal');
2639 $this->tpl->setVariable(
'DISCARD_SOLUTION_MODAL', $modal->getHTML());
2640 $this->tpl->parseCurrentBlock();
2709 if (!empty(
$_SESSION[
'save_on_navigation_prevent_confirmation'])) {
2713 $tpl =
new ilTemplate(
'tpl.tst_player_confirmation_modal.html',
true,
true,
'Modules/Test');
2715 if ($this->object->isInstantFeedbackAnswerFixationEnabled() && $this->
object->isForceInstantFeedbackEnabled()) {
2716 $text = $this->lng->txt(
'save_on_navigation_locked_confirmation');
2718 $text = $this->lng->txt(
'save_on_navigation_confirmation');
2720 if ($this->object->isForceInstantFeedbackEnabled()) {
2721 $text .=
" " . $this->lng->txt(
'save_on_navigation_forced_feedback_hint');
2723 $tpl->setVariable(
'CONFIRMATION_TEXT',
$text);
2727 $button->setId(
'tst_save_on_navigation_button');
2728 $button->setUrl(
'#');
2729 $button->setCaption(
'tst_save_and_proceed');
2730 $button->setPrimary(
true);
2731 $tpl->setCurrentBlock(
'buttons');
2732 $tpl->setVariable(
'BUTTON', $button->render());
2733 $tpl->parseCurrentBlock();
2736 $button->setId(
'tst_cancel_on_navigation_button');
2737 $button->setUrl(
'#');
2738 $button->setCaption(
'cancel');
2739 $button->setPrimary(
false);
2740 $tpl->setCurrentBlock(
'buttons');
2741 $tpl->setVariable(
'BUTTON', $button->render());
2742 $tpl->parseCurrentBlock();
2744 $tpl->setCurrentBlock(
'checkbox');
2745 $tpl->setVariable(
'CONFIRMATION_CHECKBOX_NAME',
'save_on_navigation_prevent_confirmation');
2746 $tpl->setVariable(
'CONFIRMATION_CHECKBOX_LABEL', $this->lng->txt(
'tst_dont_show_msg_again_in_current_session'));
2747 $tpl->parseCurrentBlock();
2750 $modal->setId(
'tst_save_on_navigation_modal');
2751 $modal->setHeading($this->lng->txt(
'save_on_navigation'));
2752 $modal->setBody(
$tpl->get());
2754 $this->tpl->setCurrentBlock(
'nav_while_edit_modal');
2755 $this->tpl->setVariable(
'NAV_WHILE_EDIT_MODAL', $modal->getHTML());
2756 $this->tpl->parseCurrentBlock();
2762 require_once
'Modules/Test/classes/class.ilTestPlayerConfirmationModal.php';
2764 $modal->setModalId(
'tst_next_locks_unchanged_modal');
2766 $modal->setHeaderText($this->lng->txt(
'tst_nav_next_locks_empty_answer_header'));
2767 $modal->setConfirmationText($this->lng->txt(
'tst_nav_next_locks_empty_answer_confirm'));
2769 $button = $modal->buildModalButtonInstance(
'tst_nav_next_empty_answer_button');
2770 $button->setCaption(
'tst_proceed');
2771 $button->setPrimary(
false);
2772 $modal->addButton($button);
2774 $button = $modal->buildModalButtonInstance(
'tst_cancel_next_empty_answer_button');
2775 $button->setCaption(
'cancel');
2776 $button->setPrimary(
true);
2777 $modal->addButton($button);
2779 $this->tpl->setCurrentBlock(
'next_locks_unchanged_modal');
2780 $this->tpl->setVariable(
'NEXT_LOCKS_UNCHANGED_MODAL', $modal->getHTML());
2781 $this->tpl->parseCurrentBlock();
2790 require_once
'Modules/Test/classes/class.ilTestPlayerConfirmationModal.php';
2792 $modal->setModalId(
'tst_next_locks_changed_modal');
2794 $modal->setHeaderText($this->lng->txt(
'tst_nav_next_locks_current_answer_header'));
2795 $modal->setConfirmationText($this->lng->txt(
'tst_nav_next_locks_current_answer_confirm'));
2797 $modal->setConfirmationCheckboxName(self::FOLLOWUP_QST_LOCKS_PREVENT_CONFIRMATION_PARAM);
2798 $modal->setConfirmationCheckboxLabel($this->lng->txt(
'tst_dont_show_msg_again_in_current_session'));
2800 $button = $modal->buildModalButtonInstance(
'tst_nav_next_changed_answer_button');
2801 $button->setCaption(
'tst_save_and_proceed');
2802 $button->setPrimary(
true);
2803 $modal->addButton($button);
2805 $button = $modal->buildModalButtonInstance(
'tst_cancel_next_changed_answer_button');
2806 $button->setCaption(
'cancel');
2807 $button->setPrimary(
false);
2808 $modal->addButton($button);
2810 $this->tpl->setCurrentBlock(
'next_locks_changed_modal');
2811 $this->tpl->setVariable(
'NEXT_LOCKS_CHANGED_MODAL', $modal->getHTML());
2812 $this->tpl->parseCurrentBlock();
2819 $_SESSION[self::FOLLOWUP_QST_LOCKS_PREVENT_CONFIRMATION_PARAM] =
true;
2824 if (!isset(
$_SESSION[self::FOLLOWUP_QST_LOCKS_PREVENT_CONFIRMATION_PARAM])) {
2828 return $_SESSION[self::FOLLOWUP_QST_LOCKS_PREVENT_CONFIRMATION_PARAM];
2837 protected function populateQuestionEditControl($questionGUI)
2843 $state = $questionGUI->object->lookupForExistingSolutions($this->testSession->getActiveId(), $this->testSession->getPass());
2854 if ($questionGUI->isAutosaveable() && $this->
object->getAutosave()) {
2856 $config[
'autosaveInterval'] = $this->
object->getAutosaveIval();
2859 $config[
'autosaveInterval'] = 0;
2864 $questionConfig = $questionGUI->object->getTestPresentationConfig();
2868 $config[
'withFormChangeDetection'] = $questionConfig->isFormChangeDetectionEnabled();
2871 $config[
'withBackgroundChangeDetection'] = $questionConfig->isBackgroundChangeDetectionEnabled();
2875 $config[
'forcedInstantFeedback'] = $this->
object->isForceInstantFeedbackEnabled();
2876 $config[
'nextQuestionLocks'] = $this->
object->isFollowupQuestionAnswerFixationEnabled();
2878 $this->tpl->addJavascript(
'./Modules/Test/js/ilTestPlayerQuestionEditControl.js');
2879 $this->tpl->addOnLoadCode(
'il.TestPlayerQuestionEditControl.init(' . json_encode(
$config) .
')');
2886 return self::PRESENTATION_MODE_EDIT;
2896 $fixedSeed = $questionId . $this->testSession->getActiveId() . $this->testSession->getPass();
2909 if (!isset(
$_SESSION[
'forced_feedback_navigation_url'])) {
2910 $_SESSION[
'forced_feedback_navigation_url'] = array();
2913 $_SESSION[
'forced_feedback_navigation_url'][$this->testSession->getActiveId()] = $forcedFeedbackNavUrl;
2918 if (!isset(
$_SESSION[
'forced_feedback_navigation_url'])) {
2922 if (!isset(
$_SESSION[
'forced_feedback_navigation_url'][$this->testSession->getActiveId()])) {
2926 return $_SESSION[
'forced_feedback_navigation_url'][$this->testSession->getActiveId()];
2936 if (isset(
$_SESSION[
'forced_feedback_navigation_url'][$this->testSession->getActiveId()])) {
2937 unset(
$_SESSION[
'forced_feedback_navigation_url'][$this->testSession->getActiveId()]);
checkTestSessionUser(ilTestSession $testSession)
static makeDirParents($a_dir)
Create a new directory and all parent directories.
populateSyntaxStyleBlock()
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
submitIntermediateSolutionCmd()
startPlayerCmd()
Start a test for the first time.
populateNextLocksUnchangedModal()
const AFTER_TEST_PASS_FINISHED
populateDiscardSolutionModal()
removeIntermediateSolution()
remove an auto-saved solution of the current question
performTestPassFinishedTasks($finishedPass)
const CMD_CONFIRM_REQUEST
isQuestionSummaryFinishTestButtonRequired()
outObligationsOnlySummaryCmd()
getSpecificFeedbackOutput($userSolution)
Returns the answer specific feedback for the question.
Class ilTestPassFinishTasks.
if((!isset($_SERVER['DOCUMENT_ROOT'])) OR(empty($_SERVER['DOCUMENT_ROOT']))) $_SERVER['DOCUMENT_ROOT']
showAnswerOptionalQuestionsConfirmation()
static allObligationsAnswered($test_id, $active_id, $pass)
checks wether all questions marked as obligatory were answered within the test pass with given testId...
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.
setAnswerChangedParameter($changed=true)
Set the 'answer changed' url parameter for generated links.
isFirstQuestionInSequence($sequenceElement)
populateSpecificFeedbackBlock(assQuestionGUI $question_gui)
populateContentStyleBlock()
handleQuestionActionCmd()
const FOLLOWUP_QST_LOCKS_PREVENT_CONFIRMATION_PARAM
getAccessCodeFromSession()
markQuestionAndSaveIntermediateCmd()
checkOnlineTestAccess()
check access restrictions like client ip, partipating user etc.
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
static getStyleSheetLocation($mode="output", $a_css_name="", $a_css_location="")
get full style sheet file name (path inclusive) of current user
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)
getObjectiveOrientedContainer()
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.
isTestSignRedirectRequired($activeId, $lastFinishedPass)
static get($a_var)
Get a value.
populateHelperGuiContent($helperGui)
const BACK_FROM_FINISHING
const AUTO_SAVE_ON_TIME_LIMIT
getNextCommandParameter()
doesAccessCodeInSessionExists()
populateLowerPreviousButtonBlock($disabled)
toggleSideListCmd()
Toggle side list.
getResultsSignature()
Returns HTML code for a signature field.
cancelAnswerOptionalQuestionsCmd()
isFollowUpQuestionLocksConfirmationPrevented()
setAnonymousId($anonymous_id)
hasInlineFeedback()
this method can be overwritten per question type
const CSS_CLASS_FEEDBACK_CORRECT
const DEFAULT_SKL_TRIG_NUM_ANSWERS_BARRIER
handleUserSettings()
Handles some form parameters on starting and resuming a test.
const BACK_TO_INFO_SCREEN
afterTestPassFinishedCmd()
buildReadOnlyStateQuestionNavigationGUI($questionId)
populateCharSelectorIfRequired()
getContentBlockName()
Returns the name of the current content block (depends on the kiosk mode setting) ...
confirmHintRequestCmd()
Go to hint request confirmation.
static formatDate(ilDateTime $date, $a_skip_day=false, $a_include_wd=false, $include_seconds=false)
Format a date public.
__construct($a_object)
ilTestOutputGUI constructor
Base Exception for all Exceptions relating to Modules/Test.
archiveParticipantSubmission($active, $pass)
maxProcessingTimeReached()
Outputs a message when the maximum processing time is reached.
setFollowUpQuestionLocksConfirmationPrevented()
populateLowerNextButtonBlock($disabled, $primaryNext)
showRequestedHintListCmd()
Go to requested hint list.
prepareTestPage($presentationMode, $sequenceElement, $questionId)
getCorrectSolutionOutput($question_id, $active_id, $pass, ilTestQuestionRelatedObjectivesList $objectivesList=null)
Returns an output of the solution to an answer compared to the correct solution.
populateNavWhenChangedModal()
unregisterForcedFeedbackNavUrl()
populateInstantResponseBlocks(assQuestionGUI $questionGui, $authorizedSolution)
static sendInfo($a_info="", $a_keep=false)
Send Info Message to Screen.
buildQuestionRelatedObjectivesList(ilLOTestQuestionAdapter $objectivesAdapter, ilTestQuestionSequence $testSequence)
isNrOfTriesReached()
nr of tries exceeded
ensureExistingTestSession(ilTestSession $testSession)
if(!array_key_exists('stateid', $_REQUEST)) $state
Handle linkback() response from LinkedIn.
populateQuestionNavigation($sequenceElement, $disabled, $primaryNext)
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 getInstance(ilTestSession $a_test_session)
initTestQuestionConfig(assQuestion $questionOBJ)
confirmFinishCmd()
The final submission of a test was confirmed.
markQuestionCmd()
Set a question solved.
handleIntermediateSubmit()
Check the 'answer changed' parameter when a question form is intermediately submitted.
isForcedFeedbackNavUrlRegistered()
static _enabledAssessmentLogging()
check wether assessment logging is enabled or not
foreach($_POST as $key=> $value) $res
getInstantResponseParameter()
handleSkillTriggering(ilTestSession $testSession)
buildEditableStateQuestionNavigationGUI($questionId, $charSelectorAvailable)
buildTestPassQuestionList()
$maxProcessingTimeReached
outQuestionSummaryCmd($fullpage=true, $contextFinishTest=false, $obligationsInfo=false, $obligationsFilter=false)
Output of a summary of all test questions for test participants.
showSideList($presentationMode, $currentSequenceElement)
populateGenericFeedbackBlock(assQuestionGUI $question_gui, $solutionCorrect)
getRegisteredForcedFeedbackNavUrl()
populatePreviousButtons($disabled)
outQuestionSummaryWithObligationsInfoCmd()
outCorrectSolution()
Creates an output of the solution of an answer compared to the correct solution.
const CONFIRM_HINT_REQUEST
getIntroductionPageButtonLabel()
special template class to simplify handling of ITX/PEAR
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
const ACCESS_CODE_CONFIRMED
static _getSolvedQuestions($active_id, $question_fi=null)
get solved questions
const REDIRECT_ON_TIME_LIMIT
Output class for assessment test evaluation.
populateTestNavigationToolbar(ilTestNavigationToolbarGUI $toolbarGUI)
redirection script todo: (a better solution should control the processing via a xml file) ...
const SHOW_INSTANT_RESPONSE
static _getCurrentGUI(ilObjTest $a_test_obj=null)
Get the GUI that is used for the currently available selector (other GUI instances may exist for conf...
static getSyntaxStylePath()
get syntax style path
const CSS_CLASS_FEEDBACK_WRONG
static getContentStylePath($a_style_id, $add_random=true)
get content style path
getAnswerChangedParameter()
Get the 'answer changed' status from the current request It may be set by ilTestPlayerNavigationContr...
getSequenceElementParameter()
Basic GUI class for assessment questions.
populateNextLocksChangedModal()
detectChangesCmd()
Detect changes sent in the background to the server This is called by ajax from ilTestPlayerQuestionE...
const PRESENTATION_MODE_VIEW
const PRESENTATION_CONTEXT_TEST
initProcessLocker($activeId)
static _instantiateQuestion($question_id)
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
isShowingPostponeStatusReguired($questionId)
unmarkQuestionCmd()
Set a question unsolved.
handlePasswordProtectionRedirect()
redirectAfterDashboardCmd()
Multiple choice question GUI representation.
const UNMARK_QUESTION_SAVE
registerForcedFeedbackNavUrl($forcedFeedbackNavUrl)
const QUESTION_SUMMARY_OBLIGATIONS_ONLY
static getInstance()
Get instance.
populateUpperNextButtonBlock($disabled, $primaryNext)
isOptionalQuestionAnsweringConfirmationRequired($sequenceElement)
const CMD_SHOW_LIST
command constants
showQuestionViewable(assQuestionGUI $questionGui, $formAction, $isQuestionWorkedThrough, $instantResponse)
isTestAccessible()
test accessible returns true if the user can perform the test
populateNextButtons($disabled, $primaryNext)
populateMessageContent($contentHTML)
populateUpperPreviousButtonBlock($disabled)
const DISPLAY_ACCESS_CODE
performFinishTasks(ilTestProcessLocker $processLocker)
outQuestionPage($a_temp_var, $a_postponed=false, $active_id="", $html="", $inlineFeedbackEnabled=false)
output question page
buildQuestionAnswerShuffler($questionId)
showMaximumAllowedUsersReachedMessage()
resetSequenceElementParameter()
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)
outProcessingTime($active_id)
getNextSequenceParameter()
determineInlineScoreDisplay()
getTestPresentationConfig()
Get the test question configuration (initialised once)
outQuestionForTest( $formaction, $active_id, $pass, $is_question_postponed=false, $user_post_solutions=false, $show_specific_inline_feedback=false)
getNavigationUrlParameter()
getQuestionHeaderBlockBuilder()
getQuestionGuiInstance($questionId, $fromCache=true)
static buildExamId($active_id, $pass, $test_obj_id=null)
const FIXED_SHUFFLER_SEED_MIN_LENGTH
getQuestionInstance($questionId, $fromCache=true)
getQuestionsDefaultPresentationMode($isQuestionWorkedThrough)
unmarkQuestionAndSaveIntermediateCmd()
Service GUI class for tests.
static generatePDF($pdf_output, $output_mode, $filename=null, $purpose=null)
initTestCmd()
Start a test for the first time after a redirect.
buildPreviousButtonInstance($disabled)
getGenericFeedbackOutput($active_id, $pass)
Returns the answer specific feedback for the question.
finishTestCmd($requires_confirmation=true)
handleTearsAndAngerQuestionIsNull($questionId, $sequenceElement)
isMaxProcessingTimeReached()
Checks wheather the maximum processing time is reached or not.
getCurrentSequenceElement()
buildNextButtonInstance($disabled, $primaryNext)
static _getUsePreviousAnswers($active_id, $user_active_user_setting=false)
Returns if the previous results should be hidden for a learner.
static redirect($a_script)
confirmAnswerOptionalQuestionsCmd()
static getWebspaceDir($mode="filesystem")
get webspace directory
populateFeedbackBlockHeader($withFocusAnchor)
getTestNavigationToolbarGUI()
populateSolutionBlock($solutionoutput)
populateScoreBlock($reachedPoints, $maxPoints)
isParticipantsAnswerFixed($questionId)
Output class for assessment test execution.
Confirmation screen class.
autosaveOnTimeLimitCmd()
Automatically save a user answer when the limited duration of a test run is reached (called by synchr...
static lookupExamId($active_id, $pass)
setNavigationGUI($navigationGUI)
buildFixedShufflerSeed($questionId)