ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
class.ilTestOutputGUI.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4require_once './Modules/Test/classes/class.ilTestPlayerAbstractGUI.php';
5
21{
26
30 public function executeCommand()
31 {
32 global $DIC;
33 $ilDB = $DIC['ilDB'];
34 $ilPluginAdmin = $DIC['ilPluginAdmin'];
35 $lng = $DIC['lng'];
36 $ilTabs = $DIC['ilTabs'];
37
38 $this->checkReadAccess();
39
40 $ilTabs->clearTargets();
41
42 $cmd = $this->ctrl->getCmd();
43 $next_class = $this->ctrl->getNextClass($this);
44
45 $this->ctrl->saveParameter($this, "sequence");
46 $this->ctrl->saveParameter($this, "pmode");
47 $this->ctrl->saveParameter($this, "active_id");
48
50
51 $testSessionFactory = new ilTestSessionFactory($this->object);
52 $this->testSession = $testSessionFactory->getSession($_GET['active_id']);
53
54 $this->ensureExistingTestSession($this->testSession);
55 $this->checkTestSessionUser($this->testSession);
56
57 $this->initProcessLocker($this->testSession->getActiveId());
58
59 $testSequenceFactory = new ilTestSequenceFactory($ilDB, $lng, $ilPluginAdmin, $this->object);
60 $this->testSequence = $testSequenceFactory->getSequenceByTestSession($this->testSession);
61 $this->testSequence->loadFromDb();
62 $this->testSequence->loadQuestions();
63
64 require_once 'Modules/Test/classes/class.ilTestQuestionRelatedObjectivesList.php';
65 $this->questionRelatedObjectivesList = new ilTestQuestionRelatedObjectivesList();
66
67 include_once 'Services/jQuery/classes/class.iljQueryUtil.php';
69 include_once "./Services/YUI/classes/class.ilYuiUtil.php";
71
73
74 $cmd = $this->getCommand($cmd);
75
76 switch ($next_class) {
77 case 'ilassquestionpagegui':
78
79 $this->checkTestExecutable();
80
81 $questionId = $this->testSequence->getQuestionForSequence($this->getCurrentSequenceElement());
82
83 require_once "./Modules/TestQuestionPool/classes/class.ilAssQuestionPageGUI.php";
84 $page_gui = new ilAssQuestionPageGUI($questionId);
85 $ret = $this->ctrl->forwardCommand($page_gui);
86 break;
87
88 case 'iltestsubmissionreviewgui':
89
90 $this->checkTestExecutable();
91
92 require_once './Modules/Test/classes/class.ilTestSubmissionReviewGUI.php';
93 $gui = new ilTestSubmissionReviewGUI($this, $this->object, $this->testSession);
94 $gui->setObjectiveOrientedContainer($this->getObjectiveOrientedContainer());
95 $ret = $this->ctrl->forwardCommand($gui);
96 break;
97
98 case 'ilassquestionhintrequestgui':
99
100 $this->checkTestExecutable();
101
102 $questionGUI = $this->object->createQuestionGUI(
103 "",
104 $this->testSequence->getQuestionForSequence($this->getCurrentSequenceElement())
105 );
106
107 require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionHintTracking.php';
108 $questionHintTracking = new ilAssQuestionHintTracking(
109 $questionGUI->object->getId(),
110 $this->testSession->getActiveId(),
111 $this->testSession->getPass()
112 );
113
114 require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionHintRequestGUI.php';
115 $gui = new ilAssQuestionHintRequestGUI($this, ilTestPlayerCommands::SHOW_QUESTION, $questionGUI, $questionHintTracking);
116
117// fau: testNav - save the 'answer changed' status for viewing hint requests
119// fau.
120 $ret = $this->ctrl->forwardCommand($gui);
121
122 break;
123
124 case 'iltestsignaturegui':
125
126 $this->checkTestExecutable();
127
128 require_once './Modules/Test/classes/class.ilTestSignatureGUI.php';
129 $gui = new ilTestSignatureGUI($this);
130 $ret = $this->ctrl->forwardCommand($gui);
131 break;
132
133 case 'iltestpasswordprotectiongui':
134
135 $this->checkTestExecutable();
136
137 require_once 'Modules/Test/classes/class.ilTestPasswordProtectionGUI.php';
138 $gui = new ilTestPasswordProtectionGUI($this->ctrl, $this->tpl, $this->lng, $this, $this->passwordChecker);
139 $ret = $this->ctrl->forwardCommand($gui);
140 break;
141
142 default:
143
145 $this->checkTestExecutable();
146 }
147
148 $cmd .= 'Cmd';
149 $ret = &$this->$cmd();
150 break;
151 }
152 return $ret;
153 }
154
155 protected function startTestCmd()
156 {
157 global $DIC;
158 $ilUser = $DIC['ilUser'];
159
160 $_SESSION['tst_pass_finish'] = 0;
161
162 // ensure existing test session
163 $this->testSession->setUserId($ilUser->getId());
164 $this->testSession->setAnonymousId($_SESSION["tst_access_code"][$this->object->getTestId()]);
165 $this->testSession->setObjectiveOrientedContainerId($this->getObjectiveOrientedContainer()->getObjId());
166 $this->testSession->saveToDb();
167
168 $active_id = $this->testSession->getActiveId();
169 $this->ctrl->setParameter($this, "active_id", $active_id);
170
171 $shuffle = $this->object->getShuffleQuestions();
172 if ($this->object->isRandomTest()) {
174
175 $this->object->loadQuestions();
176 $shuffle = false; // shuffle is already done during the creation of the random questions
177 }
178
179 assQuestion::_updateTestPassResults(
180 $active_id,
181 $this->testSession->getPass(),
182 $this->object->areObligationsEnabled(),
183 null,
184 $this->object->id
185 );
186
187 // ensure existing test sequence
188 if (!$this->testSequence->hasSequence()) {
189 $this->testSequence->createNewSequence($this->object->getQuestionCount(), $shuffle);
190 $this->testSequence->saveToDb();
191 }
192
193 $this->testSequence->loadFromDb();
194 $this->testSequence->loadQuestions();
195
196 if ($this->testSession->isObjectiveOriented()) {
197 require_once 'Modules/Course/classes/Objectives/class.ilLOTestQuestionAdapter.php';
198 $objectivesAdapter = ilLOTestQuestionAdapter::getInstance($this->testSession);
199
200 $objectivesAdapter->notifyTestStart($this->testSession, $this->object->getId());
201 $objectivesAdapter->prepareTestPass($this->testSession, $this->testSequence);
202
203 $objectivesAdapter->buildQuestionRelatedObjectiveList(
204 $this->testSequence,
205 $this->questionRelatedObjectivesList
206 );
207
208 if ($this->testSequence->hasOptionalQuestions()) {
210
211 $this->testSequence->reorderOptionalQuestionsToSequenceEnd();
212 $this->testSequence->saveToDb();
213 }
214 }
215
216 $active_time_id = $this->object->startWorkingTime(
217 $this->testSession->getActiveId(),
218 $this->testSession->getPass()
219 );
220 $_SESSION["active_time_id"] = $active_time_id;
221
223
224 $sequenceElement = $this->testSequence->getFirstSequence();
225
226 $this->ctrl->setParameter($this, 'sequence', $sequenceElement);
227 $this->ctrl->setParameter($this, 'pmode', '');
228
229 if ($this->object->getListOfQuestionsStart()) {
230 $this->ctrl->redirect($this, ilTestPlayerCommands::QUESTION_SUMMARY);
231 }
232
233 $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
234 }
235
237 {
238 global $DIC;
239 $ilUser = $DIC['ilUser'];
240
241 require_once('./Modules/Test/classes/class.ilObjTestAccess.php');
242 require_once('./Services/Tracking/classes/class.ilLPStatusWrapper.php');
243 ilLPStatusWrapper::_updateStatus($this->object->getId(), $ilUser->getId());
244 }
245
246 private function isValidSequenceElement($sequenceElement)
247 {
248 if ($sequenceElement === false) {
249 return false;
250 }
251
252 if ($sequenceElement < 1) {
253 return false;
254 }
255
256 if (!$this->testSequence->getPositionOfSequence($sequenceElement)) {
257 return false;
258 }
259
260 return true;
261 }
262
263 protected function showQuestionCmd()
264 {
265 $_SESSION['tst_pass_finish'] = 0;
266
267 $_SESSION["active_time_id"] = $this->object->startWorkingTime(
268 $this->testSession->getActiveId(),
269 $this->testSession->getPass()
270 );
271
272 $sequenceElement = $this->getCurrentSequenceElement();
273
274 if (!$this->isValidSequenceElement($sequenceElement)) {
275 $sequenceElement = $this->testSequence->getFirstSequence();
276 }
277
278 $this->testSession->setLastSequence($sequenceElement);
279 $this->testSession->saveToDb();
280
281
282 $questionId = $this->testSequence->getQuestionForSequence($sequenceElement);
283
284 if (!(int) $questionId && $this->testSession->isObjectiveOriented()) {
286 }
287
288 if (!$this->testSequence->isQuestionPresented($questionId)) {
289 $this->testSequence->setQuestionPresented($questionId);
290 $this->testSequence->saveToDb();
291 }
292
293 $isQuestionWorkedThrough = assQuestion::_isWorkedThrough(
294 $this->testSession->getActiveId(),
295 $questionId,
296 $this->testSession->getPass()
297 );
298
299 // fau: testNav - always use edit mode, except for fixed answer
300 if ($this->isParticipantsAnswerFixed($questionId)) {
302 $instantResponse = true;
303 } else {
305 $instantResponse = $this->getInstantResponseParameter();
306 }
307 // fau.
308
309 $questionGui = $this->getQuestionGuiInstance($questionId);
310
311 if (!($questionGui instanceof assQuestionGUI)) {
312 $this->handleTearsAndAngerQuestionIsNull($questionId, $sequenceElement);
313 }
314
315 $questionGui->setSequenceNumber($this->testSequence->getPositionOfSequence($sequenceElement));
316 $questionGui->setQuestionCount($this->testSequence->getUserQuestionCount());
317
318 require_once 'Modules/Test/classes/class.ilTestQuestionHeaderBlockBuilder.php';
319 $headerBlockBuilder = new ilTestQuestionHeaderBlockBuilder($this->lng);
320 $headerBlockBuilder->setHeaderMode($this->object->getTitleOutput());
321 $headerBlockBuilder->setQuestionTitle($questionGui->object->getTitle());
322 $headerBlockBuilder->setQuestionPoints($questionGui->object->getPoints());
323 $headerBlockBuilder->setQuestionPosition($this->testSequence->getPositionOfSequence($sequenceElement));
324 $headerBlockBuilder->setQuestionCount($this->testSequence->getUserQuestionCount());
325 $headerBlockBuilder->setQuestionPostponed($this->testSequence->isPostponedQuestion($questionId));
326 $headerBlockBuilder->setQuestionObligatory(
327 $this->object->areObligationsEnabled() && ilObjTest::isQuestionObligatory($questionGui->object->getId())
328 );
329 if ($this->testSession->isObjectiveOriented()) {
330 require_once 'Modules/Course/classes/Objectives/class.ilLOTestQuestionAdapter.php';
331 $objectivesAdapter = ilLOTestQuestionAdapter::getInstance($this->testSession);
332 $objectivesAdapter->buildQuestionRelatedObjectiveList($this->testSequence, $this->questionRelatedObjectivesList);
333 $this->questionRelatedObjectivesList->loadObjectivesTitles();
334
335 $objectivesString = $this->questionRelatedObjectivesList->getQuestionRelatedObjectiveTitles($questionId);
336 $headerBlockBuilder->setQuestionRelatedObjectives($objectivesString);
337 }
338 $questionGui->setQuestionHeaderBlockBuilder($headerBlockBuilder);
339
340 $this->prepareTestPage($presentationMode, $sequenceElement, $questionId);
341
342 $navigationToolbarGUI = $this->getTestNavigationToolbarGUI();
343 $navigationToolbarGUI->setFinishTestButtonEnabled(true);
344
345 $isNextPrimary = $this->handlePrimaryButton($navigationToolbarGUI, $questionId);
346
347 $this->ctrl->setParameter($this, 'sequence', $sequenceElement);
348 $this->ctrl->setParameter($this, 'pmode', $presentationMode);
349 $formAction = $this->ctrl->getFormAction($this, ilTestPlayerCommands::SUBMIT_INTERMEDIATE_SOLUTION);
350
351 switch ($presentationMode) {
353
354// fau: testNav - enable navigation toolbar in edit mode
355 $navigationToolbarGUI->setDisabledStateEnabled(false);
356// fau.
357 $this->showQuestionEditable($questionGui, $formAction, $isQuestionWorkedThrough, $instantResponse);
358
359 break;
360
362
363 if ($this->testSequence->isQuestionOptional($questionGui->object->getId())) {
365 }
366
367 $this->showQuestionViewable($questionGui, $formAction, $isQuestionWorkedThrough, $instantResponse);
368
369 break;
370
371 default:
372
373 require_once 'Modules/Test/exceptions/class.ilTestException.php';
374 throw new ilTestException('no presentation mode given');
375 }
376
377 $navigationToolbarGUI->build();
378 $this->populateTestNavigationToolbar($navigationToolbarGUI);
379
380 // fau: testNav - enable the question navigation in edit mode
381 $this->populateQuestionNavigation($sequenceElement, false, $isNextPrimary);
382 // fau.
383
384 if ($instantResponse) {
385 // fau: testNav - always use authorized solution for instant feedback
387 $questionGui,
388 true
389 );
390 // fau.
391 }
392
393 // fau: testNav - add feedback modal
397 }
398 // fau.
399 }
400
401 protected function editSolutionCmd()
402 {
403 $this->ctrl->setParameter($this, 'pmode', ilTestPlayerAbstractGUI::PRESENTATION_MODE_EDIT);
404 $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
405 }
406
407 protected function submitSolutionAndNextCmd()
408 {
409 if ($this->object->isForceInstantFeedbackEnabled()) {
410 return $this->submitSolutionCmd();
411 }
412
413 if ($this->saveQuestionSolution(true, false)) {
414 $questionId = $this->testSequence->getQuestionForSequence(
416 );
417
419
420 $nextSequenceElement = $this->testSequence->getNextSequence($this->getCurrentSequenceElement());
421
422 if (!$this->isValidSequenceElement($nextSequenceElement)) {
423 $nextSequenceElement = $this->testSequence->getFirstSequence();
424 }
425
426 $this->testSession->setLastSequence($nextSequenceElement);
427 $this->testSession->saveToDb();
428
429 $this->ctrl->setParameter($this, 'sequence', $nextSequenceElement);
430 $this->ctrl->setParameter($this, 'pmode', '');
431 }
432
433 $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
434 }
435
436 protected function submitSolutionCmd()
437 {
438 if ($this->saveQuestionSolution(true, false)) {
439 $questionId = $this->testSequence->getQuestionForSequence(
441 );
442
444
445 if ($this->object->isForceInstantFeedbackEnabled()) {
446 $this->ctrl->setParameter($this, 'instresp', 1);
447
448 $this->testSequence->setQuestionChecked($questionId);
449 $this->testSequence->saveToDb();
450 }
451
452 if ($this->getNextCommandParameter()) {
453 if ($this->getNextSequenceParameter()) {
454 $this->ctrl->setParameter($this, 'sequence', $this->getNextSequenceParameter());
455 $this->ctrl->setParameter($this, 'pmode', '');
456 }
457
458 $this->ctrl->redirect($this, $this->getNextCommandParameter());
459 }
460
461 $this->ctrl->setParameter($this, 'pmode', ilTestPlayerAbstractGUI::PRESENTATION_MODE_VIEW);
462 } else {
463 $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
464 }
465
466 // fau: testNav - remember to prevent the navigation confirmation
468 // fau.
469
470 // fau: testNav - handle navigation after saving
471 if ($this->getNavigationUrlParameter()) {
473 } else {
474 $this->ctrl->saveParameter($this, 'sequence');
475 }
476 // fau.
477 $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
478 }
479
480 protected function discardSolutionCmd()
481 {
482 $currentSequenceElement = $this->getCurrentSequenceElement();
483
484 $currentQuestionOBJ = $this->getQuestionInstance(
485 $this->testSequence->getQuestionForSequence($currentSequenceElement)
486 );
487
488 $currentQuestionOBJ->resetUsersAnswer(
489 $this->testSession->getActiveId(),
490 $this->testSession->getPass()
491 );
492
493 $this->ctrl->saveParameter($this, 'sequence');
494
495 $this->ctrl->setParameter($this, 'pmode', ilTestPlayerAbstractGUI::PRESENTATION_MODE_VIEW);
496
497 $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
498 }
499
500 protected function skipQuestionCmd()
501 {
502 $curSequenceElement = $this->getCurrentSequenceElement();
503 $nextSequenceElement = $this->testSequence->getNextSequence($curSequenceElement);
504
505 if (!$this->isValidSequenceElement($nextSequenceElement)) {
506 $nextSequenceElement = $this->testSequence->getFirstSequence();
507 }
508
509 if ($this->object->isPostponingEnabled()) {
510 $this->testSequence->postponeSequence($curSequenceElement);
511 $this->testSequence->saveToDb();
512 }
513
514 $this->ctrl->setParameter($this, 'sequence', $nextSequenceElement);
515 $this->ctrl->setParameter($this, 'pmode', '');
516
517 $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
518 }
519
520 protected function handleQuestionPostponing($sequenceElement)
521 {
522 $questionId = $this->testSequence->getQuestionForSequence($sequenceElement);
523
524 $isQuestionWorkedThrough = assQuestion::_isWorkedThrough(
525 $this->testSession->getActiveId(),
526 $questionId,
527 $this->testSession->getPass()
528 );
529
530 if (!$isQuestionWorkedThrough) {
531 $this->testSequence->postponeQuestion($questionId);
532 $this->testSequence->saveToDb();
533 }
534 }
535
536 protected function nextQuestionCmd()
537 {
538 $lastSequenceElement = $this->getCurrentSequenceElement();
539 $nextSequenceElement = $this->testSequence->getNextSequence($lastSequenceElement);
540
541 if ($this->object->isPostponingEnabled()) {
542 $this->handleQuestionPostponing($lastSequenceElement);
543 }
544
545 if (!$this->isValidSequenceElement($nextSequenceElement)) {
546 $nextSequenceElement = $this->testSequence->getFirstSequence();
547 }
548
549 $this->ctrl->setParameter($this, 'sequence', $nextSequenceElement);
550 $this->ctrl->setParameter($this, 'pmode', '');
551
552 $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
553 }
554
555 protected function previousQuestionCmd()
556 {
557 $sequenceElement = $this->testSequence->getPreviousSequence(
559 );
560
561 if (!$this->isValidSequenceElement($sequenceElement)) {
562 $sequenceElement = $this->testSequence->getLastSequence();
563 }
564
565 $this->ctrl->setParameter($this, 'sequence', $sequenceElement);
566 $this->ctrl->setParameter($this, 'pmode', '');
567
568 $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
569 }
570
571 protected function isFirstQuestionInSequence($sequenceElement)
572 {
573 return $sequenceElement == $this->testSequence->getFirstSequence();
574 }
575
576 protected function isLastQuestionInSequence($sequenceElement)
577 {
578 return $sequenceElement == $this->testSequence->getLastSequence();
579 }
580
586 protected function canSaveResult()
587 {
588 return !$this->object->endingTimeReached() && !$this->isMaxProcessingTimeReached() && !$this->isNrOfTriesReached();
589 }
590
594 protected function getCurrentQuestionId()
595 {
596 return $this->testSequence->getQuestionForSequence($_GET["sequence"]);
597 }
598
602 public function saveQuestionSolution($authorized = true, $force = false)
603 {
604 $this->updateWorkingTime();
605 $this->saveResult = false;
606 if (!$force) {
607 $formtimestamp = $_POST["formtimestamp"];
608 if (strlen($formtimestamp) == 0) {
609 $formtimestamp = $_GET["formtimestamp"];
610 }
611 if ($formtimestamp != $_SESSION["formtimestamp"]) {
612 $_SESSION["formtimestamp"] = $formtimestamp;
613 } else {
614 return false;
615 }
616 }
617 // save question solution
618 if ($this->canSaveResult() || $force) {
619 // but only if the ending time is not reached
620 $q_id = $this->testSequence->getQuestionForSequence($_GET["sequence"]);
621
622 if ($this->isParticipantsAnswerFixed($q_id)) {
623 // should only be reached by firebugging the disabled form in ui
624 throw new ilTestException('not allowed request');
625 }
626
627 if (is_numeric($q_id) && (int) $q_id) {
628 $questionOBJ = $this->getQuestionInstance($q_id);
629 $pass = null;
630 $active_id = $this->testSession->getActiveId();
631 if ($this->object->isRandomTest()) {
632 $pass = ilObjTest::_getPass($active_id);
633 }
634 $this->saveResult = $questionOBJ->persistWorkingState(
635 $active_id,
636 $pass,
637 $this->object->areObligationsEnabled(),
638 $authorized
639 );
640
641 if ($authorized && $this->testSession->isObjectiveOriented()) {
642 require_once 'Modules/Course/classes/Objectives/class.ilLOTestQuestionAdapter.php';
643 $objectivesAdapter = ilLOTestQuestionAdapter::getInstance($this->testSession);
644 $objectivesAdapter->updateQuestionResult($this->testSession, $questionOBJ);
645 }
646
647 if ($authorized && $this->object->isSkillServiceToBeConsidered()) {
648 $this->handleSkillTriggering($this->testSession);
649 }
650 }
651 }
652
653 if ($this->saveResult == false || (!$questionOBJ->validateSolutionSubmit() && $questionOBJ->savePartial()) ) {
654 $this->ctrl->setParameter($this, "save_error", "1");
655 $_SESSION["previouspost"] = $_POST;
656 }
657
658 return $this->saveResult;
659 }
660
661 protected function showInstantResponseCmd()
662 {
663 $questionId = $this->testSequence->getQuestionForSequence(
665 );
666
667 if ($this->getAnswerChangedParameter() && !$this->isParticipantsAnswerFixed($questionId)) {
668 if ($this->saveQuestionSolution(true)) {
670 $this->setAnswerChangedParameter(false);
671 } else {
672 $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
673 }
674 $this->testSequence->setQuestionChecked($questionId);
675 $this->testSequence->saveToDb();
676 }
677
678 $this->ctrl->setParameter($this, 'instresp', 1);
679
680 // fau: testNav - handle navigation after feedback
681 if ($this->getNavigationUrlParameter()) {
684 }
685 // fau.
686 $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
687 }
688
689 protected function handleQuestionActionCmd()
690 {
691 $questionId = $this->testSequence->getQuestionForSequence(
693 );
694
695 if (!$this->isParticipantsAnswerFixed($questionId)) {
696 $this->updateWorkingTime();
697 $this->saveQuestionSolution(false);
698 // fau: testNav - add changed status of the question
699 $this->setAnswerChangedParameter(true);
700 // fau.
701 }
702
703 $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
704 }
705
707 {
708 if ($this->testSession->getActiveId() > 0) {
709 if ($this->testSequence->hasRandomQuestionsForPass($this->testSession->getActiveId(), $this->testSession->getPass()) > 0) {
710 // Something went wrong. Maybe the user pressed the start button twice
711 // Questions already exist so there is no need to create new questions
712
713 global $DIC;
714 $ilLog = $DIC['ilLog'];
715 $ilUser = $DIC['ilUser'];
716
717 $ilLog->write(
718 __METHOD__ . ' Random Questions allready exists for user ' .
719 $ilUser->getId() . ' in test ' . $this->object->getTestId()
720 );
721
722 return true;
723 }
724 } else {
725 // This may not happen! If it happens, raise a fatal error...
726
727 global $DIC;
728 $ilLog = $DIC['ilLog'];
729 $ilUser = $DIC['ilUser'];
730
731 $ilLog->write(__METHOD__ . ' ' . sprintf(
732 $this->lng->txt("error_random_question_generation"),
733 $ilUser->getId(),
734 $this->object->getTestId()
735 ));
736
737 return true;
738 };
739
740 return false;
741 }
742
744 {
745 global $DIC;
746 $tree = $DIC['tree'];
747 $ilDB = $DIC['ilDB'];
748 $ilPluginAdmin = $DIC['ilPluginAdmin'];
749
750 require_once 'Modules/Test/classes/class.ilTestRandomQuestionSetConfig.php';
751 $questionSetConfig = new ilTestRandomQuestionSetConfig($tree, $ilDB, $ilPluginAdmin, $this->object);
752 $questionSetConfig->loadFromDb();
753
754 require_once 'Modules/Test/classes/class.ilTestRandomQuestionSetSourcePoolDefinitionFactory.php';
755 $sourcePoolDefinitionFactory = new ilTestRandomQuestionSetSourcePoolDefinitionFactory($ilDB, $this->object);
756
757 require_once 'Modules/Test/classes/class.ilTestRandomQuestionSetSourcePoolDefinitionList.php';
758 $sourcePoolDefinitionList = new ilTestRandomQuestionSetSourcePoolDefinitionList($ilDB, $this->object, $sourcePoolDefinitionFactory);
759 $sourcePoolDefinitionList->loadDefinitions();
760
761 $this->processLocker->executeRandomPassBuildOperation(function () use ($ilDB, $ilPluginAdmin, $questionSetConfig, $sourcePoolDefinitionList) {
763 require_once 'Modules/Test/classes/class.ilTestRandomQuestionSetStagingPoolQuestionList.php';
764 $stagingPoolQuestionList = new ilTestRandomQuestionSetStagingPoolQuestionList($ilDB, $ilPluginAdmin);
765
766 require_once 'Modules/Test/classes/class.ilTestRandomQuestionSetBuilder.php';
767 $questionSetBuilder = ilTestRandomQuestionSetBuilder::getInstance($ilDB, $this->object, $questionSetConfig, $sourcePoolDefinitionList, $stagingPoolQuestionList);
768
769 $questionSetBuilder->performBuild($this->testSession);
770 }
771 }, $sourcePoolDefinitionList->hasTaxonomyFilters());
772 }
773
777 protected function resumePlayerCmd()
778 {
779 $this->handleUserSettings();
780
781 $active_id = $this->testSession->getActiveId();
782 $this->ctrl->setParameter($this, "active_id", $active_id);
783
784 $active_time_id = $this->object->startWorkingTime($active_id, $this->testSession->getPass());
785 $_SESSION["active_time_id"] = $active_time_id;
786 $_SESSION['tst_pass_finish'] = 0;
787
788 if ($this->object->isRandomTest()) {
789 if (!$this->testSequence->hasRandomQuestionsForPass($active_id, $this->testSession->getPass())) {
790 // create a new set of random questions
792 }
793 }
794
795 $shuffle = $this->object->getShuffleQuestions();
796 if ($this->object->isRandomTest()) {
797 $shuffle = false;
798 }
799
800 assQuestion::_updateTestPassResults(
801 $active_id,
802 $this->testSession->getPass(),
803 $this->object->areObligationsEnabled(),
804 null,
805 $this->object->id
806 );
807
808 // ensure existing test sequence
809 if (!$this->testSequence->hasSequence()) {
810 $this->testSequence->createNewSequence($this->object->getQuestionCount(), $shuffle);
811 $this->testSequence->saveToDb();
812 }
813
814 if ($this->object->getListOfQuestionsStart()) {
815 $this->ctrl->redirect($this, ilTestPlayerCommands::QUESTION_SUMMARY);
816 }
817
818 $this->ctrl->setParameter($this, 'sequence', $this->testSession->getLastSequence());
819 $this->ctrl->setParameter($this, 'pmode', '');
820 $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
821 }
822
823 protected function isShowingPostponeStatusReguired($questionId)
824 {
825 return $this->testSequence->isPostponedQuestion($questionId);
826 }
827
829 {
830 global $DIC;
831 $ilDB = $DIC['ilDB'];
832 $ilUser = $DIC['ilUser'];
833
834 $assSettings = new ilSetting('assessment');
835
836 include_once("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
837 $isAssessmentLogEnabled = ilObjAssessmentFolder::_enabledAssessmentLogging();
838
839 require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionUserSolutionAdopter.php';
840 $userSolutionAdopter = new ilAssQuestionUserSolutionAdopter($ilDB, $assSettings, $isAssessmentLogEnabled);
841
842 $userSolutionAdopter->setUserId($ilUser->getId());
843 $userSolutionAdopter->setActiveId($this->testSession->getActiveId());
844 $userSolutionAdopter->setTargetPass($this->testSequence->getPass());
845 $userSolutionAdopter->setQuestionIds($this->testSequence->getOptionalQuestions());
846
847 $userSolutionAdopter->perform();
848 }
849
850 abstract protected function populateQuestionOptionalMessage();
851
852 protected function isOptionalQuestionAnsweringConfirmationRequired($sequenceKey)
853 {
854 if ($this->testSequence->isAnsweringOptionalQuestionsConfirmed()) {
855 return false;
856 }
857
858 $questionId = $this->testSequence->getQuestionForSequence($sequenceKey);
859
860 if (!$this->testSequence->isQuestionOptional($questionId)) {
861 return false;
862 }
863
864 return true;
865 }
866
868 {
869 return true;
870 }
871
873 {
874 ilUtil::sendFailure(sprintf($this->lng->txt('tst_objective_oriented_test_pass_without_questions'), $this->object->getTitle()), true);
875
876 $this->backToInfoScreenCmd();
877 }
878
882 protected function handlePrimaryButton(ilTestNavigationToolbarGUI $navigationToolbarGUI, $currentQuestionId)
883 {
884 $isNextPrimary = true;
885
886 if ($this->object->isForceInstantFeedbackEnabled()) {
887 $isNextPrimary = false;
888 }
889
890 $questionsMissingResult = assQuestion::getQuestionsMissingResultRecord(
891 $this->testSession->getActiveId(),
892 $this->testSession->getPass(),
893 $this->testSequence->getOrderedSequenceQuestions()
894 );
895
896 if (!count($questionsMissingResult)) {
897 $navigationToolbarGUI->setFinishTestButtonPrimary(true);
898 $isNextPrimary = false;
899 } elseif (count($questionsMissingResult) == 1) {
900 $lastOpenQuestion = current($questionsMissingResult);
901
902 if ($currentQuestionId == $lastOpenQuestion) {
903 $navigationToolbarGUI->setFinishTestButtonPrimary(true);
904 $isNextPrimary = false;
905 }
906 }
907
908 return $isNextPrimary;
909 }
910}
$_GET["client_id"]
$_POST["username"]
$_SESSION["AccountId"]
An exception for terminatinating execution or to throw for unit testing.
Basic GUI class for assessment questions.
static _isWorkedThrough($active_id, $question_id, $pass=null)
Returns true if the question was worked through in the given pass Worked through means that the user ...
static getQuestionsMissingResultRecord($activeId, $pass, $questionIds)
Question page GUI class.
static getInstance(ilTestSession $a_test_session)
static _updateStatus($a_obj_id, $a_usr_id, $a_obj=null, $a_percentage=false, $a_force_raise=false)
Update status.
static _enabledAssessmentLogging()
check wether assessment logging is enabled or not
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test.
static isQuestionObligatory($question_id)
checks wether the question with given id is marked as obligatory or not
ILIAS Setting Class.
Base Exception for all Exceptions relating to Modules/Test.
setFinishTestButtonPrimary($finishTestButtonPrimary)
Output class for assessment test execution.
isLastQuestionInSequence($sequenceElement)
handleQuestionPostponing($sequenceElement)
isOptionalQuestionAnsweringConfirmationRequired($sequenceKey)
canSaveResult()
Returns TRUE if the answers of the current user could be saved.
handlePrimaryButton(ilTestNavigationToolbarGUI $navigationToolbarGUI, $currentQuestionId)
resumePlayerCmd()
Resume a test at the last position.
populateQuestionOptionalMessage()
isShowingPostponeStatusReguired($questionId)
executeCommand()
Execute Command.
isValidSequenceElement($sequenceElement)
isFirstQuestionInSequence($sequenceElement)
saveQuestionSolution($authorized=true, $force=false)
saves the user input of a question
Output class for assessment test execution.
handleSkillTriggering(ilTestSession $testSession)
checkTestSessionUser(ilTestSession $testSession)
removeIntermediateSolution()
remove an auto-saved solution of the current question
setAnswerChangedParameter($changed=true)
Set the 'answer changed' url parameter for generated links.
prepareTestPage($presentationMode, $sequenceElement, $questionId)
handleTearsAndAngerQuestionIsNull($questionId, $sequenceElement)
getQuestionInstance($questionId, $fromCache=true)
populateInstantResponseModal(assQuestionGUI $questionGui, $navUrl)
showQuestionEditable(assQuestionGUI $questionGui, $formAction, $isQuestionWorkedThrough, $instantResponse)
getQuestionGuiInstance($questionId, $fromCache=true)
ensureExistingTestSession(ilTestSession $testSession)
updateWorkingTime()
updates working time and stores state saveresult to see if question has to be stored or not
handleUserSettings()
Handles some form parameters on starting and resuming a test.
populateInstantResponseBlocks(assQuestionGUI $questionGui, $authorizedSolution)
populateTestNavigationToolbar(ilTestNavigationToolbarGUI $toolbarGUI)
getAnswerChangedParameter()
Get the 'answer changed' status from the current request It may be set by ilTestPlayerNavigationContr...
isMaxProcessingTimeReached()
Checks wheather the maximum processing time is reached or not.
saveNavigationPreventConfirmation()
Save the save the switch to prevent the navigation confirmation.
registerForcedFeedbackNavUrl($forcedFeedbackNavUrl)
populateQuestionNavigation($sequenceElement, $disabled, $primaryNext)
showQuestionViewable(assQuestionGUI $questionGui, $formAction, $isQuestionWorkedThrough, $instantResponse)
static getInstance(ilDBInterface $db, ilObjTest $testOBJ, ilTestRandomQuestionSetConfig $questionSetConfig, ilTestRandomQuestionSetSourcePoolDefinitionList $sourcePoolDefinitionList, ilTestRandomQuestionSetStagingPoolQuestionList $stagingPoolQuestionList)
getCommand($cmd)
Retrieves the ilCtrl command.
Signature Plugin Class.
Class ilTestSubmissionReviewGUI.
static redirect($a_script)
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
static initConnectionWithAnimation()
Init YUI Connection module.
static initjQuery($a_tpl=null)
inits and adds the jQuery JS-File to the global or a passed template
$ret
Definition: parser.php:6
global $DIC
Definition: saml.php:7
global $ilDB
$ilUser
Definition: imgupload.php:18