4require_once 
'./Modules/Test/classes/inc.AssessmentConstants.php';
 
    5require_once 
'./Modules/Test/classes/class.ilTestPlayerCommands.php';
 
    6require_once 
'./Modules/Test/classes/class.ilTestServiceGUI.php';
 
    7require_once 
'./Modules/TestQuestionPool/classes/class.assQuestion.php';
 
    8require_once 
'./Services/UIComponent/Button/classes/class.ilSubmitButton.php';
 
    9require_once 
'Modules/Test/classes/class.ilTestPlayerNavButton.php';
 
   71        parent::__construct($a_object);
 
   72        $this->ref_id = 
$_GET[
"ref_id"];
 
   75        require_once 
'Modules/Test/classes/class.ilTestPasswordChecker.php';
 
   78        $this->processLocker = 
null;
 
   79        $this->testSession = 
null;
 
   80        $this->assSettings = 
null;
 
   87        if (!$rbacsystem->checkAccess(
"read", $this->object->getRefId())) {
 
   89            $this->
ilias->raiseError($this->lng->txt(
"cannot_execute_test"), $this->ilias->error_obj->MESSAGE);
 
   95        $executable = $this->
object->isExecutable($this->testSession, $this->testSession->getUserId());
 
   97        if (!$executable[
'executable']) {
 
   99            $this->ctrl->redirectByClass(
"ilobjtestgui", 
"infoScreen");
 
  108            throw new ilTestException(
'active id given does not relate to current user!');
 
  137        require_once 
'Modules/Test/classes/class.ilTestProcessLockerFactory.php';
 
  140        $processLockerFactory->setActiveId($activeId);
 
  142        $this->processLocker = $processLockerFactory->getLocker();
 
  153        include_once(
"./Services/Tagging/classes/class.ilTaggingGUI.php");
 
  155        $tagging_gui->setObject($this->object->getId(), $this->object->getType());
 
  156        $tagging_gui->saveInput();
 
  157        $this->ctrl->redirectByClass(
"ilobjtestgui", 
"infoScreen");
 
  166            $this->
object->updateWorkingTime(
$_SESSION[
"active_time_id"]);
 
  169        $_SESSION[
"active_time_id"] = $this->
object->startWorkingTime(
 
  170            $this->testSession->getActiveId(),
 
  171            $this->testSession->getPass()
 
  185            $this->testSession->getActiveId(),
 
  186            $this->testSession->getPass()
 
  200        $this->ctrl->redirectByClass(
"ilobjtestgui", 
"infoScreen");
 
  213        $active_id = $this->testSession->getActiveId();
 
  214        $starting_time = $this->
object->getStartingTimeOfUser($active_id);
 
  215        if ($starting_time === 
false) {
 
  218            return $this->
object->isMaxProcessingTimeReached($starting_time, $active_id);
 
  224        $show_question_inline_score = 
false;
 
  225        if ($this->object->getAnswerFeedbackPoints()) {
 
  226            $show_question_inline_score = 
true;
 
  227            return $show_question_inline_score;
 
  229        return $show_question_inline_score;
 
  234        $this->tpl->setCurrentBlock(
'test_nav_toolbar');
 
  235        $this->tpl->setVariable(
'TEST_NAV_TOOLBAR', $toolbarGUI->getHTML());
 
  236        $this->tpl->parseCurrentBlock();
 
  265        $button->setId(
'bottomnextbutton');
 
  267        $this->tpl->setCurrentBlock(
"next_bottom");
 
  268        $this->tpl->setVariable(
"BTN_NEXT", $button->render());
 
  269        $this->tpl->parseCurrentBlock();
 
  275        $button->setId(
'nextbutton');
 
  277        $this->tpl->setCurrentBlock(
"next");
 
  278        $this->tpl->setVariable(
"BTN_NEXT", $button->render());
 
  279        $this->tpl->parseCurrentBlock();
 
  285        $button->setId(
'bottomprevbutton');
 
  287        $this->tpl->setCurrentBlock(
"prev_bottom");
 
  288        $this->tpl->setVariable(
"BTN_PREV", $button->render());
 
  289        $this->tpl->parseCurrentBlock();
 
  295        $button->setId(
'prevbutton');
 
  297        $this->tpl->setCurrentBlock(
"prev");
 
  298        $this->tpl->setVariable(
"BTN_PREV", $button->render());
 
  299        $this->tpl->parseCurrentBlock();
 
  311        $button->setPrimary($primaryNext);
 
  312        $button->setRightGlyph(
'glyphicon glyphicon-arrow-right');
 
  316        $button->setCaption(
'next_question');
 
  317        $button->addCSSClass(
'ilTstNavElem');
 
  330        $button->setLeftGlyph(
'glyphicon glyphicon-arrow-left');
 
  334        $button->setCaption(
'previous_question');
 
  335        $button->addCSSClass(
'ilTstNavElem');
 
  342        $this->tpl->setCurrentBlock(
"specific_feedback");
 
  343        $this->tpl->setVariable(
 
  345            $question_gui->getSpecificFeedbackOutput(
 
  346                                     $this->testSession->getActiveId(),
 
  350        $this->tpl->parseCurrentBlock();
 
  357        if (strlen($feedback)) {
 
  363            $this->tpl->setCurrentBlock(
"answer_feedback");
 
  364            $this->tpl->setVariable(
"ANSWER_FEEDBACK", $feedback);
 
  365            $this->tpl->setVariable(
"ILC_FB_CSS_CLASS", $cssClass);
 
  366            $this->tpl->parseCurrentBlock();
 
  373            $this->lng->txt(
"you_received_a_of_b_points"),
 
  378        $this->tpl->setCurrentBlock(
"received_points_information");
 
  379        $this->tpl->setVariable(
"RECEIVED_POINTS_INFORMATION", $scoreInformation);
 
  380        $this->tpl->parseCurrentBlock();
 
  385        if (strlen($solutionoutput)) {
 
  386            $this->tpl->setCurrentBlock(
"solution_output");
 
  387            $this->tpl->setVariable(
"CORRECT_SOLUTION", $this->lng->txt(
"tst_best_solution_is"));
 
  388            $this->tpl->setVariable(
"QUESTION_FEEDBACK", $solutionoutput);
 
  389            $this->tpl->parseCurrentBlock();
 
  395        $this->tpl->setCurrentBlock(
"SyntaxStyle");
 
  396        $this->tpl->setVariable(
 
  397            "LOCATION_SYNTAX_STYLESHEET",
 
  400        $this->tpl->parseCurrentBlock();
 
  405        include_once(
"./Services/Style/Content/classes/class.ilObjStyleSheet.php");
 
  406        $this->tpl->setCurrentBlock(
"ContentStyle");
 
  407        $this->tpl->setVariable(
 
  408            "LOCATION_CONTENT_STYLESHEET",
 
  411        $this->tpl->parseCurrentBlock();
 
  421        if ($this->testSession->isAnonymousUser()) {
 
  422            $this->testSession->setAccessCodeToSession(
$_POST[
'anonymous_id']);
 
  425        $this->ctrl->redirectByClass(
"ilobjtestgui", 
"infoScreen");
 
  437        $isFirstTestStartRequest = 
false;
 
  439        $this->processLocker->executeTestStartLockOperation(
function () use ($testStartLock, &$isFirstTestStartRequest) {
 
  440            if ($this->testSession->lookupTestStartLock() != $testStartLock) {
 
  441                $this->testSession->persistTestStartLock($testStartLock);
 
  442                $isFirstTestStartRequest = true;
 
  446        if ($isFirstTestStartRequest) {
 
  451        $this->ctrl->setParameterByClass(
'ilObjTestGUI', 
'lock', $testStartLock);
 
  452        $this->ctrl->redirectByClass(
"ilobjtestgui", 
"redirectToInfoScreen");
 
  459        } elseif (isset(
$_GET[
'lock']) && strlen(
$_GET[
'lock'])) {
 
  460            return $_GET[
'lock'];
 
  476        if ($this->object->checkMaximumAllowedUsers() == 
false) {
 
  480        if ($this->testSession->isAnonymousUser() && !$this->testSession->getActiveId()) {
 
  481            $accessCode = $this->testSession->createNewAccessCode();
 
  483            $this->testSession->setAccessCodeToSession($accessCode);
 
  484            $this->testSession->setAnonymousId($accessCode);
 
  485            $this->testSession->saveToDb();
 
  490        $this->testSession->unsetAccessCodeInSession();
 
  496        $this->tpl->addBlockFile($this->
getContentBlockName(), 
"adm_content", 
"tpl.il_as_tst_anonymous_code_presentation.html", 
"Modules/Test");
 
  497        $this->tpl->setCurrentBlock(
"adm_content");
 
  498        $this->tpl->setVariable(
"TEXT_ANONYMOUS_CODE_CREATED", $this->lng->txt(
"tst_access_code_created"));
 
  499        $this->tpl->setVariable(
"TEXT_ANONYMOUS_CODE", $this->testSession->getAccessCodeFromSession());
 
  500        $this->tpl->setVariable(
"FORMACTION", $this->ctrl->getFormAction($this));
 
  502        $this->tpl->setVariable(
"TXT_CONFIRM", $this->lng->txt(
"continue_work"));
 
  503        $this->tpl->parseCurrentBlock();
 
  518        if (
$_POST[
"chb_javascript"]) {
 
  519            $ilUser->writePref(
"tst_javascript", 1);
 
  521            $ilUser->writePref(
"tst_javascript", 0);
 
  525        if ($this->object->getNrOfTries() != 1) {
 
  526            if ($this->object->getUsePreviousAnswers() == 1) {
 
  527                if (
$_POST[
"chb_use_previous_answers"]) {
 
  528                    $ilUser->writePref(
"tst_use_previous_answers", 1);
 
  530                    $ilUser->writePref(
"tst_use_previous_answers", 0);
 
  538        $active_id = $this->testSession->getActiveId();
 
  543        $this->testSession->setLastFinishedPass($this->testSession->getPass());
 
  544        $this->testSession->increaseTestPass();
 
  548        $this->tpl->addBlockFile($this->
getContentBlockName(), 
"adm_content", 
"tpl.il_as_tst_redirect_autosave.html", 
"Modules/Test");
 
  549        $this->tpl->setVariable(
"TEXT_REDIRECT", $this->lng->txt(
"redirectAfterSave"));
 
  550        $this->tpl->setCurrentBlock(
"HeadContent");
 
  551        $this->tpl->setVariable(
"CONTENT_BLOCK", 
"<meta http-equiv=\"refresh\" content=\"5; url=" . 
$url . 
"\">");
 
  552        $this->tpl->parseCurrentBlock();
 
  560        $authorizedSolution = !$canSaveResult;
 
  575                    $res = is_int($db_res);
 
  579                    $result = $this->lng->txt(
"autosave_success");
 
  581                    $result = $this->lng->txt(
"autosave_failed");
 
  586        if (!$canSaveResult && !$this->ctrl->isAsynch()) {
 
  607            $this->testSession->getActiveId(),
 
  608            $this->testSession->getPass()
 
  635        $show_side_list = 
$ilUser->getPref(
'side_list_of_questions');
 
  636        $ilUser->writePref(
'side_list_of_questions', !$show_side_list);
 
  653        $questionId  = $this->testSequence->getQuestionForSequence(
 
  657        $this->
object->setQuestionSetSolved(1, $questionId, $this->testSession->getUserId());
 
  675        $questionId  = $this->testSequence->getQuestionForSequence(
 
  679        $this->
object->setQuestionSetSolved(0, $questionId, $this->testSession->getUserId());
 
  695    protected function confirmFinishTestCmd()
 
  702        require_once 
'Services/Utilities/classes/class.ilConfirmationGUI.php';
 
  704        $confirmation->setFormAction($this->ctrl->getFormAction($this, 
'confirmFinish'));
 
  705        $confirmation->setHeaderText($this->lng->txt(
"tst_finish_confirmation_question"));
 
  706        $confirmation->setConfirm($this->lng->txt(
"tst_finish_confirm_button"), 
'confirmFinish');
 
  718        $active_id = $this->testSession->getActiveId();
 
  736        if ($this->object->areObligationsEnabled() && !$allObligationsAnswered) {
 
  737            if ($this->object->getListOfQuestions()) {
 
  747        if ($this->object->getEnableExamview() && !isset(
$_GET[
'reviewed']) && $requires_confirmation) {
 
  748            $this->ctrl->redirectByClass(
'ilTestSubmissionReviewGUI', 
"show");
 
  753        if (($requires_confirmation) && ($actualpass == $this->object->getNrOfTries() - 1)) {
 
  755            return $this->confirmFinishTestCmd();
 
  759        if (($actualpass == $this->object->getNrOfTries() - 1) && (!$requires_confirmation)) {
 
  761            #$ilAuth->setIdle(ilSession::getIdleValue(), false); 
  762            #$ilAuth->setExpire(0); 
  763            switch ($this->object->getMailNotification()) {
 
  765                    $this->
object->sendSimpleNotification($active_id);
 
  768                    $this->
object->sendAdvancedNotification($active_id);
 
  778            if ($this->object->getMailNotificationType() == 1) {
 
  779                switch ($this->object->getMailNotification()) {
 
  781                        $this->
object->sendSimpleNotification($active_id);
 
  784                        $this->
object->sendAdvancedNotification($active_id);
 
  799        require_once 
'Modules/Test/classes/class.ilTestPassFinishTasks.php';
 
  802        $finishTasks->performFinishTasks($this->processLocker);
 
  807        $activeId = $this->testSession->getActiveId();
 
  808        $lastFinishedPass = $this->testSession->getLastFinishedPass();
 
  812            $this->ctrl->redirectByClass(
'ilTestSignatureGUI', 
'invokeSignaturePlugin');
 
  816        if (!
$_GET[
'skipfinalstatement']) {
 
  817            if ($this->object->getShowFinalStatement()) {
 
  823        $redirection_mode = $this->
object->getRedirectionMode();
 
  824        $redirection_url  = $this->
object->getRedirectionUrl();
 
  825        if ($redirection_url && $redirection_mode && !$this->object->canViewResults()) {
 
  827                if ($this->object->getKioskMode()) {
 
  841        if (!$this->object->getSignSubmission()) {
 
  845        if (!is_null(
ilSession::get(
"signed_{$activeId}_{$lastFinishedPass}"))) {
 
  849        global $ilPluginAdmin;
 
  851        $activePlugins = $ilPluginAdmin->getActivePluginsForSlot(
IL_COMP_MODULE, 
'Test', 
'tsig');
 
  853        if (!count($activePlugins)) {
 
  867        global $ilObjDataCache;
 
  869        require_once 
'Modules/Test/classes/class.ilTestResultHeaderLabelBuilder.php';
 
  872        $objectivesList = 
null;
 
  875            $testSequence = $this->testSequenceFactory->getSequenceByActiveIdAndPass($this->testSession->getActiveId(), $this->testSession->getPass());
 
  879            require_once 
'Modules/Course/classes/Objectives/class.ilLOTestQuestionAdapter.php';
 
  883            $objectivesList->loadObjectivesTitles();
 
  885            $testResultHeaderLabelBuilder->setObjectiveOrientedContainerId($this->testSession->getObjectiveOrientedContainerId());
 
  886            $testResultHeaderLabelBuilder->setUserId($this->testSession->getUserId());
 
  887            $testResultHeaderLabelBuilder->setTestObjId($this->object->getId());
 
  888            $testResultHeaderLabelBuilder->setTestRefId($this->object->getRefId());
 
  889            $testResultHeaderLabelBuilder->initObjectiveOrientedMode();
 
  892        $results = $this->
object->getTestResult(
 
  899        require_once 
'class.ilTestEvaluationGUI.php';
 
  901        $results_output = $testevaluationgui->getPassListOfAnswers(
 
  911            $testResultHeaderLabelBuilder
 
  914        require_once 
'./Modules/Test/classes/class.ilTestArchiver.php';
 
  920        if (!is_dir(
$path)) {
 
  923        $filename = realpath(
$path) . 
'/exam_N' . $inst_id . 
'-' . $this->
object->getId()
 
  924                    . 
'-' . $active . 
'-' . 
$pass . 
'.pdf';
 
  926        require_once 
'Modules/Test/classes/class.ilTestPDFGenerator.php';
 
  930        $archiver->handInParticipantSubmission($active, 
$pass, 
$filename, $results_output);
 
  935        $questions = $this->
object->getQuestions();
 
  936        foreach ($questions as $question_id) {
 
  937            $question_object = $this->
object->getQuestionDataset($question_id);
 
  938            if ($question_object->type_tag == 
'assFileUpload') {
 
  957                $handle = opendir($candidate_path);
 
  958                while ($handle !== 
false && (
$file = readdir($handle)) !== 
false) {
 
  960                        $filename_start = 
'file_' . $active . 
'_' . 
$pass . 
'_';
 
  962                        if (strpos(
$file, $filename_start) === 0) {
 
  963                            $archiver->handInParticipantQuestionMaterial($active, 
$pass, $question_id, 
$file, 
$file);
 
  969        $passdata = $this->
object->getTestResult(
 
  975        $overview = $testevaluationgui->getPassListOfAnswers(
 
  985            $testResultHeaderLabelBuilder
 
  997        require_once 
'Modules/Test/classes/class.ilTestPassesSelector.php';
 
  999        $testPassesSelector->setActiveId($this->testSession->getActiveId());
 
 1000        $testPassesSelector->setLastFinishedPass($this->testSession->getLastFinishedPass());
 
 1002        if (count($testPassesSelector->getReportablePasses())) {
 
 1003            $this->ctrl->redirectByClass(
"ilTestEvaluationGUI", 
"outUserResultsOverview");
 
 1011        $this->ctrl->redirectByClass(
'ilObjTestGUI', 
'redirectToInfoScreen');
 
 1019        $template = 
new ilTemplate(
"tpl.il_as_tst_final_statement.html", 
true, 
true, 
"Modules/Test");
 
 1020        $this->ctrl->setParameter($this, 
"skipfinalstatement", 1);
 
 1022        $template->setVariable(
"FINALSTATEMENT", $this->object->prepareTextareaOutput($this->object->getFinalStatement(), 
true));
 
 1023        $template->setVariable(
"BUTTON_CONTINUE", $this->lng->txt(
"btn_next"));
 
 1032        if ($this->object->getShowKioskModeTitle()) {
 
 1033            $template->setCurrentBlock(
"kiosk_show_title");
 
 1034            $template->setVariable(
"TEST_TITLE", $this->object->getTitle());
 
 1037        if ($this->object->getShowKioskModeParticipant()) {
 
 1038            $template->setCurrentBlock(
"kiosk_show_participant");
 
 1039            $template->setVariable(
"PARTICIPANT_NAME_TXT", $this->lng->txt(
"login_as"));
 
 1042            $template->setVariable(
"PARTICIPANT_MATRICULATION", 
$ilUser->getMatriculation());
 
 1046        if ($this->object->isShowExamIdInTestPassEnabled()) {
 
 1048                $this->testSession->getActiveId(),
 
 1049                $this->testSession->getPass(),
 
 1050                $this->object->getId()
 
 1053            $template->setCurrentBlock(
"kiosk_show_exam_id");
 
 1054            $template->setVariable(
"EXAM_ID_TXT", $this->lng->txt(
"exam_id"));
 
 1055            $template->setVariable(
"EXAM_ID", $exam_id);
 
 1066        global 
$ilUser, $ilNavigationHistory;
 
 1068        $ilNavigationHistory->addItem(
 
 1069            $this->testSession->getRefId(),
 
 1083        if ($this->object->endingTimeReached()) {
 
 1089            $this->ctrl->setParameter($this, 
"sequence", $sequenceElement);
 
 1094        if ($this->object->getKioskMode()) {
 
 1098        $this->tpl->setVariable(
"TEST_ID", $this->object->getTestId());
 
 1099        $this->tpl->setVariable(
"LOGIN", 
$ilUser->getLogin());
 
 1100        $this->tpl->setVariable(
"SEQ_ID", $sequenceElement);
 
 1101        $this->tpl->setVariable(
"QUEST_ID", $questionId);
 
 1103        if ($this->object->getEnableProcessingTime()) {
 
 1107        $this->tpl->setVariable(
"PAGETITLE", 
"- " . $this->object->getTitle());
 
 1109        if ($this->object->isShowExamIdInTestPassEnabled() && !$this->object->getKioskMode()) {
 
 1110            $this->tpl->setCurrentBlock(
'exam_id_footer');
 
 1112                $this->testSession->getActiveId(),
 
 1113                $this->testSession->getPass(),
 
 1114                $this->object->getId()
 
 1116            $this->tpl->setVariable(
'EXAM_ID_TXT', $this->lng->txt(
'exam_id'));
 
 1117            $this->tpl->parseCurrentBlock();
 
 1120        if ($this->object->getListOfQuestions()) {
 
 1121            $this->
showSideList($presentationMode, $sequenceElement);
 
 1132        $questionNavigationGUI->setQuestionWorkedThrough($isQuestionWorkedThrough);
 
 1139        $answerFeedbackEnabled = (
 
 1140            $instantResponse && $this->
object->getSpecificAnswerFeedback()
 
 1144            $this->testSession->getActiveId(),  #active_id
 
 1145            $this->testSession->getPass(),              #pass
 
 1146            false,                                                              #graphical_output
 
 1147            false,                                                              #result_output
 
 1148            true,                                                               #show_question_only
 
 1149            $answerFeedbackEnabled,                             #show_feedback
 
 1150            false,                                                              #show_correct_solution
 
 1151            false,                                                              #show_manual_scoring
 
 1152            true                                                                #show_question_text
 
 1158            $this->testSession->getActiveId(),
 
 1162        $this->tpl->setCurrentBlock(
'readonly_css_class');
 
 1163        $this->tpl->touchBlock(
'readonly_css_class');
 
 1164        $this->tpl->parseCurrentBlock();
 
 1166        $this->tpl->setVariable(
'QUESTION_OUTPUT', $pageoutput);
 
 1168        $this->tpl->setVariable(
"FORMACTION", $formAction);
 
 1169        $this->tpl->setVariable(
"ENCTYPE", 
'enctype="' . $questionGui->
getFormEncodingType() . 
'"');
 
 1170        $this->tpl->setVariable(
"FORM_TIMESTAMP", time());
 
 1176            $questionGui->object->getId(),
 
 1177            $this->populateCharSelectorIfRequired()
 
 1179        if ($isQuestionWorkedThrough) {
 
 1180            $questionNavigationGUI->setDiscardSolutionButtonEnabled(
true);
 
 1184        } elseif ($this->object->isPostponingEnabled()) {
 
 1185            $questionNavigationGUI->setSkipQuestionLinkTarget(
 
 1193        $answerFeedbackEnabled = (
 
 1194            $instantResponse && $this->
object->getSpecificAnswerFeedback()
 
 1197        if (isset(
$_GET[
'save_error']) && 
$_GET[
'save_error'] == 1 && isset(
$_SESSION[
'previouspost'])) {
 
 1198            $userPostSolution = 
$_SESSION[
'previouspost'];
 
 1201            $userPostSolution = 
false;
 
 1209        $qstConfig = $questionGui->object->getTestPresentationConfig();
 
 1212            $qstConfig->setWorkedThrough($isQuestionWorkedThrough);
 
 1213            $qstConfig->setIsUnchangedAnswerPossible($this->object->getMCScoring());
 
 1216        if ($qstConfig->isPreviousPassSolutionReuseAllowed()) {
 
 1218            if ($passIndex < $this->testSession->getPass()) { 
 
 1219                $qstConfig->setSolutionInitiallyPrefilled(
true);
 
 1222            $passIndex = $this->testSession->getPass();
 
 1229            $formAction,                                                        #form_action
 
 1230            $this->testSession->getActiveId(),          #active_id
 
 1234            $isPostponed,                                                       #is_postponed
 
 1235            $userPostSolution,                                          #user_post_solution
 
 1236            $answerFeedbackEnabled                                      #answer_feedback == inline_specific_feedback
 
 1247        $this->populateQuestionEditControl($questionGui);
 
 1254        require_once 
'./Modules/Test/classes/class.ilObjTest.php';
 
 1257            $currentSolutionAvailable = $questionGui->object->authorizedOrIntermediateSolutionExists(
 
 1258                $this->testSession->getActiveId(),
 
 1259                $this->testSession->getPass()
 
 1262            if (!$currentSolutionAvailable) {
 
 1263                $previousPass = $questionGui->object->getSolutionMaxPass(
 
 1264                    $this->testSession->getActiveId()
 
 1267                $previousSolutionAvailable = $questionGui->object->authorizedSolutionExists(
 
 1268                    $this->testSession->getActiveId(),
 
 1272                if ($previousSolutionAvailable) {
 
 1273                    return $previousPass;
 
 1278        return $this->testSession->getPass();
 
 1293        $this->ctrl->saveParameter($this, 
'sequence');
 
 1315        $user = $this->
object->getInvitedUsers($ilUser->getId());
 
 1316        if (!is_array($user) || count($user)!=1) {
 
 1318            $this->ctrl->redirectByClass(
"ilobjtestgui", 
"backToRepository");
 
 1321        $user = array_pop($user);
 
 1323        if (strcmp($user[
"clientip"], 
"")!=0 && strcmp($user[
"clientip"], 
$_SERVER[
"REMOTE_ADDR"])!=0) {
 
 1325            $this->ctrl->redirectByClass(
"ilobjtestgui", 
"backToRepository");
 
 1337                and  $this->
object->startingTimeReached()
 
 1338                and  !$this->
object->endingTimeReached();
 
 1346        return $this->
object->hasNrOfTriesRestriction() && $this->
object->isNrOfTriesReached($this->testSession->getPass());
 
 1357        $this->testSession->increasePass();
 
 1358        $this->testSession->setLastSequence(0);
 
 1359        $this->testSession->saveToDb();
 
 1383        $this->tpl->addBlockFile($this->
getContentBlockName(), 
"adm_content", 
"tpl.il_as_tst_submit_answers_confirm.html", 
"Modules/Test");
 
 1384        $this->tpl->setCurrentBlock(
"adm_content");
 
 1385        if ($this->object->isTestFinished($this->testSession->getActiveId())) {
 
 1386            $this->tpl->setCurrentBlock(
"not_submit_allowed");
 
 1387            $this->tpl->setVariable(
"TEXT_ALREADY_SUBMITTED", $this->lng->txt(
"tst_already_submitted"));
 
 1388            $this->tpl->setVariable(
"BTN_OK", $this->lng->txt(
"tst_show_answer_sheet"));
 
 1390            $this->tpl->setCurrentBlock(
"submit_allowed");
 
 1391            $this->tpl->setVariable(
"TEXT_CONFIRM_SUBMIT_RESULTS", $this->lng->txt(
"tst_confirm_submit_answers"));
 
 1392            $this->tpl->setVariable(
"BTN_OK", $this->lng->txt(
"tst_submit_results"));
 
 1394        $this->tpl->setVariable(
"BTN_BACK", $this->lng->txt(
"back"));
 
 1395        $this->tpl->setVariable(
"FORMACTION", $this->ctrl->getFormAction($this, 
"finalSubmission"));
 
 1396        $this->tpl->parseCurrentBlock();
 
 1403        $starting_time = $this->
object->getStartingTimeOfUser($active_id);
 
 1404        $processing_time = $this->
object->getProcessingTimeInSeconds($active_id);
 
 1405        $processing_time_minutes = floor($processing_time / 60);
 
 1406        $processing_time_seconds = $processing_time - $processing_time_minutes * 60;
 
 1407        $str_processing_time = 
"";
 
 1408        if ($processing_time_minutes > 0) {
 
 1409            $str_processing_time = $processing_time_minutes . 
" " . ($processing_time_minutes == 1 ? $this->lng->txt(
"minute") : $this->lng->txt(
"minutes"));
 
 1411        if ($processing_time_seconds > 0) {
 
 1412            if (strlen($str_processing_time) > 0) {
 
 1413                $str_processing_time .= 
" " . $this->lng->txt(
"and") . 
" ";
 
 1415            $str_processing_time .= $processing_time_seconds . 
" " . ($processing_time_seconds == 1 ? $this->lng->txt(
"second") : $this->lng->txt(
"seconds"));
 
 1417        $time_left = $starting_time + $processing_time - time();
 
 1418        $time_left_minutes = floor($time_left / 60);
 
 1419        $time_left_seconds = $time_left - $time_left_minutes * 60;
 
 1420        $str_time_left = 
"";
 
 1421        if ($time_left_minutes > 0) {
 
 1422            $str_time_left = $time_left_minutes . 
" " . ($time_left_minutes == 1 ? $this->lng->txt(
"minute") : $this->lng->txt(
"minutes"));
 
 1424        if ($time_left < 300) {
 
 1425            if ($time_left_seconds > 0) {
 
 1426                if (strlen($str_time_left) > 0) {
 
 1427                    $str_time_left .= 
" " . $this->lng->txt(
"and") . 
" ";
 
 1429                $str_time_left .= $time_left_seconds . 
" " . ($time_left_seconds == 1 ? $this->lng->txt(
"second") : $this->lng->txt(
"seconds"));
 
 1432        $date = getdate($starting_time);
 
 1434        $datenow = getdate();
 
 1435        $this->tpl->setCurrentBlock(
"enableprocessingtime");
 
 1436        $this->tpl->setVariable(
 
 1437            "USER_WORKING_TIME",
 
 1439                $this->lng->txt(
"tst_time_already_spent"),
 
 1440                $formattedStartingTime,
 
 1441                $str_processing_time
 
 1444        $this->tpl->setVariable(
"USER_REMAINING_TIME", 
sprintf($this->lng->txt(
"tst_time_already_spent_left"), $str_time_left));
 
 1445        $this->tpl->parseCurrentBlock();
 
 1447        $template->setVariable(
"STRING_MINUTE", $this->lng->txt(
"minute"));
 
 1448        $template->setVariable(
"STRING_MINUTES", $this->lng->txt(
"minutes"));
 
 1449        $template->setVariable(
"STRING_SECOND", $this->lng->txt(
"second"));
 
 1450        $template->setVariable(
"STRING_SECONDS", $this->lng->txt(
"seconds"));
 
 1451        $template->setVariable(
"STRING_TIMELEFT", $this->lng->txt(
"tst_time_already_spent_left"));
 
 1452        $template->setVariable(
"AND", strtolower($this->lng->txt(
"and")));
 
 1453        $template->setVariable(
"YEAR", $date[
"year"]);
 
 1454        $template->setVariable(
"MONTH", $date[
"mon"]-1);
 
 1455        $template->setVariable(
"DAY", $date[
"mday"]);
 
 1456        $template->setVariable(
"HOUR", $date[
"hours"]);
 
 1457        $template->setVariable(
"MINUTE", $date[
"minutes"]);
 
 1458        $template->setVariable(
"SECOND", $date[
"seconds"]);
 
 1459        if ($this->object->isEndingTimeEnabled()) {
 
 1461            preg_match(
"/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $date_time->get(
IL_CAL_TIMESTAMP), $matches);
 
 1462            $template->setVariable(
"ENDYEAR", $matches[1]);
 
 1463            $template->setVariable(
"ENDMONTH", $matches[2]-1);
 
 1464            $template->setVariable(
"ENDDAY", $matches[3]);
 
 1465            $template->setVariable(
"ENDHOUR", $matches[4]);
 
 1466            $template->setVariable(
"ENDMINUTE", $matches[5]);
 
 1467            $template->setVariable(
"ENDSECOND", $matches[6]);
 
 1469        $template->setVariable(
"YEARNOW", $datenow[
"year"]);
 
 1470        $template->setVariable(
"MONTHNOW", $datenow[
"mon"]-1);
 
 1471        $template->setVariable(
"DAYNOW", $datenow[
"mday"]);
 
 1472        $template->setVariable(
"HOURNOW", $datenow[
"hours"]);
 
 1473        $template->setVariable(
"MINUTENOW", $datenow[
"minutes"]);
 
 1474        $template->setVariable(
"SECONDNOW", $datenow[
"seconds"]);
 
 1475        $template->setVariable(
"PTIME_M", $processing_time_minutes);
 
 1476        $template->setVariable(
"PTIME_S", $processing_time_seconds);
 
 1478        $this->tpl->setCurrentBlock(
"HeadContent");
 
 1479        $this->tpl->setVariable(
"CONTENT_BLOCK", 
$template->get());
 
 1480        $this->tpl->parseCurrentBlock();
 
 1483    protected function showSideList($presentationMode, $currentSequenceElement)
 
 1487        $sideListActive = 
$ilUser->getPref(
'side_list_of_questions');
 
 1489        if ($sideListActive) {
 
 1495            $questionSummaryData = $this->service->getQuestionSummaryData($this->testSequence, 
false);
 
 1497            require_once 
'Modules/Test/classes/class.ilTestQuestionSideListGUI.php';
 
 1499            $questionSideListGUI->setTargetGUI($this);
 
 1500            $questionSideListGUI->setQuestionSummaryData($questionSummaryData);
 
 1501            $questionSideListGUI->setCurrentSequenceElement($currentSequenceElement);
 
 1504            $questionSideListGUI->setDisabled(
false);
 
 1508            $this->tpl->setVariable(
'LIST_OF_QUESTIONS', $questionSideListGUI->getHTML());
 
 1517    public function outQuestionSummaryCmd($fullpage = 
true, $contextFinishTest = 
false, $obligationsNotAnswered = 
false, $obligationsFilter = 
false)
 
 1520            $this->tpl->addBlockFile($this->
getContentBlockName(), 
"adm_content", 
"tpl.il_as_tst_question_summary.html", 
"Modules/Test");
 
 1523        if ($obligationsNotAnswered) {
 
 1527        if ($this->object->getKioskMode() && $fullpage) {
 
 1529            if (strlen($head)) {
 
 1530                $this->tpl->setCurrentBlock(
"kiosk_options");
 
 1531                $this->tpl->setVariable(
"KIOSK_HEAD", $head);
 
 1532                $this->tpl->parseCurrentBlock();
 
 1537        $active_id = $this->testSession->getActiveId();
 
 1538        $questionSummaryData = $this->service->getQuestionSummaryData($this->testSequence, $obligationsFilter);
 
 1540        $this->ctrl->setParameter($this, 
"sequence", 
$_GET[
"sequence"]);
 
 1543            include_once 
"./Modules/Test/classes/tables/class.ilListOfQuestionsTableGUI.php";
 
 1546            $table_gui->setShowPointsEnabled(!$this->object->getTitleOutput());
 
 1547            $table_gui->setShowMarkerEnabled($this->object->getShowMarker());
 
 1548            $table_gui->setObligationsNotAnswered($obligationsNotAnswered);
 
 1549            $table_gui->setShowObligationsEnabled($this->object->areObligationsEnabled());
 
 1550            $table_gui->setObligationsFilterEnabled($obligationsFilter);
 
 1555            $table_gui->setData($questionSummaryData);
 
 1557            $this->tpl->setVariable(
'TABLE_LIST_OF_QUESTIONS', $table_gui->getHTML());
 
 1559            if ($this->object->getEnableProcessingTime()) {
 
 1577        $this->tpl->addBlockFile($this->
getContentBlockName(), 
"adm_content", 
"tpl.il_as_tst_max_allowed_users_reached.html", 
"Modules/Test");
 
 1578        $this->tpl->setCurrentBlock(
"adm_content");
 
 1579        $this->tpl->setVariable(
"MAX_ALLOWED_USERS_MESSAGE", 
sprintf($this->lng->txt(
"tst_max_allowed_users_message"), $this->object->getAllowedUsersTimeGap()));
 
 1580        $this->tpl->setVariable(
"MAX_ALLOWED_USERS_HEADING", 
sprintf($this->lng->txt(
"tst_max_allowed_users_heading"), $this->object->getAllowedUsersTimeGap()));
 
 1582        $this->tpl->setVariable(
"TXT_BACK_TO_INFOSCREEN", $this->lng->txt(
"tst_results_back_introduction"));
 
 1583        $this->tpl->setVariable(
"FORMACTION", $this->ctrl->getFormAction($this));
 
 1584        $this->tpl->parseCurrentBlock();
 
 1599        $this->tpl->addBlockFile(
"ADM_CONTENT", 
"adm_content", 
"tpl.il_as_tst_correct_solution.html", 
"Modules/Test");
 
 1601        include_once(
"./Services/Style/Content/classes/class.ilObjStyleSheet.php");
 
 1602        $this->tpl->setCurrentBlock(
"ContentStyle");
 
 1604        $this->tpl->parseCurrentBlock();
 
 1606        $this->tpl->setCurrentBlock(
"SyntaxStyle");
 
 1608        $this->tpl->parseCurrentBlock();
 
 1611        if ($this->object->getShowSolutionAnswersOnly()) {
 
 1615        $this->tpl->setCurrentBlock(
"adm_content");
 
 1617        $this->tpl->setVariable(
"OUTPUT_SOLUTION", $solution);
 
 1618        $this->tpl->setVariable(
"TEXT_BACK", $this->lng->txt(
"back"));
 
 1619        $this->ctrl->saveParameter($this, 
"pass");
 
 1620        $this->ctrl->saveParameter($this, 
"active_id");
 
 1621        $this->tpl->setVariable(
"URL_BACK", $this->ctrl->getLinkTarget($this, 
"outUserResultsOverview"));
 
 1622        $this->tpl->parseCurrentBlock();
 
 1638        $this->tpl->addBlockFile($this->
getContentBlockName(), 
"adm_content", 
"tpl.il_as_tst_finish_list_of_answers.html", 
"Modules/Test");
 
 1640        $result_array =&$this->
object->getTestResult(
 
 1649        foreach ($result_array as $question_data) {
 
 1650            $question = $question_data[
"qid"];
 
 1651            if (is_numeric($question)) {
 
 1652                $this->tpl->setCurrentBlock(
"printview_question");
 
 1653                $question_gui = $this->
object->createQuestionGUI(
"", $question);
 
 1654                $template = 
new ilTemplate(
"tpl.il_as_qpl_question_printview.html", 
true, 
true, 
"Modules/TestQuestionPool");
 
 1656                $template->setVariable(
"QUESTION_TITLE", $question_gui->object->getTitle());
 
 1658                $show_question_only = ($this->
object->getShowSolutionAnswersOnly()) ? 
true : 
false;
 
 1659                $result_output = $question_gui->getSolutionOutput($active_id, 
$pass, 
false, 
false, $show_question_only, $this->object->getShowSolutionFeedback());
 
 1660                $template->setVariable(
"SOLUTION_OUTPUT", $result_output);
 
 1661                $this->tpl->setVariable(
"QUESTION_OUTPUT", 
$template->get());
 
 1662                $this->tpl->parseCurrentBlock();
 
 1668        if ($this->object->getShowSolutionAnswersOnly()) {
 
 1671        if (strlen($top_data)) {
 
 1672            $this->tpl->setCurrentBlock(
"top_data");
 
 1673            $this->tpl->setVariable(
"TOP_DATA", $top_data);
 
 1674            $this->tpl->parseCurrentBlock();
 
 1677        if (strlen($bottom_data)) {
 
 1678            $this->tpl->setCurrentBlock(
"bottom_data");
 
 1679            $this->tpl->setVariable(
"FORMACTION", $this->ctrl->getFormAction($this));
 
 1680            $this->tpl->setVariable(
"BOTTOM_DATA", $bottom_data);
 
 1681            $this->tpl->parseCurrentBlock();
 
 1684        $this->tpl->setCurrentBlock(
"adm_content");
 
 1685        $this->tpl->setVariable(
"TXT_ANSWER_SHEET", $this->lng->txt(
"tst_list_of_answers"));
 
 1688        $this->tpl->setVariable(
"USER_DETAILS", $user_data);
 
 1689        $this->tpl->setVariable(
"SIGNATURE", $signature);
 
 1690        $this->tpl->setVariable(
"TITLE", $this->object->getTitle());
 
 1691        $this->tpl->setVariable(
"TXT_TEST_PROLOG", $this->lng->txt(
"tst_your_answers"));
 
 1692        $invited_user =&$this->
object->getInvitedUsers($ilUser->getId());
 
 1693        $pagetitle = $this->
object->getTitle() . 
" - " . $this->lng->txt(
"clientip") .
 
 1694            ": " . $invited_user[
$ilUser->getId()][
"clientip"] . 
" - " .
 
 1695            $this->lng->txt(
"matriculation") . 
": " .
 
 1696            $invited_user[
$ilUser->getId()][
"matriculation"];
 
 1697        $this->tpl->setVariable(
"PAGETITLE", $pagetitle);
 
 1698        $this->tpl->parseCurrentBlock();
 
 1708        if ($this->object->getKioskMode()) {
 
 1709            $this->tpl->setBodyClass(
"kiosk");
 
 1710            $this->tpl->setAddFooter(
false);
 
 1713            return "ADM_CONTENT";
 
 1719        $this->ctrl->redirectByClass(
 
 1720            array(
'ilRepositoryGUI', 
'ilObjTestGUI', 
'ilTestEvaluationGUI'),
 
 1721            "outUserResultsOverview" 
 1734        $this->ctrl->setParameter($this, 
'pmode', self::PRESENTATION_MODE_EDIT);
 
 1736        require_once 
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintRequestGUI.php';
 
 1749        $this->ctrl->setParameter($this, 
'pmode', self::PRESENTATION_MODE_EDIT);
 
 1751        require_once 
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintRequestGUI.php';
 
 1770        $this->tpl->addBlockFile(
 
 1773            'tpl.il_as_tst_question_summary.html',
 
 1777        if ($this->object->getKioskMode()) {
 
 1784        $this->tpl->addBlockFile(
 
 1787            'tpl.il_as_tst_output.html',
 
 1798        if (strlen($head)) {
 
 1799            $this->tpl->setCurrentBlock(
"kiosk_options");
 
 1800            $this->tpl->setVariable(
"KIOSK_HEAD", $head);
 
 1801            $this->tpl->parseCurrentBlock();
 
 1807        if ($this->ctrl->getNextClass() == 
'iltestpasswordprotectiongui') {
 
 1811        if (!$this->passwordChecker->isPasswordProtectionPageRedirectRequired()) {
 
 1817        $nextCommand = $this->ctrl->getCmdClass() . 
'::' . $this->ctrl->getCmd();
 
 1818        $this->ctrl->setParameterByClass(
'ilTestPasswordProtectionGUI', 
'nextCommand', $nextCommand);
 
 1819        $this->ctrl->redirectByClass(
'ilTestPasswordProtectionGUI', 
'showPasswordForm');
 
 1824        if (!$this->object->isInstantFeedbackAnswerFixationEnabled()) {
 
 1828        if (!$this->testSequence->isQuestionChecked($questionId)) {
 
 1840        return $this->lng->txt(
"save_introduction");
 
 1845        $this->assSettings = 
new ilSetting(
'assessment');
 
 1854        $questionList->load();
 
 1858        require_once 
'Modules/Test/classes/class.ilTestSkillEvaluation.php';
 
 1859        $skillEvaluation = 
new ilTestSkillEvaluation($this->db, $this->object->getTestId(), $this->object->getRefId());
 
 1861        $skillEvaluation->setUserId(
$testSession->getUserId());
 
 1862        $skillEvaluation->setActiveId(
$testSession->getActiveId());
 
 1865        $skillEvaluation->setNumRequiredBookingsForSkillTriggering($this->assSettings->get(
 
 1866            'ass_skl_trig_num_answ_barrier',
 
 1871        $skillEvaluation->init($questionList);
 
 1872        $skillEvaluation->evaluate($testResults);
 
 1874        $skillEvaluation->handleSkillTriggering();
 
 1881        require_once 
'Modules/Test/classes/confirmations/class.ilTestAnswerOptionalQuestionsConfirmationGUI.php';
 
 1884        $confirmation->setFormAction($this->ctrl->getFormAction($this));
 
 1885        $confirmation->setCancelCmd(
'cancelAnswerOptionalQuestions');
 
 1886        $confirmation->setConfirmCmd(
'confirmAnswerOptionalQuestions');
 
 1888        $confirmation->build($this->object->isFixedTest());
 
 1895        $this->testSequence->setAnsweringOptionalQuestionsConfirmed(
true);
 
 1896        $this->testSequence->saveToDb();
 
 1898        $this->ctrl->setParameter($this, 
'activecommand', 
'gotoquestion');
 
 1899        $this->ctrl->redirect($this, 
'redirectQuestion');
 
 1904        if ($this->object->getListOfQuestions()) {
 
 1905            $this->ctrl->setParameter($this, 
'activecommand', 
'summary');
 
 1907            $this->ctrl->setParameter($this, 
'activecommand', 
'previous');
 
 1910        $this->ctrl->redirect($this, 
'redirectQuestion');
 
 1918        if ($this->object->getKioskMode()) {
 
 1919            $this->tpl->addBlockfile($this->
getContentBlockName(), 
'content', 
"tpl.il_as_tst_kiosk_mode_content.html", 
"Modules/Test");
 
 1920            $this->tpl->setContent($this->ctrl->getHTML($helperGui));
 
 1933        if (
$ilSetting->get(
'char_selector_availability') > 0) {
 
 1934            require_once 
'Services/UIComponent/CharSelector/classes/class.ilCharSelectorGUI.php';
 
 1937                $char_selector->addToPage();
 
 1938                $this->tpl->setCurrentBlock(
'char_selector');
 
 1939                $this->tpl->setVariable(
"CHAR_SELECTOR_TEMPLATE", $char_selector->getSelectorHtml());
 
 1940                $this->tpl->parseCurrentBlock();
 
 1953        require_once 
'Modules/Test/classes/class.ilTestNavigationToolbarGUI.php';
 
 1956        $navigationToolbarGUI->setSuspendTestButtonEnabled($this->object->getShowCancel());
 
 1957        $navigationToolbarGUI->setQuestionTreeButtonEnabled($this->object->getListOfQuestions());
 
 1958        $navigationToolbarGUI->setQuestionTreeVisible(
$ilUser->getPref(
'side_list_of_questions'));
 
 1959        $navigationToolbarGUI->setQuestionListButtonEnabled($this->object->getListOfQuestions());
 
 1962        return $navigationToolbarGUI;
 
 1967        require_once 
'Modules/Test/classes/class.ilTestQuestionNavigationGUI.php';
 
 1974        if ($this->object->getShowMarker()) {
 
 1975            include_once 
"./Modules/Test/classes/class.ilObjTest.php";
 
 1979            if (count($solved_array) > 0) {
 
 1980                $solved = array_pop($solved_array);
 
 1981                $solved = $solved[
"solved"];
 
 1986                $navigationGUI->setQuestionMarked(
true);
 
 1989                $navigationGUI->setQuestionMarked(
false);
 
 1994        return $navigationGUI;
 
 1999        require_once 
'Modules/Test/classes/class.ilTestQuestionNavigationGUI.php';
 
 2002        if ($this->object->isForceInstantFeedbackEnabled()) {
 
 2017            case $this->
object->getSpecificAnswerFeedback():
 
 2018            case $this->
object->getGenericAnswerFeedback():
 
 2019            case $this->
object->getAnswerFeedbackPoints():
 
 2020            case $this->
object->getInstantFeedbackSolution():
 
 2022                $navigationGUI->setAnswerFreezingEnabled($this->object->isInstantFeedbackAnswerFixationEnabled());
 
 2024                if ($this->object->isForceInstantFeedbackEnabled()) {
 
 2025                    $navigationGUI->setForceInstantResponseEnabled(
true);
 
 2033        if ($this->object->isOfferingQuestionHintsEnabled()) {
 
 2034            $activeId = $this->testSession->getActiveId();
 
 2035            $pass = $this->testSession->getPass();
 
 2037            require_once 
'Modules/TestQuestionPool/classes/class.ilAssQuestionHintTracking.php';
 
 2040            if ($questionHintTracking->requestsPossible()) {
 
 2044            if ($questionHintTracking->requestsExist()) {
 
 2049        $navigationGUI->setCharSelectorEnabled($charSelectorAvailable);
 
 2051        if ($this->object->getShowMarker()) {
 
 2052            include_once 
"./Modules/Test/classes/class.ilObjTest.php";
 
 2056            if (count($solved_array) > 0) {
 
 2057                $solved = array_pop($solved_array);
 
 2058                $solved = $solved[
"solved"];
 
 2064                $navigationGUI->setQuestionMarked(
true);
 
 2067                $navigationGUI->setQuestionMarked(
false);
 
 2071        return $navigationGUI;
 
 2079        if (!$this->object->getListOfQuestionsEnd()) {
 
 2080            return 'finishTest';
 
 2083        if ($this->object->areObligationsEnabled()) {
 
 2085                $this->testSession->getTestId(),
 
 2086                $this->testSession->getActiveId(),
 
 2087                $this->testSession->getPass()
 
 2090            if (!$allObligationsAnswered) {
 
 2091                return 'outQuestionSummaryWithObligationsInfo';
 
 2095        return 'outQuestionSummary';
 
 2127        $answerFeedbackEnabled = $this->
object->getSpecificAnswerFeedback();
 
 2130            $this->testSession->getActiveId(),  #active_id
 
 2131            $this->testSession->getPass(),              #pass
 
 2132            false,                                                              #graphical_output
 
 2133            false,                                                              #result_output
 
 2134            true,                                                               #show_question_only
 
 2135            $answerFeedbackEnabled,                             #show_feedback
 
 2136            false,                                                              #show_correct_solution
 
 2137            false,                                                              #show_manual_scoring
 
 2138            true                                                                #show_question_text
 
 2144            $this->testSession->getActiveId(),
 
 2148        $tpl = 
new ilTemplate(
'tpl.tst_player_response_modal.html', 
true, 
true, 
'Modules/Test');
 
 2154        $this->tpl = $saved_tpl;
 
 2156        $tpl->setVariable(
'QUESTION_OUTPUT', $pageoutput);
 
 2159        $button->setId(
'tst_confirm_feedback');
 
 2160        $button->setUrl($navUrl);
 
 2161        $button->setCaption(
'proceed');
 
 2162        $button->setPrimary(
true);
 
 2163        $tpl->setVariable(
'BUTTON', $button->render());
 
 2166        require_once(
'Services/UIComponent/Modal/classes/class.ilModalGUI.php');
 
 2169        $modal->setId(
'tst_question_feedback_modal');
 
 2170        $modal->setHeading($this->lng->txt(
'tst_instant_feedback'));
 
 2171        $modal->setBody(
$tpl->get());
 
 2173        $this->tpl->addOnLoadCode(
"$('#tst_question_feedback_modal').modal('show');");
 
 2174        $this->tpl->setVariable(
'INSTANT_RESPONSE_MODAL', $modal->getHTML());
 
 2186        if ($this->object->getInstantFeedbackSolution()) {
 
 2191                $this->testSession->getActiveId(),    #active_id
 
 2193                false,                                                #graphical_output
 
 2194                $show_question_inline_score,                        #result_output
 
 2195                false,                                                #show_question_only
 
 2196                false,                                                #show_feedback
 
 2197                true,                                                #show_correct_solution
 
 2198                false,                                                #show_manual_scoring
 
 2199                false                                                #show_question_text
 
 2204        $reachedPoints = $questionGui->object->getAdjustedReachedPoints(
 
 2205            $this->testSession->getActiveId(),
 
 2210        $maxPoints = $questionGui->object->getMaximumPoints();
 
 2212        $solutionCorrect = ($reachedPoints == $maxPoints);
 
 2216        if ($this->object->getAnswerFeedbackPoints()) {
 
 2222        if ($this->object->getGenericAnswerFeedback()) {
 
 2228        if ($this->object->getSpecificAnswerFeedback()) {
 
 2239        return $this->testSession->getLastSequence();
 
 2244        unset(
$_GET[
'sequence']);
 
 2245        $this->ctrl->setParameter($this, 
'sequence', 
null);
 
 2250        if (isset(
$_GET[
'sequence'])) {
 
 2251            return $_GET[
'sequence'];
 
 2259        if (isset(
$_GET[
'pmode'])) {
 
 2260            return $_GET[
'pmode'];
 
 2268        if (isset(
$_GET[
'instresp'])) {
 
 2269            return $_GET[
'instresp'];
 
 2277        if (isset(
$_POST[
'nextcmd']) && strlen(
$_POST[
'nextcmd'])) {
 
 2278            return $_POST[
'nextcmd'];
 
 2286        if (isset(
$_POST[
'nextseq']) && is_numeric(
$_POST[
'nextseq'])) {
 
 2287            return (
int) 
$_POST[
'nextseq'];
 
 2296        if (isset(
$_POST[
'test_player_navigation_url'])) {
 
 2297            return $_POST[
'test_player_navigation_url'];
 
 2311        return !empty(
$_GET[
'test_answer_changed']);
 
 2320        $this->ctrl->setParameter($this, 
'test_answer_changed', 
$changed ? 
'1' : 
'0');
 
 2346        if (!empty(
$_POST[
'save_on_navigation_prevent_confirmation'])) {
 
 2347            $_SESSION[
'save_on_navigation_prevent_confirmation'] = 
true;
 
 2366        if (!$fromCache || !isset($this->cachedQuestionGuis[$questionId])) {
 
 2367            $questionGui = $this->
object->createQuestionGUI(
"", $questionId);
 
 2368            $questionGui->setTargetGui($this);
 
 2370            $questionGui->object->setObligationsToBeConsidered($this->object->areObligationsEnabled());
 
 2371            $questionGui->populateJavascriptFilesRequiredForWorkForm(
$tpl);
 
 2379            $this->cachedQuestionGuis[$questionId] = $questionGui;
 
 2382        return $this->cachedQuestionGuis[$questionId];
 
 2398        if (!$fromCache || !isset($this->cachedQuestionObjects[$questionId])) {
 
 2402            require_once 
'Modules/TestQuestionPool/classes/class.ilAssQuestionProcessLockerFactory.php';
 
 2404            $processLockerFactory->setQuestionId($questionOBJ->getId());
 
 2405            $processLockerFactory->setUserId(
$ilUser->getId());
 
 2406            include_once(
"./Modules/Test/classes/class.ilObjAssessmentFolder.php");
 
 2408            $questionOBJ->setProcessLocker($processLockerFactory->getLocker());
 
 2410            $questionOBJ->setObligationsToBeConsidered($this->object->areObligationsEnabled());
 
 2417            $this->cachedQuestionObjects[$questionId] = $questionOBJ;
 
 2420        return $this->cachedQuestionObjects[$questionId];
 
 2427            $this->object->isPreviousSolutionReuseEnabled($this->testSession->getActiveId())
 
 2438        require_once 
'Services/Randomization/classes/class.ilArrayElementShuffler.php';
 
 2442        $shuffler->setSeed($fixedSeed);
 
 2458            . 
"active={$this->testSession->getActiveId()} " 
 2459            . 
"qId=$questionId seq=$sequenceElement " 
 2460            . serialize($this->testSequence)
 
 2463        $ilLog->logStack(
'INV SEQ');
 
 2465        $this->ctrl->setParameter($this, 
'sequence', $this->testSequence->getFirstSequence());
 
 2474        if ($this->object->getKioskMode()) {
 
 2475            $this->tpl->addBlockfile($this->
getContentBlockName(), 
'content', 
"tpl.il_as_tst_kiosk_mode_content.html", 
"Modules/Test");
 
 2476            $this->tpl->setContent($contentHTML);
 
 2484        require_once 
'Services/UIComponent/Button/classes/class.ilSubmitButton.php';
 
 2485        require_once 
'Services/UIComponent/Button/classes/class.ilLinkButton.php';
 
 2486        require_once 
'Services/UIComponent/Modal/classes/class.ilModalGUI.php';
 
 2493        if ($this->object->getKioskMode()) {
 
 2500        $tpl = 
new ilTemplate(
'tpl.tst_player_confirmation_modal.html', 
true, 
true, 
'Modules/Test');
 
 2502        $tpl->setVariable(
'CONFIRMATION_TEXT', $this->lng->txt(
'discard_answer_confirmation'));
 
 2506        $button->setCaption(
'discard_answer');
 
 2507        $tpl->setCurrentBlock(
'buttons');
 
 2508        $tpl->setVariable(
'BUTTON', $button->render());
 
 2509        $tpl->parseCurrentBlock();
 
 2512        $button->setId(
'tst_cancel_discard_button');
 
 2513        $button->setCaption(
'cancel');
 
 2514        $button->setPrimary(
true);
 
 2515        $tpl->setCurrentBlock(
'buttons');
 
 2516        $tpl->setVariable(
'BUTTON', $button->render());
 
 2517        $tpl->parseCurrentBlock();
 
 2520        $modal->setId(
'tst_discard_solution_modal');
 
 2521        $modal->setHeading($this->lng->txt(
'discard_answer'));
 
 2522        $modal->setBody(
$tpl->get());
 
 2524        $this->tpl->setCurrentBlock(
'discard_solution_modal');
 
 2525        $this->tpl->setVariable(
'DISCARD_SOLUTION_MODAL', $modal->getHTML());
 
 2526        $this->tpl->parseCurrentBlock();
 
 2593        if (!empty(
$_SESSION[
'save_on_navigation_prevent_confirmation'])) {
 
 2597        $tpl = 
new ilTemplate(
'tpl.tst_player_confirmation_modal.html', 
true, 
true, 
'Modules/Test');
 
 2599        if ($this->object->isInstantFeedbackAnswerFixationEnabled() && $this->object->isForceInstantFeedbackEnabled()) {
 
 2600            $text =  $this->lng->txt(
'save_on_navigation_locked_confirmation');
 
 2602            $text =  $this->lng->txt(
'save_on_navigation_confirmation');
 
 2604        if ($this->object->isForceInstantFeedbackEnabled()) {
 
 2605            $text .= 
" " . $this->lng->txt(
'save_on_navigation_forced_feedback_hint');
 
 2607        $tpl->setVariable(
'CONFIRMATION_TEXT', 
$text);
 
 2611        $button->setId(
'tst_save_on_navigation_button');
 
 2612        $button->setUrl(
'#');
 
 2613        $button->setCaption(
'tst_save_and_proceed');
 
 2614        $button->setPrimary(
true);
 
 2615        $tpl->setCurrentBlock(
'buttons');
 
 2616        $tpl->setVariable(
'BUTTON', $button->render());
 
 2617        $tpl->parseCurrentBlock();
 
 2620        $button->setId(
'tst_cancel_on_navigation_button');
 
 2621        $button->setUrl(
'#');
 
 2622        $button->setCaption(
'cancel');
 
 2623        $button->setPrimary(
false);
 
 2624        $tpl->setCurrentBlock(
'buttons');
 
 2625        $tpl->setVariable(
'BUTTON', $button->render());
 
 2626        $tpl->parseCurrentBlock();
 
 2628        $tpl->setCurrentBlock(
'checkbox');
 
 2629        $tpl->setVariable(
'CONFIRMATION_CHECKBOX_NAME', 
'save_on_navigation_prevent_confirmation');
 
 2630        $tpl->setVariable(
'CONFIRMATION_CHECKBOX_LABEL', $this->lng->txt(
'save_on_navigation_prevent_confirmation'));
 
 2631        $tpl->parseCurrentBlock();
 
 2634        $modal->setId(
'tst_save_on_navigation_modal');
 
 2635        $modal->setHeading($this->lng->txt(
'save_on_navigation'));
 
 2636        $modal->setBody(
$tpl->get());
 
 2638        $this->tpl->setCurrentBlock(
'nav_while_edit_modal');
 
 2639        $this->tpl->setVariable(
'NAV_WHILE_EDIT_MODAL', $modal->getHTML());
 
 2640        $this->tpl->parseCurrentBlock();
 
 2650    protected function populateQuestionEditControl($questionGUI)
 
 2656        $state = $questionGUI->object->lookupForExistingSolutions($this->testSession->getActiveId(), $this->testSession->getPass());
 
 2667        if ($questionGUI->isAutosaveable() && $this->object->getAutosave()) {
 
 2669            $config[
'autosaveInterval'] = $this->
object->getAutosaveIval();
 
 2672            $config[
'autosaveInterval'] = 0;
 
 2677        $questionConfig = $questionGUI->object->getTestPresentationConfig();
 
 2681        $config[
'withFormChangeDetection'] = $questionConfig->isFormChangeDetectionEnabled();
 
 2684        $config[
'withBackgroundChangeDetection'] = $questionConfig->isBackgroundChangeDetectionEnabled();
 
 2688        $config[
'forcedInstantFeedback'] = $this->
object->isForceInstantFeedbackEnabled();
 
 2690        $this->tpl->addJavascript(
'./Modules/Test/js/ilTestPlayerQuestionEditControl.js');
 
 2691        $this->tpl->addOnLoadCode(
'il.TestPlayerQuestionEditControl.init(' . json_encode(
$config) . 
')');
 
 2708        $fixedSeed = $questionId . $this->testSession->getActiveId() . $this->testSession->getPass();
 
 2721        if (!isset(
$_SESSION[
'forced_feedback_navigation_url'])) {
 
 2722            $_SESSION[
'forced_feedback_navigation_url'] = array();
 
 2725        $_SESSION[
'forced_feedback_navigation_url'][$this->testSession->getActiveId()] = $forcedFeedbackNavUrl;
 
 2730        if (!isset(
$_SESSION[
'forced_feedback_navigation_url'])) {
 
 2734        if (!isset(
$_SESSION[
'forced_feedback_navigation_url'][$this->testSession->getActiveId()])) {
 
 2738        return $_SESSION[
'forced_feedback_navigation_url'][$this->testSession->getActiveId()];
 
 2748        if (isset(
$_SESSION[
'forced_feedback_navigation_url'][$this->testSession->getActiveId()])) {
 
 2749            unset(
$_SESSION[
'forced_feedback_navigation_url'][$this->testSession->getActiveId()]);
 
sprintf('%.4f', $callTime)
if(!array_key_exists('stateid', $_REQUEST)) $state
Handle linkback() response from LinkedIn.
An exception for terminatinating execution or to throw for unit testing.
Multiple choice question GUI representation.
Basic GUI class for assessment questions.
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)
const PRESENTATION_CONTEXT_TEST
setNavigationGUI($navigationGUI)
outQuestionForTest( $formaction, $active_id, $pass, $is_question_postponed=false, $user_post_solutions=false, $show_specific_inline_feedback=false)
getQuestionHeaderBlockBuilder()
outQuestionPage($a_temp_var, $a_postponed=false, $active_id="", $html="")
output question page
getGenericFeedbackOutput($active_id, $pass)
Returns the answer specific feedback for the question.
Abstract basic class which is to be extended by the concrete assessment question type classes.
static _instantiateQuestion($question_id)
getTestPresentationConfig()
Get the test question configuration (initialised once)
const CSS_CLASS_FEEDBACK_WRONG
const CSS_CLASS_FEEDBACK_CORRECT
const CMD_CONFIRM_REQUEST
const CMD_SHOW_LIST
command constants
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...
Confirmation screen class.
static formatDate(ilDateTime $date, $a_skip_day=false, $a_include_wd=false)
Format a date @access public.
@classDescription Date and time handling
static getInstance(ilTestSession $a_test_session)
static getInstance()
Get instance.
const DEFAULT_SKL_TRIG_NUM_ANSWERS_BARRIER
static _enabledAssessmentLogging()
check wether assessment logging is enabled or not
static getSyntaxStylePath()
get syntax style path
static getContentStylePath($a_style_id, $add_random=true)
get content style path
static lookupExamId($active_id, $pass)
static _getUsePreviousAnswers($active_id, $user_active_user_setting=false)
Returns if the previous results should be hidden for a learner.
static allObligationsAnswered($test_id, $active_id, $pass)
checks wether all questions marked as obligatory were answered within the test pass with given testId...
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test.
static buildExamId($active_id, $pass, $test_obj_id=null)
static _getSolvedQuestions($active_id, $question_fi=null)
get solved questions
static get($a_var)
Get a value.
special template class to simplify handling of ITX/PEAR
Output class for assessment test evaluation.
Base Exception for all Exceptions relating to Modules/Test.
static generatePDF($pdf_output, $output_mode, $filename=null, $purpose=null)
Class ilTestPassFinishTasks.
Output class for assessment test execution.
handleSkillTriggering(ilTestSession $testSession)
populateContentStyleBlock()
checkTestSessionUser(ilTestSession $testSession)
populateNextButtons($disabled, $primaryNext)
populateDiscardSolutionModal()
redirectAfterAutosaveCmd()
isShowingPostponeStatusReguired($questionId)
buildFixedShufflerSeed($questionId)
populateMessageContent($contentHTML)
saveTagsCmd()
Save tags for tagging gui.
initTestQuestionConfig(assQuestion $questionOBJ)
const FIXED_SHUFFLER_SEED_MIN_LENGTH
confirmHintRequestCmd()
Go to hint request confirmation.
__construct($a_object)
ilTestOutputGUI constructor
getNextCommandParameter()
removeIntermediateSolution()
remove an auto-saved solution of the current question
setAnswerChangedParameter($changed=true)
Set the 'answer changed' url parameter for generated links.
confirmFinishCmd()
The final submission of a test was confirmed.
isQuestionSummaryFinishTestButtonRequired()
getPresentationModeParameter()
buildEditableStateQuestionNavigationGUI($questionId, $charSelectorAvailable)
startPlayerCmd()
Start a test for the first time.
populateSolutionBlock($solutionoutput)
buildPreviousButtonInstance($disabled)
initProcessLocker($activeId)
prepareTestPage($presentationMode, $sequenceElement, $questionId)
isOptionalQuestionAnsweringConfirmationRequired($sequenceElement)
submitIntermediateSolutionCmd()
handleTearsAndAngerQuestionIsNull($questionId, $sequenceElement)
isNrOfTriesReached()
nr of tries exceeded
outObligationsOnlySummaryCmd()
const PRESENTATION_MODE_EDIT
populateLowerPreviousButtonBlock($disabled)
cancelAnswerOptionalQuestionsCmd()
handleQuestionActionCmd()
getQuestionInstance($questionId, $fromCache=true)
saveQuestionSolution($authorized=true, $force=false)
saves the user input of a question
handlePasswordProtectionRedirect()
isFirstQuestionInSequence($sequenceElement)
populateGenericFeedbackBlock(assQuestionGUI $question_gui, $solutionCorrect)
getRegisteredForcedFeedbackNavUrl()
populateUpperPreviousButtonBlock($disabled)
populateSpecificFeedbackBlock($question_gui)
unmarkQuestionCmd()
Set a question unsolved.
showSideList($presentationMode, $currentSequenceElement)
markQuestionAndSaveIntermediateCmd()
getCurrentSequenceElement()
populateSyntaxStyleBlock()
showMaximumAllowedUsersReachedMessage()
populateUpperNextButtonBlock($disabled, $primaryNext)
initTestCmd()
Start a test for the first time after a redirect.
populateInstantResponseModal(assQuestionGUI $questionGui, $navUrl)
endingTimeReached()
handle endingTimeReached
buildQuestionAnswerShuffler($questionId)
maxProcessingTimeReached()
Outputs a message when the maximum processing time is reached.
showQuestionEditable(assQuestionGUI $questionGui, $formAction, $isQuestionWorkedThrough, $instantResponse)
getQuestionGuiInstance($questionId, $fromCache=true)
getInstantResponseParameter()
resumePlayerCmd()
Resume a test at the last position.
$maxProcessingTimeReached
unmarkQuestionAndSaveIntermediateCmd()
handleIntermediateSubmit()
Check the 'answer changed' parameter when a question form is intermediately submitted.
getIntroductionPageButtonLabel()
confirmSubmitAnswers()
confirm submit results if confirm then results are submitted and the screen will be redirected to the...
getSequenceElementParameter()
performTestPassFinishedTasks($finishedPass)
ensureExistingTestSession(ilTestSession $testSession)
determineInlineScoreDisplay()
populateScoreBlock($reachedPoints, $maxPoints)
updateWorkingTime()
updates working time and stores state saveresult to see if question has to be stored or not
populateHelperGuiContent($helperGui)
handleUserSettings()
Handles some form parameters on starting and resuming a test.
populateInstantResponseBlocks(assQuestionGUI $questionGui, $authorizedSolution)
getQuestionsDefaultPresentationMode($isQuestionWorkedThrough)
outCorrectSolution()
Creates an output of the solution of an answer compared to the correct solution.
showAnswerOptionalQuestionsConfirmation()
detectChangesCmd()
Detect changes sent in the background to the server This is called by ajax from ilTestPlayerQuestionE...
populateLowerNextButtonBlock($disabled, $primaryNext)
finishTestCmd($requires_confirmation=true)
getTestNavigationToolbarGUI()
markQuestionCmd()
Set a question solved.
populatePreviousButtons($disabled)
populateTestNavigationToolbar(ilTestNavigationToolbarGUI $toolbarGUI)
const PRESENTATION_MODE_VIEW
getNavigationUrlParameter()
isTestSignRedirectRequired($activeId, $lastFinishedPass)
populateNavWhenChangedModal()
confirmAnswerOptionalQuestionsCmd()
getAnswerChangedParameter()
Get the 'answer changed' status from the current request It may be set by ilTestPlayerNavigationContr...
determineSolutionPassIndex(assQuestionGUI $questionGui)
archiveParticipantSubmission($active, $pass)
populateCharSelectorIfRequired()
buildTestPassQuestionList()
isParticipantsAnswerFixed($questionId)
unregisterForcedFeedbackNavUrl()
showRequestedHintListCmd()
Go to requested hint list.
afterTestPassFinishedCmd()
outProcessingTime($active_id)
isMaxProcessingTimeReached()
Checks wheather the maximum processing time is reached or not.
resetSequenceElementParameter()
buildReadOnlyStateQuestionNavigationGUI($questionId)
setAnonymousIdCmd()
Sets a session variable with the test access code for an anonymous test user.
saveNavigationPreventConfirmation()
Save the save the switch to prevent the navigation confirmation.
outQuestionSummaryWithObligationsInfoCmd()
registerForcedFeedbackNavUrl($forcedFeedbackNavUrl)
isLastQuestionInSequence($sequenceElement)
checkOnlineTestAccess()
check access restrictions like client ip, partipating user etc.
populateQuestionNavigation($sequenceElement, $disabled, $primaryNext)
buildNextButtonInstance($disabled, $primaryNext)
toggleSideListCmd()
Toggle side list.
getNextSequenceParameter()
isTestAccessible()
test accessible returns true if the user can perform the test
showQuestionViewable(assQuestionGUI $questionGui, $formAction, $isQuestionWorkedThrough, $instantResponse)
getContentBlockName()
Returns the name of the current content block (depends on the kiosk mode setting)
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...
isForcedFeedbackNavUrlRegistered()
outUserResultsOverviewCmd()
outQuestionSummaryCmd($fullpage=true, $contextFinishTest=false, $obligationsNotAnswered=false, $obligationsFilter=false)
Output of a summary of all test questions for test participants.
const REDIRECT_ON_TIME_LIMIT
const SHOW_INSTANT_RESPONSE
const QUESTION_SUMMARY_INC_OBLIGATIONS
const BACK_TO_INFO_SCREEN
const AFTER_TEST_PASS_FINISHED
const SHOW_FINAL_STATMENT
const ACCESS_CODE_CONFIRMED
const CONFIRM_HINT_REQUEST
const DISPLAY_ACCESS_CODE
const UNMARK_QUESTION_SAVE
const SHOW_REQUESTED_HINTS_LIST
const BACK_FROM_FINISHING
const QUESTION_SUMMARY_OBLIGATIONS_ONLY
Service GUI class for tests.
getCorrectSolutionOutput($question_id, $active_id, $pass, ilTestQuestionRelatedObjectivesList $objectivesList=null)
Returns an output of the solution to an answer compared to the correct solution.
getObjectiveOrientedContainer()
getResultsSignature()
Returns HTML code for a signature field.
buildQuestionRelatedObjectivesList(ilLOTestQuestionAdapter $objectivesAdapter, ilTestQuestionSequence $testSequence)
getAdditionalUsrDataHtmlAndPopulateWindowTitle($testSession, $active_id, $overwrite_anonymity=false)
Returns the user data for a test results output.
static getWebspaceDir($mode="filesystem")
get webspace directory
static getStyleSheetLocation($mode="output", $a_css_name="", $a_css_location="")
get full style sheet file name (path inclusive) of current user
static redirect($a_script)
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
static makeDirParents($a_dir)
Create a new directory and all parent directories.
static sendInfo($a_info="", $a_keep=false)
Send Info Message to Screen.
$GLOBALS['loaded']
Global hash that tracks already loaded includes.
redirection script todo: (a better solution should control the processing via a xml file)
if(!file_exists("$old.txt")) if( $old===$new) if(file_exists("$new.txt")) $file
foreach($_POST as $key=> $value) $res
if((!isset($_SERVER['DOCUMENT_ROOT'])) OR(empty($_SERVER['DOCUMENT_ROOT']))) $_SERVER['DOCUMENT_ROOT']