19 declare(strict_types=1);
45 $this->
tabs->clearTargets();
47 $cmd = $this->
ctrl->getCmd();
48 $next_class = $this->
ctrl->getNextClass($this);
51 if ($cmd ===
'autosave') {
52 echo $this->
lng->txt(
'autosave_failed') .
': ' . $read_access;
55 $this->tpl->setOnScreenMessage(
'failure', $read_access,
true);
56 $this->
ctrl->redirectByClass([ilRepositoryGUI::class, ilObjTestGUI::class, TestScreenGUI::class]);
59 $this->
ctrl->saveParameter($this,
"sequence");
60 $this->
ctrl->saveParameter($this,
"pmode");
61 $this->
ctrl->saveParameter($this,
"active_id");
74 $this->testSequence = $test_sequence_factory->getSequenceByTestSession($this->test_session);
75 $this->testSequence->loadFromDb();
76 $this->testSequence->loadQuestions();
85 $instance_name = $this->
settings->get(
'short_inst_name') ??
'';
86 if (trim($instance_name) ===
'') {
87 $instance_name =
'ILIAS';
89 $this->global_screen->tool()->context()->current()->addAdditionalData(
93 $this->global_screen->tool()->context()->current()->addAdditionalData(
95 $this->
object->getKioskMode()
98 $title = $this->
object->getTitle();
100 $title .=
' - ' . $this->
lng->txt(
'question') . $sequence_index;
102 $this->global_screen->tool()->context()->current()->addAdditionalData(
106 $this->global_screen->tool()->context()->current()->addAdditionalData(
114 switch ($next_class) {
115 case 'ilassquestionpagegui':
121 $ret = $this->
ctrl->forwardCommand($page_gui);
124 case 'iltestsubmissionreviewgui':
130 $ret = $this->
ctrl->forwardCommand($gui);
133 case 'ilassquestionhintrequestgui':
136 $questionGUI = $this->
object->createQuestionGUI(
138 $this->testSequence->getQuestionForSequence($this->getCurrentSequenceElement())
142 $questionGUI->object->getId(),
143 $this->test_session->getActiveId(),
144 $this->test_session->getPass()
151 $questionHintTracking,
162 $ret = $this->
ctrl->forwardCommand($gui);
165 case 'ilassspecfeedbackpagegui':
166 case 'ilassgenfeedbackpagegui':
167 $id = $this->testrequest->int(
'pg_id');
168 if ($this->
ctrl->getCmd() !==
'displayMediaFullscreen' 174 $next_class ===
'ilassgenfeedbackpagegui' ?
'qfbg' :
'qfbs',
176 ))->displayMediaFullscreen();
179 case 'iltestpasswordprotectiongui':
187 $this->passwordChecker,
191 $ret = $this->
ctrl->forwardCommand($gui);
199 if (strtolower($cmd) ===
'showquestion') {
201 $testPassesSelector->setActiveId($this->test_session->getActiveId());
202 $testPassesSelector->setLastFinishedPass($this->test_session->getLastFinishedPass());
204 if (!$testPassesSelector->openPassExists()) {
205 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'tst_pass_finished'),
true);
206 $this->
ctrl->redirectByClass([ilRepositoryGUI::class, ilObjTestGUI::class, ilTestScreenGUI::class]);
210 if ($cmd ===
'outQuestionSummary' 211 || $cmd ===
'submitSolution') {
216 $ret = $this->$cmd();
227 $this->test_session->setUserId($this->
user->getId());
229 if ($access_code != null && isset($access_code[$this->
object->getTestId()])) {
230 $this->test_session->setAnonymousId($access_code[$this->
object->getTestId()]);
235 $this->test_session->saveToDb();
237 $active_id = $this->test_session->getActiveId();
238 $this->
ctrl->setParameter($this,
"active_id", $active_id);
240 $shuffle = $this->
object->getShuffleQuestions();
241 if ($this->
object->isRandomTest()) {
244 $this->
object->loadQuestions();
248 $this->
object->updateTestPassResults(
250 $this->test_session->getPass(),
251 $this->
object->areObligationsEnabled(),
253 $this->
object->getId()
257 if (!$this->testSequence->hasSequence()) {
258 $this->testSequence->createNewSequence($this->
object->getQuestionCount(), $shuffle);
259 $this->testSequence->saveToDb();
262 $this->testSequence->loadFromDb();
263 $this->testSequence->loadQuestions();
265 if ($this->test_session->isObjectiveOriented()) {
268 $objectivesAdapter->notifyTestStart($this->test_session, $this->
object->getId());
269 $objectivesAdapter->prepareTestPass($this->test_session, $this->testSequence);
271 $objectivesAdapter->buildQuestionRelatedObjectiveList(
273 $this->question_related_objectives_list
276 if ($this->testSequence->hasOptionalQuestions()) {
279 $this->testSequence->reorderOptionalQuestionsToSequenceEnd();
280 $this->testSequence->saveToDb();
284 $active_time_id = $this->
object->startWorkingTime(
285 $this->test_session->getActiveId(),
286 $this->test_session->getPass()
292 $sequence_element = $this->testSequence->getFirstSequence();
294 $this->
ctrl->setParameter($this,
'sequence', $sequence_element);
295 $this->
ctrl->setParameter($this,
'pmode',
'');
297 if ($this->
object->getListOfQuestionsStart()) {
311 if ($sequence_element ===
false) {
315 if ($sequence_element < 1) {
319 if (!$this->testSequence->getPositionOfSequence($sequence_element)) {
332 $this->
object->startWorkingTime(
333 $this->test_session->getActiveId(),
334 $this->test_session->getPass()
338 $this->
help->setScreenIdComponent(
"tst");
339 $this->
help->setScreenId(
"assessment");
340 $this->
help->setSubScreenId(
"question");
345 $sequence_element = $this->testSequence->getFirstSequence();
348 $this->test_session->setLastSequence($sequence_element ?? 0);
349 $this->test_session->saveToDb();
351 $questionId = $this->testSequence->getQuestionForSequence($sequence_element ?? 0);
353 if (!(
int) $questionId && $this->test_session->isObjectiveOriented()) {
357 if ($questionId !== null && !$this->testSequence->isQuestionPresented($questionId)) {
358 $this->testSequence->setQuestionPresented($questionId);
359 $this->testSequence->saveToDb();
362 $isQuestionWorkedThrough = $this->questioninfo->lookupResultRecordExist(
363 $this->test_session->getActiveId(),
365 $this->test_session->getPass()
369 $instant_response =
false;
372 $s = $this->
object->getMainSettings()->getQuestionBehaviourSettings();
373 if ($s->getInstantFeedbackGenericEnabled()
374 || $s->getInstantFeedbackPointsEnabled()
375 || $s->getInstantFeedbackSolutionEnabled()
376 || $s->getInstantFeedbackSpecificEnabled()) {
377 $instant_response =
true;
382 if (!$this->
object->isInstantFeedbackAnswerFixationEnabled()) {
394 $questionGui->setSequenceNumber($this->testSequence->getPositionOfSequence($sequence_element));
395 $questionGui->setQuestionCount($this->testSequence->getUserQuestionCount());
398 $headerBlockBuilder->setHeaderMode($this->
object->getTitleOutput());
399 $headerBlockBuilder->setQuestionTitle($questionGui->object->getTitleForHTMLOutput());
400 $headerBlockBuilder->setQuestionPoints($questionGui->object->getPoints());
401 $headerBlockBuilder->setQuestionPosition($this->testSequence->getPositionOfSequence($sequence_element));
402 $headerBlockBuilder->setQuestionCount($this->testSequence->getUserQuestionCount());
403 $headerBlockBuilder->setQuestionPostponed($this->testSequence->isPostponedQuestion($questionId));
404 $headerBlockBuilder->setQuestionObligatory(
407 if ($this->test_session->isObjectiveOriented()) {
409 $objectivesAdapter->buildQuestionRelatedObjectiveList($this->testSequence, $this->question_related_objectives_list);
410 $this->question_related_objectives_list->loadObjectivesTitles();
412 $objectivesString = $this->question_related_objectives_list->getQuestionRelatedObjectiveTitles($questionId);
413 $headerBlockBuilder->setQuestionRelatedObjectives($objectivesString);
415 $questionGui->setQuestionHeaderBlockBuilder($headerBlockBuilder);
420 $navigationToolbarGUI->setFinishTestButtonEnabled(
true);
424 $this->
ctrl->setParameter($this,
'sequence', $sequence_element);
425 $this->
ctrl->setParameter($this,
'pmode', $presentationMode);
428 switch ($presentationMode) {
432 $navigationToolbarGUI->setDisabledStateEnabled(
false);
434 $this->
showQuestionEditable($questionGui, $formAction, $isQuestionWorkedThrough, $instant_response);
440 if ($this->testSequence->isQuestionOptional($questionGui->object->getId())) {
444 $this->
showQuestionViewable($questionGui, $formAction, $isQuestionWorkedThrough, $instant_response);
452 $navigationToolbarGUI->build();
459 if ($instant_response) {
484 if ($this->
object->isForceInstantFeedbackEnabled()) {
490 $questionId = $this->testSequence->getQuestionForSequence(
499 $nextSequenceElement = $this->testSequence->getFirstSequence();
502 $this->test_session->setLastSequence($nextSequenceElement ?? 0);
503 $this->test_session->saveToDb();
505 $this->
ctrl->setParameter($this,
'sequence', $nextSequenceElement);
506 $this->
ctrl->setParameter($this,
'pmode',
'');
515 $questionId = $this->testSequence->getQuestionForSequence(
521 if ($this->
object->isForceInstantFeedbackEnabled()) {
522 $this->
ctrl->setParameter($this,
'instresp', 1);
524 $this->testSequence->setQuestionChecked($questionId);
525 $this->testSequence->saveToDb();
531 $this->
ctrl->setParameter($this,
'pmode',
'');
550 $this->
ctrl->saveParameter($this,
'sequence');
561 $this->testSequence->getQuestionForSequence($currentSequenceElement)
566 $currentQuestionOBJ->resetUsersAnswer(
567 $this->test_session->getActiveId(),
568 $this->test_session->getPass()
571 $this->
ctrl->saveParameter($this,
'sequence');
581 $nextSequenceElement = $this->testSequence->getNextSequence($curSequenceElement);
584 $nextSequenceElement = $this->testSequence->getFirstSequence();
587 if ($this->
object->isPostponingEnabled()) {
588 $this->testSequence->postponeSequence($curSequenceElement);
589 $this->testSequence->saveToDb();
592 $this->
ctrl->setParameter($this,
'sequence', $nextSequenceElement);
593 $this->
ctrl->setParameter($this,
'pmode',
'');
600 $questionId = $this->testSequence->getQuestionForSequence($sequence_element);
602 $isQuestionWorkedThrough = $this->questioninfo->lookupResultRecordExist(
603 $this->test_session->getActiveId(),
605 $this->test_session->getPass()
608 if (!$isQuestionWorkedThrough) {
609 $this->testSequence->postponeQuestion($questionId);
610 $this->testSequence->saveToDb();
616 $testObj =
new ilObjTest($this->ref_id,
true);
618 $participants = $testObj->getActiveParticipantList();
619 $participant = $participants->getParticipantByActiveId($this->testrequest->getActiveId());
620 if (!$participant || !$participant->hasUnfinishedPasses()) {
621 $this->tpl->setOnScreenMessage(
'failure', $this->
lng->txt(
"tst_current_run_no_longer_valid"),
true);
630 $nextSequenceElement = $this->testSequence->getNextSequence($lastSequenceElement);
632 if ($this->
object->isPostponingEnabled()) {
637 $nextSequenceElement = $this->testSequence->getFirstSequence();
640 $this->
ctrl->setParameter($this,
'sequence', $nextSequenceElement);
641 $this->
ctrl->setParameter($this,
'pmode',
'');
650 $sequence_element = $this->testSequence->getPreviousSequence(
655 $sequence_element = $this->testSequence->getLastSequence();
658 $this->
ctrl->setParameter($this,
'sequence', $sequence_element);
659 $this->
ctrl->setParameter($this,
'pmode',
'');
666 return $sequence_element == $this->testSequence->getFirstSequence();
671 return $sequence_element == $this->testSequence->getLastSequence();
689 return $this->testSequence->getQuestionForSequence($this->testrequest->int(
'sequence'));
698 $this->save_result =
false;
700 $formtimestamp = $_POST[
"formtimestamp"] ??
'';
701 if (strlen($formtimestamp) == 0) {
702 $formtimestamp = $this->testrequest->raw(
"formtimestamp");
723 $q_id = $this->testSequence->getQuestionForSequence($this->testrequest->int(
'sequence'));
730 if (is_numeric($q_id) && (
int) $q_id) {
733 $active_id = (
int) $this->test_session->getActiveId();
735 $this->save_result = $questionOBJ->persistWorkingState(
738 $this->
object->areObligationsEnabled(),
742 if ($authorized && $this->test_session->isObjectiveOriented()) {
744 $objectivesAdapter->updateQuestionResult($this->test_session, $questionOBJ);
747 if ($authorized && $this->
object->isSkillServiceToBeConsidered()) {
754 $this->
ctrl->setParameter($this,
"save_error",
"1");
763 $questionId = $this->testSequence->getQuestionForSequence(
774 $this->testSequence->setQuestionChecked($questionId);
775 $this->testSequence->saveToDb();
776 } elseif ($this->
object->isForceInstantFeedbackEnabled()) {
777 $this->testSequence->setQuestionChecked($questionId);
778 $this->testSequence->saveToDb();
781 $this->
ctrl->setParameter($this,
'instresp', 1);
794 $questionId = $this->testSequence->getQuestionForSequence(
811 if ($this->test_session->getActiveId() > 0) {
812 if ($this->testSequence->hasRandomQuestionsForPass($this->test_session->getActiveId(), $this->test_session->getPass()) > 0) {
813 $this->logging_services->root()->write(
814 __METHOD__ .
' Random Questions allready exists for user ' .
815 $this->
user->getId() .
' in test ' . $this->
object->getTestId()
821 $this->logging_services->root()->write(__METHOD__ .
' ' . sprintf(
822 $this->
lng->txt(
"error_random_question_generation"),
823 $this->
user->getId(),
824 $this->
object->getTestId()
839 $this->logging_services->root(),
849 $sourcePoolDefinitionList->loadDefinitions();
851 $this->processLocker->executeRandomPassBuildOperation(
function () use ($questionSetConfig, $sourcePoolDefinitionList) {
858 $this->logging_services->root(),
861 $sourcePoolDefinitionList,
862 $stagingPoolQuestionList
865 $questionSetBuilder->performBuild($this->test_session);
867 }, $sourcePoolDefinitionList->hasTaxonomyFilters());
877 $active_id = $this->test_session->getActiveId();
878 $this->
ctrl->setParameter($this,
"active_id", $active_id);
880 $active_time_id = $this->
object->startWorkingTime($active_id, $this->test_session->getPass());
884 if ($this->
object->isRandomTest()) {
885 if (!$this->testSequence->hasRandomQuestionsForPass($active_id, $this->test_session->getPass())) {
891 $shuffle = $this->
object->getShuffleQuestions();
892 if ($this->
object->isRandomTest()) {
896 $this->
object->updateTestPassResults(
898 $this->test_session->getPass(),
899 $this->
object->areObligationsEnabled(),
901 $this->
object->getId()
905 if (!$this->testSequence->hasSequence()) {
906 $this->testSequence->createNewSequence($this->
object->getQuestionCount(), $shuffle);
907 $this->testSequence->saveToDb();
910 if ($this->
object->getListOfQuestionsStart()) {
914 $this->
ctrl->setParameter($this,
'sequence', $this->test_session->getLastSequence());
915 $this->
ctrl->setParameter($this,
'pmode',
'');
921 return $this->testSequence->isPostponedQuestion($questionId);
932 $userSolutionAdopter->setUserId($this->
user->getId());
933 $userSolutionAdopter->setActiveId($this->test_session->getActiveId());
934 $userSolutionAdopter->setTargetPass($this->testSequence->getPass());
935 $userSolutionAdopter->setQuestionIds($this->testSequence->getOptionalQuestions());
937 $userSolutionAdopter->perform();
944 if ($this->testSequence->isAnsweringOptionalQuestionsConfirmed()) {
948 $questionId = $this->testSequence->getQuestionForSequence($sequenceKey);
950 if (!$this->testSequence->isQuestionOptional($questionId)) {
964 $this->tpl->setOnScreenMessage(
'failure', sprintf($this->
lng->txt(
'tst_objective_oriented_test_pass_without_questions'), $this->
object->getTitle()),
true);
965 $this->
ctrl->redirectByClass(ilObjTestGUI::class);
970 $isNextPrimary =
true;
972 if ($this->
object->isForceInstantFeedbackEnabled()) {
973 $isNextPrimary =
false;
976 $questionsMissingResult = $this->questioninfo->getQuestionsMissingResultRecord(
977 $this->test_session->getActiveId(),
978 $this->test_session->getPass(),
979 $this->testSequence->getOrderedSequenceQuestions()
982 if ($questionsMissingResult === []) {
987 if (count($questionsMissingResult) === 1
988 && $currentQuestionId === current($questionsMissingResult)) {
993 return $isNextPrimary;
998 $titleContent = $this->ui_factory->listing()->property();
1000 if ($this->
object->getShowKioskModeParticipant()) {
1001 $testParticipantNameLabel = $this->
lng->txt(
"conf_user_name");
1005 $testParticipantNameValue =
"<span class='il-test-kiosk-head__participant-name'>" . $this->
user->getFullname() .
"</span>";
1006 $titleContent = $titleContent->withProperty($testParticipantNameLabel, $testParticipantNameValue,
false);
1009 if ($this->
object->isShowExamIdInTestPassEnabled()) {
1010 $testExamIdLabel = $this->
lng->txt(
"exam_id_label");
1012 $this->test_session->getActiveId(),
1013 $this->test_session->getPass(),
1014 $this->
object->getId()
1016 $titleContent = $titleContent->withProperty($testExamIdLabel, $testExamIdValue);
1019 if ($this->
object->getShowKioskModeTitle()) {
1020 $testNameLabel = $this->
lng->txt(
"test");
1021 $testNameValue = $this->
object->getTitle();
1022 $titleContent = $titleContent->withProperty($testNameLabel, $testNameValue,
false);
1025 return $this->ui_renderer->render($titleContent);
isShowingPostponeStatusReguired($questionId)
getQuestionInstance(int $question_id, bool $from_cache=true)
static get(string $a_var)
isQuestionSummaryFinishTestButtonRequired()
ilComponentRepository $component_repository
getQuestionGuiInstance($question_id, $fromCache=true)
removeIntermediateSolution()
populateQuestionOptionalMessage()
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test.
setAnswerChangedParameter($changed=true)
Set the 'answer changed' url parameter for generated links.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
showQuestionEditable(assQuestionGUI $questionGui, $formAction, $isQuestionWorkedThrough, $instantResponse)
populateTestNavigationToolbar(ilTestNavigationToolbarGUI $toolbar_gui)
getObjectiveOrientedContainer()
Output class for assessment test execution.
updateWorkingTime()
updates working time and stores state saveresult to see if question has to be stored or not ...
handleTearsAndAngerNoObjectiveOrientedQuestion()
static getInstance(ilDBInterface $db, ilLanguage $lng, ilLogger $log, ilObjTest $testOBJ, ilTestRandomQuestionSetConfig $questionSetConfig, ilTestRandomQuestionSetSourcePoolDefinitionList $sourcePoolDefinitionList, ilTestRandomQuestionSetStagingPoolQuestionList $stagingPoolQuestionList)
submitSolutionAndNextCmd()
getNextCommandParameter()
executeCommand()
Execute Command.
handleQuestionActionCmd()
getSession(?int $active_id=null)
Creates and returns an instance of a test sequence that corresponds to the current test mode...
resumePlayerCmd()
Resume a test at the last position.
handleUserSettings()
Handles some form parameters on starting and resuming a test.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
ilTestQuestionRelatedObjectivesList $question_related_objectives_list
Base Exception for all Exceptions relating to Modules/Test.
isLastQuestionInSequence($sequence_element)
unregisterForcedFeedbackNavUrl()
populateInstantResponseBlocks(assQuestionGUI $questionGui, $authorizedSolution)
static isQuestionObligatory($question_id)
checks wether the question with given id is marked as obligatory or not
isValidSequenceElement($sequence_element)
isNrOfTriesReached()
nr of tries exceeded
checkTestSessionUser(ilTestSession $test_session)
populateQuestionNavigation($sequence_element, $primary_next)
static getInstance(ilTestSession $a_test_session)
isForcedFeedbackNavUrlRegistered()
static _enabledAssessmentLogging()
getInstantResponseParameter()
isOptionalQuestionAnsweringConfirmationRequired($sequenceKey)
Class ilTestSubmissionReviewGUI.
getRegisteredForcedFeedbackNavUrl()
getCommand($cmd)
Retrieves the ilCtrl command.
handleSkillTriggering(ilTestSession $test_session)
const PRESENTATION_MODE_EDIT
saveNavigationPreventConfirmation()
Save the save the switch to prevent the navigation confirmation.
ensureExistingTestSession(ilTestSession $test_session)
ilTestSessionFactory $testSessionFactory
const TEST_PLAYER_KIOSK_MODE_ENABLED
handlePrimaryButton(ilTestNavigationToolbarGUI $navigationToolbarGUI, int $currentQuestionId)
getAnswerChangedParameter()
Get the 'answer changed' status from the current request It may be set by ilTestPlayerNavigationContr...
getSequenceElementParameter()
Basic GUI class for assessment questions.
const PRESENTATION_MODE_VIEW
const SUBMIT_INTERMEDIATE_SOLUTION
ILIAS TestQuestionPool QuestionInfoService $questioninfo
initProcessLocker($activeId)
updateLearningProgressOnTestStart()
static redirect(string $a_script)
const TEST_PLAYER_VIEW_TITLE
handlePasswordProtectionRedirect()
registerForcedFeedbackNavUrl($forcedFeedbackNavUrl)
saveQuestionSolution($authorized=true, $force=false)
saves the user input of a question
showQuestionViewable(assQuestionGUI $questionGui, $formAction, $isQuestionWorkedThrough, $instantResponse)
performTearsAndAngerBrokenConfessionChecks()
static initjQuery(ilGlobalTemplateInterface $a_tpl=null)
inits and adds the jQuery JS-File to the global or a passed template
generateRandomTestPassForActiveUser()
isFirstQuestionInSequence($sequence_element)
populateInstantResponseModal(assQuestionGUI $questionGui, $navUrl)
const TEST_PLAYER_SHORT_TITLE
getNextSequenceParameter()
getNavigationUrlParameter()
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
static buildExamId($active_id, $pass, $test_obj_id=null)
handleCheckTestPassValid()
handleTearsAndAngerQuestionIsNull(int $question_id, $sequence_element)
isMaxProcessingTimeReached()
getCurrentSequenceElement()
getTestNavigationToolbarGUI()
static set(string $a_var, $a_val)
Set a value.
static initConnectionWithAnimation()
Init YUI connection and animation module used in Modules/Test (Jan 2022)
canSaveResult()
Returns TRUE if the answers of the current user could be saved.
adoptUserSolutionsFromPreviousPass()
static isTestExecutionCommand($cmd)
static _updateStatus(int $a_obj_id, int $a_usr_id, ?object $a_obj=null, bool $a_percentage=false, bool $a_force_raise=false)
isParticipantsAnswerFixed($questionId)
Output class for assessment test execution.
prepareTestPage($sequenceElement, $questionId)
handleQuestionPostponing($sequence_element)