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