/** * Creates the learners output of a question */ protected function outWorkingForm($sequence = "", $test_id, $postpone_allowed, $directfeedback = false) { global $ilUser; if (!$this->isValidSequenceElement($sequence)) { $sequence = $this->testSequence->getFirstSequence(); } $_SESSION["active_time_id"] = $this->object->startWorkingTime($this->testSession->getActiveId(), $this->testSession->getPass()); $this->populateContentStyleBlock(); $this->populateSyntaxStyleBlock(); if ($this->object->getListOfQuestions()) { $this->showSideList(); } $questionId = $this->testSequence->getQuestionForSequence($sequence); if (!(int) $questionId && $this->testSession->isObjectiveOriented()) { ilUtil::sendFailure(sprintf($this->lng->txt('tst_objective_oriented_test_pass_without_questions'), $this->object->getTitle()), true); $this->performCustomRedirect(); } $question_gui = $this->object->createQuestionGUI("", $questionId); if (!is_object($question_gui)) { global $ilLog; $ilLog->write("INV SEQ: active={$this->testSession->getActiveId()} qId={$questionId} seq={$sequence} " . serialize($this->testSequence)); $ilLog->logStack('INV SEQ'); $this->ctrl->setParameter($this, 'gotosequence', $this->testSequence->getFirstSequence()); $this->ctrl->setParameter($this, 'activecommand', 'gotoquestion'); $this->ctrl->redirect($this, 'redirectQuestion'); } $question_gui->setTargetGui($this); if ($this->object->getJavaScriptOutput()) { $question_gui->object->setOutputType(OUTPUT_JAVASCRIPT); } $is_postponed = $this->testSequence->isPostponedQuestion($question_gui->object->getId()); $this->ctrl->setParameter($this, "sequence", "{$sequence}"); $formaction = $this->ctrl->getFormAction($this, "gotoQuestion"); $question_gui->setSequenceNumber($this->testSequence->getPositionOfSequence($sequence)); $question_gui->setQuestionCount($this->testSequence->getUserQuestionCount()); // output question $user_post_solution = FALSE; if (array_key_exists("previouspost", $_SESSION)) { $user_post_solution = $_SESSION["previouspost"]; unset($_SESSION["previouspost"]); } // Determine $answer_feedback: It should hold a boolean stating if answer-specific-feedback is to be given. // It gets the parameter "Scoring and Results" -> "Instant Feedback" -> "Show Answer-Specific Feedback" // $directfeedback holds a boolean stating if the instant feedback was requested using the "Check" button. $answer_feedback = FALSE; if ($directfeedback && $this->object->getSpecificAnswerFeedback()) { $answer_feedback = TRUE; } if ($this->isParticipantsAnswerFixed($questionId)) { $solutionoutput = $question_gui->getSolutionOutput($this->testSession->getActiveId(), NULL, FALSE, false, true, $answer_feedback, false, FALSE, true); $pageoutput = $question_gui->outQuestionPage("", $this->testSequence->isPostponedQuestion($questionId), $this->testSession->getActiveId(), $solutionoutput); $this->tpl->setVariable("QUESTION_OUTPUT", $pageoutput); $this->tpl->setVariable("FORMACTION", $formaction); $directfeedback = true; } else { // Answer specific feedback is rendered into the display of the test question with in the concrete question types outQuestionForTest-method. // Notation of the params prior to getting rid of this crap in favor of a class $question_gui->outQuestionForTest($formaction, $this->testSession->getActiveId(), NULL, $is_postponed, $user_post_solution, $answer_feedback); // The display of specific inline feedback and specific feedback in an own block is to honor questions, which // have the possibility to embed the specific feedback into their output while maintaining compatibility to // questions, which do not have such facilities. E.g. there can be no "specific inline feedback" for essay // questions, while the multiple-choice questions do well. $this->fillQuestionRelatedNavigation($question_gui); } if ($directfeedback) { // This controls if the solution should be shown. // It gets the parameter "Scoring and Results" -> "Instant Feedback" -> "Show Solutions" if ($this->object->getInstantFeedbackSolution()) { $show_question_inline_score = $this->determineInlineScoreDisplay(); // Notation of the params prior to getting rid of this crap in favor of a class $solutionoutput = $question_gui->getSolutionOutput($this->testSession->getActiveId(), NULL, FALSE, $show_question_inline_score, FALSE, FALSE, TRUE, FALSE, FALSE); $this->populateSolutionBlock($solutionoutput); } // This controls if the score should be shown. // It gets the parameter "Scoring and Results" -> "Instant Feedback" -> "Show Results (Only Points)" if ($this->object->getAnswerFeedbackPoints()) { $reachedPoints = $question_gui->object->getAdjustedReachedPoints($this->testSession->getActiveId(), NULL); $maxPoints = $question_gui->object->getMaximumPoints(); $this->populateScoreBlock($reachedPoints, $maxPoints); } // This controls if the generic feedback should be shown. // It gets the parameter "Scoring and Results" -> "Instant Feedback" -> "Show Solutions" if ($this->object->getGenericAnswerFeedback()) { $this->populateGenericFeedbackBlock($question_gui); } // This controls if the specific feedback should be shown. // It gets the parameter "Scoring and Results" -> "Instant Feedback" -> "Show Answer-Specific Feedback" if ($this->object->getSpecificAnswerFeedback()) { $this->populateSpecificFeedbackBlock($question_gui); } } $this->populatePreviousButtons($sequence); if ($postpone_allowed && !$is_postponed) { $this->populatePostponeButtons(); } if ($this->object->getListOfQuestions()) { $this->populateSummaryButtons(); } if ($this->object->getShowCancel()) { $this->populateCancelButtonBlock(); } if ($this->isLastQuestionInSequence($question_gui)) { if ($this->object->getListOfQuestionsEnd()) { $this->populateNextButtonsLeadingToSummary(); } else { $this->populateNextButtonsLeadingToEndOfTest(); } } else { $this->populateNextButtonsLeadingToQuestion(); } if ($this->object->getShowMarker()) { include_once "./Modules/Test/classes/class.ilObjTest.php"; $solved_array = ilObjTest::_getSolvedQuestions($this->testSession->getActiveId(), $question_gui->object->getId()); $solved = 0; if (count($solved_array) > 0) { $solved = array_pop($solved_array); $solved = $solved["solved"]; } if ($solved == 1) { $this->populateQuestionMarkingBlockAsMarked(); } else { $this->populateQuestionMarkingBlockAsUnmarked(); } } $this->populateCharSelector(); if ($this->object->getJavaScriptOutput()) { $this->tpl->setVariable("JAVASCRIPT_TITLE", $this->lng->txt("disable_javascript")); $this->ctrl->setParameter($this, "tst_javascript", "0"); $this->tpl->setVariable("JAVASCRIPT_URL", $this->ctrl->getLinkTarget($this, "gotoQuestion")); } else { $this->tpl->setVariable("JAVASCRIPT_TITLE", $this->lng->txt("enable_javascript")); $this->ctrl->setParameter($this, "tst_javascript", "1"); $this->tpl->setVariable("JAVASCRIPT_URL", $this->ctrl->getLinkTarget($this, "gotoQuestion")); } if ($question_gui->object->requiresJsSwitch() && !$this->object->getForceJS()) { $this->tpl->touchBlock("jsswitch"); } $this->tpl->addJavaScript(ilUtil::getJSLocation("autosave.js", "Modules/Test")); $this->tpl->setVariable("AUTOSAVE_URL", $this->ctrl->getFormAction($this, "autosave", "", true)); if ($question_gui->isAutosaveable() && $this->object->getAutosave()) { $this->tpl->touchBlock('autosave'); //$this->tpl->setVariable("BTN_SAVE", "Zwischenspeichern"); //$this->tpl->setVariable("CMD_SAVE", "gotoquestion_{$sequence}"); //$this->tpl->setVariable("AUTOSAVEFORMACTION", str_replace("&", "&", $this->ctrl->getFormAction($this))); $this->tpl->setVariable("AUTOSAVEFORMACTION", str_replace("&", "&", $this->ctrl->getLinkTarget($this, "autosave"))); $this->tpl->setVariable("AUTOSAVEINTERVAL", $this->object->getAutosaveIval()); } if ($this->object->areObligationsEnabled() && ilObjTest::isQuestionObligatory($question_gui->object->getId())) { $this->tpl->touchBlock('question_obligatory'); $this->tpl->setVariable('QUESTION_OBLIGATORY', $this->lng->txt('required_field')); } }
function &getSequenceSummary($obligationsFilter = false) { $correctedsequence = $this->getCorrectedSequence(); $result_array = array(); include_once "./Modules/Test/classes/class.ilObjTest.php"; $solved_questions = ilObjTest::_getSolvedQuestions($this->active_id); $key = 1; foreach ($correctedsequence as $sequence) { $question =& ilObjTest::_instanciateQuestion($this->getQuestionForSequence($sequence)); if (is_object($question)) { $worked_through = $question->_isWorkedThrough($this->active_id, $question->getId(), $this->pass); $solved = 0; if (array_key_exists($question->getId(), $solved_questions)) { $solved = $solved_questions[$question->getId()]["solved"]; } $is_postponed = $this->isPostponedQuestion($question->getId()); $row = array("nr" => "{$key}", "title" => $question->getTitle(), "qid" => $question->getId(), "visited" => $worked_through, "solved" => $solved ? "1" : "0", "description" => $question->getComment(), "points" => $question->getMaximumPoints(), "worked_through" => $worked_through, "postponed" => $is_postponed, "sequence" => $sequence, "obligatory" => ilObjTest::isQuestionObligatory($question->getId()), 'isAnswered' => $question->isAnswered($this->active_id, $this->pass)); if (!$obligationsFilter || $row['obligatory']) { array_push($result_array, $row); } $key++; } } return $result_array; }
/** * Output of a summary of all test questions for test participants */ public function outQuestionSummary($fullpage = true, $contextFinishTest = false, $obligationsNotAnswered = false, $obligationsFilter = false) { if ($fullpage) { $this->tpl->addBlockFile($this->getContentBlockName(), "adm_content", "tpl.il_as_tst_question_summary.html", "Modules/Test"); } if ($obligationsNotAnswered) { ilUtil::sendFailure($this->lng->txt('not_all_obligations_answered')); } $active_id = $this->object->getTestSession()->getActiveId(); $result_array =& $this->object->getTestSequence()->getSequenceSummary($obligationsFilter); $marked_questions = array(); if ($this->object->getKioskMode() && $fullpage) { $head = $this->getKioskHead(); if (strlen($head)) { $this->tpl->setCurrentBlock("kiosk_options"); $this->tpl->setVariable("KIOSK_HEAD", $head); $this->tpl->parseCurrentBlock(); } } if ($this->object->getShowMarker()) { include_once "./Modules/Test/classes/class.ilObjTest.php"; $marked_questions = ilObjTest::_getSolvedQuestions($active_id); } $data = array(); foreach ($result_array as $key => $value) { $this->ctrl->setParameter($this, "sequence", $value["sequence"]); $href = $this->ctrl->getLinkTargetByClass(get_class($this), "gotoQuestion"); $this->tpl->setVariable("VALUE_QUESTION_TITLE", "<a href=\"" . $this->ctrl->getLinkTargetByClass(get_class($this), "gotoQuestion") . "\">" . $this->object->getQuestionTitle($value["title"]) . "</a>"); $this->ctrl->setParameter($this, "sequence", $_GET["sequence"]); $description = ""; if ($this->object->getListOfQuestionsDescription()) { $description = $value["description"]; } $points = ""; if (!$this->object->getTitleOutput()) { $points = $value["points"] . " " . $this->lng->txt("points_short"); } $marked = false; if (count($marked_questions)) { if (array_key_exists($value["qid"], $marked_questions)) { $obj = $marked_questions[$value["qid"]]; if ($obj["solved"] == 1) { $marked = true; } } } array_push($data, array('order' => $value["nr"], 'href' => $href, 'title' => $this->object->getQuestionTitle($value["title"]), 'description' => $description, 'worked_through' => $value["worked_through"] ? true : false, 'postponed' => $value["postponed"] ? $this->lng->txt("postponed") : '', 'points' => $points, 'marked' => $marked, 'sequence' => $value["sequence"], 'obligatory' => $value['obligatory'])); } $this->ctrl->setParameter($this, "sequence", $_GET["sequence"]); if ($fullpage) { include_once "./Modules/Test/classes/tables/class.ilListOfQuestionsTableGUI.php"; $table_gui = new ilListOfQuestionsTableGUI($this, 'backFromSummary', !$this->object->getTitleOutput(), $this->object->getShowMarker(), $obligationsNotAnswered, $obligationsFilter); $table_gui->setData($data); $this->tpl->setVariable('TABLE_LIST_OF_QUESTIONS', $table_gui->getHTML()); if ($this->object->getEnableProcessingTime()) { $this->outProcessingTime($active_id); } } else { $template = new ilTemplate('tpl.il_as_tst_list_of_questions_short.html', true, true, 'Modules/Test'); foreach ($data as $row) { if (strlen($row['description'])) { $template->setCurrentBlock('description'); $template->setVariable("DESCRIPTION", $row['description']); $template->parseCurrentBlock(); } $active = $row['sequence'] == $this->sequence ? ' active' : ''; $template->setCurrentBlock('item'); $template->setVariable('CLASS', $row['walked_through'] ? 'answered' . $active : 'unanswered' . $active); $template->setVariable('ITEM', ilUtil::prepareFormOutput($row['title'])); $template->setVariable('SEQUENCE', $row['sequence']); $template->parseCurrentBlock(); } $template->setVariable('LIST_OF_QUESTIONS', $this->lng->txt('list_of_questions')); $this->tpl->setVariable('LIST_OF_QUESTIONS', $template->get()); } }
protected function getMarkedQuestions() { if ($this->object->getShowMarker()) { include_once "./Modules/Test/classes/class.ilObjTest.php"; $marked_questions = ilObjTest::_getSolvedQuestions($this->testSession->getActiveId()); } else { $marked_questions = array(); } return $marked_questions; }
/** * Creates the learners output of a question */ protected function outWorkingForm($sequence = "", $test_id, $postpone_allowed, $directfeedback = false) { global $ilUser; $_SESSION["active_time_id"] = $this->object->startWorkingTime($this->testSession->getActiveId(), $this->testSession->getPass()); $this->populateContentStyleBlock(); $this->populateSyntaxStyleBlock(); $question_gui = $this->object->createQuestionGUI("", $this->testSession->getCurrentQuestionId()); $question_gui->setTargetGui($this); $question_gui->setQuestionCount($this->testSequence->getLastPositionIndex()); $question_gui->setSequenceNumber($this->testSequence->getCurrentPositionIndex($this->testSession->getCurrentQuestionId())); $this->ctrl->setParameter($this, 'sequence', $this->testSession->getCurrentQuestionId()); if ($this->object->getJavaScriptOutput()) { $question_gui->object->setOutputType(OUTPUT_JAVASCRIPT); } $is_postponed = $this->testSequence->isPostponedQuestion($question_gui->object->getId()); $formaction = $this->ctrl->getFormAction($this); // output question $user_post_solution = FALSE; if (isset($_SESSION['previouspost'])) { $user_post_solution = $_SESSION['previouspost']; unset($_SESSION['previouspost']); } global $ilNavigationHistory; $ilNavigationHistory->addItem($_GET["ref_id"], $this->ctrl->getLinkTarget($this, "resumePlayer"), "tst"); // Determine $answer_feedback: It should hold a boolean stating if answer-specific-feedback is to be given. // It gets the parameter "Scoring and Results" -> "Instant Feedback" -> "Show Answer-Specific Feedback" // $directfeedback holds a boolean stating if the instant feedback was requested using the "Check" button. $answer_feedback = FALSE; if ($directfeedback && $this->object->getSpecificAnswerFeedback()) { $answer_feedback = TRUE; } // Answer specific feedback is rendered into the display of the test question with in the concrete question types outQuestionForTest-method. // Notation of the params prior to getting rid of this crap in favor of a class $question_gui->outQuestionForTest($formaction, $this->testSession->getActiveId(), NULL, $is_postponed, $user_post_solution, $answer_feedback); // The display of specific inline feedback and specific feedback in an own block is to honor questions, which // have the possibility to embed the specific feedback into their output while maintaining compatibility to // questions, which do not have such facilities. E.g. there can be no "specific inline feedback" for essay // questions, while the multiple-choice questions do well. $this->fillQuestionRelatedNavigation($question_gui); if ($directfeedback) { // This controls if the solution should be shown. // It gets the parameter "Scoring and Results" -> "Instant Feedback" -> "Show Solutions" if ($this->object->getInstantFeedbackSolution()) { $show_question_inline_score = $this->determineInlineScoreDisplay(); // Notation of the params prior to getting rid of this crap in favor of a class $solutionoutput = $question_gui->getSolutionOutput($this->testSession->getActiveId(), NULL, TRUE, $show_question_inline_score, FALSE, FALSE, TRUE, FALSE, FALSE); $this->populateSolutionBlock($solutionoutput); } // This controls if the score should be shown. // It gets the parameter "Scoring and Results" -> "Instant Feedback" -> "Show Results (Only Points)" if ($this->object->getAnswerFeedbackPoints()) { $reachedPoints = $question_gui->object->getAdjustedReachedPoints($this->testSession->getActiveId(), NULL); $maxPoints = $question_gui->object->getMaximumPoints(); $this->populateScoreBlock($reachedPoints, $maxPoints); } // This controls if the generic feedback should be shown. // It gets the parameter "Scoring and Results" -> "Instant Feedback" -> "Show Solutions" if ($this->object->getGenericAnswerFeedback()) { $this->populateGenericFeedbackBlock($question_gui); } // This controls if the specific feedback should be shown. // It gets the parameter "Scoring and Results" -> "Instant Feedback" -> "Show Answer-Specific Feedback" if ($this->object->getSpecificAnswerFeedback()) { $this->populateSpecificFeedbackBlock($question_gui); } } $this->populatePreviousButtons($this->testSession->getCurrentQuestionId()); if ($postpone_allowed) { $this->populatePostponeButtons(); } if ($this->object->getShowCancel()) { $this->populateCancelButtonBlock(); } if ($this->isLastQuestionInSequence($question_gui)) { if ($this->object->getListOfQuestionsEnd()) { $this->populateNextButtonsLeadingToSummary(); } else { $this->populateNextButtonsLeadingToEndOfTest(); } } else { $this->populateNextButtonsLeadingToQuestion(); } if ($this->dynamicQuestionSetConfig->isTaxonomyFilterEnabled()) { $this->populateQuestionSelectionButtons(); } if ($this->object->getShowMarker()) { include_once "./Modules/Test/classes/class.ilObjTest.php"; $solved_array = ilObjTest::_getSolvedQuestions($this->testSession->getActiveId(), $question_gui->object->getId()); $solved = 0; if (count($solved_array) > 0) { $solved = array_pop($solved_array); $solved = $solved["solved"]; } if ($solved == 1) { $this->populateQuestionMarkingBlockAsMarked(); } else { $this->populateQuestionMarkingBlockAsUnmarked(); } } if ($this->object->getJavaScriptOutput()) { $this->tpl->setVariable("JAVASCRIPT_IMAGE", ilUtil::getImagePath("javascript_disable.png")); $this->tpl->setVariable("JAVASCRIPT_IMAGE_ALT", $this->lng->txt("disable_javascript")); $this->tpl->setVariable("JAVASCRIPT_IMAGE_TITLE", $this->lng->txt("disable_javascript")); $this->ctrl->setParameter($this, "tst_javascript", "0"); $this->tpl->setVariable("JAVASCRIPT_URL", $this->ctrl->getLinkTarget($this, "gotoQuestion")); } else { $this->tpl->setVariable("JAVASCRIPT_IMAGE", ilUtil::getImagePath("javascript.png")); $this->tpl->setVariable("JAVASCRIPT_IMAGE_ALT", $this->lng->txt("enable_javascript")); $this->tpl->setVariable("JAVASCRIPT_IMAGE_TITLE", $this->lng->txt("enable_javascript")); $this->ctrl->setParameter($this, "tst_javascript", "1"); $this->tpl->setVariable("JAVASCRIPT_URL", $this->ctrl->getLinkTarget($this, "gotoQuestion")); } if ($question_gui->object->supportsJavascriptOutput()) { $this->tpl->touchBlock("jsswitch"); } $this->tpl->addJavaScript(ilUtil::getJSLocation("autosave.js", "Modules/Test")); $this->tpl->setVariable("AUTOSAVE_URL", $this->ctrl->getFormAction($this, "autosave", "", true)); if ($question_gui->isAutosaveable() && $this->object->getAutosave()) { $this->tpl->touchBlock('autosave'); //$this->tpl->setVariable("BTN_SAVE", "Zwischenspeichern"); //$this->tpl->setVariable("CMD_SAVE", "gotoquestion_{$sequence}"); //$this->tpl->setVariable("AUTOSAVEFORMACTION", str_replace("&", "&", $this->ctrl->getFormAction($this))); $this->tpl->setVariable("AUTOSAVEFORMACTION", str_replace("&", "&", $this->ctrl->getLinkTarget($this, "autosave"))); $this->tpl->setVariable("AUTOSAVEINTERVAL", $this->object->getAutosaveIval()); } if ($this->object->areObligationsEnabled() && ilObjTest::isQuestionObligatory($question_gui->object->getId())) { $this->tpl->touchBlock('question_obligatory'); $this->tpl->setVariable('QUESTION_OBLIGATORY', $this->lng->txt('required_field')); } }