ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
class.ilTestPlayerDynamicQuestionSetGUI.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
30{
35
39 protected $testSequence;
40
44 protected $testSession;
45
49 public function executeCommand()
50 {
51 global $DIC;
52 $ilDB = $DIC['ilDB'];
53 $lng = $DIC['lng'];
54 $ilPluginAdmin = $DIC['ilPluginAdmin'];
55 $ilTabs = $DIC['ilTabs'];
56 $tree = $DIC['tree'];
57
58 $ilTabs->clearTargets();
59
60 $this->ctrl->saveParameter($this, "sequence");
61 $this->ctrl->saveParameter($this, "active_id");
62
64
65 require_once 'Modules/Test/classes/class.ilObjTestDynamicQuestionSetConfig.php';
66 $this->dynamicQuestionSetConfig = new ilObjTestDynamicQuestionSetConfig($tree, $ilDB, $ilPluginAdmin, $this->object);
67 $this->dynamicQuestionSetConfig->loadFromDb();
68
69 $testSessionFactory = new ilTestSessionFactory($this->object);
70 $this->testSession = $testSessionFactory->getSession($_GET['active_id']);
71
72 $this->ensureExistingTestSession($this->testSession);
73 $this->checkTestSessionUser($this->testSession);
74 $this->initProcessLocker($this->testSession->getActiveId());
75
76 $testSequenceFactory = new ilTestSequenceFactory($ilDB, $lng, $ilPluginAdmin, $this->object);
77 $this->testSequence = $testSequenceFactory->getSequenceByTestSession($this->testSession);
78 $this->testSequence->loadFromDb();
79
80 if ($this->object->isInstantFeedbackAnswerFixationEnabled()) {
81 $this->testSequence->setPreventCheckedQuestionsFromComingUpEnabled(true);
82 }
83
84 include_once 'Services/jQuery/classes/class.iljQueryUtil.php';
86 include_once "./Services/YUI/classes/class.ilYuiUtil.php";
88 if ($this->object->getKioskMode()) {
89 include_once 'Services/UIComponent/Overlay/classes/class.ilOverlayGUI.php';
91 }
92
94
95 $cmd = $this->ctrl->getCmd();
96 $nextClass = $this->ctrl->getNextClass($this);
97
98 switch ($nextClass) {
99 case 'ilassquestionpagegui':
100
101 $questionId = $this->testSession->getCurrentQuestionId();
102
103 require_once "./Modules/TestQuestionPool/classes/class.ilAssQuestionPageGUI.php";
104 $page_gui = new ilAssQuestionPageGUI($questionId);
105 $ret = $this->ctrl->forwardCommand($page_gui);
106 break;
107
108 case 'ilassquestionhintrequestgui':
109
110 $this->ctrl->saveParameter($this, 'pmode');
111
112 $questionGUI = $this->object->createQuestionGUI(
113 "",
114 $this->testSession->getCurrentQuestionId()
115 );
116
117 require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionHintTracking.php';
118 $questionHintTracking = new ilAssQuestionHintTracking(
119 $questionGUI->object->getId(),
120 $this->testSession->getActiveId(),
121 $this->testSession->getPass()
122 );
123
124 require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionHintRequestGUI.php';
126 $this,
128 $questionGUI,
129 $questionHintTracking
130 );
131
132// fau: testNav - save the 'answer changed status' for viewing hint requests
134// fau.
135 $this->ctrl->forwardCommand($gui);
136
137 break;
138
139 case 'ildynamicquestionsetstatistictablegui':
140
141 $this->ctrl->forwardCommand($this->buildQuestionSetFilteredStatisticTableGUI());
142
143 break;
144
145 case 'iltestpasswordprotectiongui':
146 require_once 'Modules/Test/classes/class.ilTestPasswordProtectionGUI.php';
147 $gui = new ilTestPasswordProtectionGUI($this->ctrl, $this->tpl, $this->lng, $this, $this->passwordChecker);
148 $ret = $this->ctrl->forwardCommand($gui);
149 break;
150
151 default:
152
153 $cmd .= 'Cmd';
154 $ret = &$this->$cmd();
155 break;
156 }
157
158 return $ret;
159 }
160
164 protected function getCurrentQuestionId()
165 {
166 return $this->testSession->getCurrentQuestionId();
167 }
168
172 protected function resumePlayerCmd()
173 {
174 if ($this->object->checkMaximumAllowedUsers() == false) {
176 }
177
178 $this->handleUserSettings();
179
180 if ($this->dynamicQuestionSetConfig->isAnyQuestionFilterEnabled()) {
181 $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION_SELECTION);
182 }
183
184 $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
185 }
186
187 protected function startTestCmd()
188 {
189 $this->testSession->setCurrentQuestionId(null); // no question "came up" yet
190
191 $this->testSession->saveToDb();
192
193 $this->ctrl->setParameter($this, 'active_id', $this->testSession->getActiveId());
194
195 assQuestion::_updateTestPassResults($this->testSession->getActiveId(), $this->testSession->getPass(), false, null, $this->object->id);
196
197 $_SESSION['active_time_id'] = $this->object->startWorkingTime(
198 $this->testSession->getActiveId(),
199 $this->testSession->getPass()
200 );
201
202 $this->ctrl->saveParameter($this, 'tst_javascript');
203
204 if ($this->dynamicQuestionSetConfig->isAnyQuestionFilterEnabled()) {
205 $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION_SELECTION);
206 }
207
208 $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
209 }
210
211 protected function showQuestionSelectionCmd()
212 {
213 $this->prepareSummaryPage();
214
215 $this->testSequence->loadQuestions(
216 $this->dynamicQuestionSetConfig,
217 $this->testSession->getQuestionSetFilterSelection()
218 );
219
220 $this->testSequence->cleanupQuestions($this->testSession);
221
222 $this->testSequence->saveToDb();
223
224 require_once 'Services/UIComponent/Toolbar/classes/class.ilToolbarGUI.php';
225 $toolbarGUI = new ilToolbarGUI();
226
227 require_once 'Services/UIComponent/Button/classes/class.ilLinkButton.php';
228 $button = ilLinkButton::getInstance();
229 $button->setUrl($this->getStartTestFromQuestionSelectionLink());
230 $button->setCaption($this->getEnterTestButtonLangVar());
231 $button->setPrimary(true);
232 $toolbarGUI->addButtonInstance($button);
233
234 if ($this->object->getShowCancel()) {
235 $button = ilLinkButton::getInstance();
236 $button->setUrl($this->ctrl->getLinkTarget(
237 $this,
239 ));
240 $button->setCaption('cancel_test');
241 $toolbarGUI->addButtonInstance($button);
242 }
243
244 if ($this->object->isPassDeletionAllowed()) {
245 require_once 'Modules/Test/classes/confirmations/class.ilTestPassDeletionConfirmationGUI.php';
246
247 $toolbarGUI->addButton(
248 $this->lng->txt('tst_dyn_test_pass_deletion_button'),
250 );
251 }
252
253 $filteredData = array($this->buildQuestionSetAnswerStatisticRowArray(
254 $this->testSequence->getFilteredQuestionsData(),
255 $this->testSequence->getTrackedQuestionList()
256 )); #vd($filteredData);
257 $filteredTableGUI = $this->buildQuestionSetFilteredStatisticTableGUI();
258 $filteredTableGUI->setData($filteredData);
259
260 $completeData = array($this->buildQuestionSetAnswerStatisticRowArray(
261 $this->testSequence->getCompleteQuestionsData(),
262 $this->testSequence->getTrackedQuestionList()
263 )); #vd($completeData);
264 $completeTableGUI = $this->buildQuestionSetCompleteStatisticTableGUI();
265 $completeTableGUI->setData($completeData);
266
267 $content = $this->ctrl->getHTML($toolbarGUI);
268 $content .= $this->ctrl->getHTML($filteredTableGUI);
269 $content .= $this->ctrl->getHTML($completeTableGUI);
270
271 $this->tpl->setVariable('TABLE_LIST_OF_QUESTIONS', $content);
272
273 if ($this->object->getEnableProcessingTime()) {
274 $this->outProcessingTime($this->testSession->getActiveId());
275 }
276 }
277
278 protected function filterQuestionSelectionCmd()
279 {
281 $tableGUI->writeFilterToSession();
282
283 $taxFilterSelection = array();
284 $answerStatusFilterSelection = ilAssQuestionList::ANSWER_STATUS_FILTER_ALL_NON_CORRECT;
285
286 foreach ($tableGUI->getFilterItems() as $item) {
287 if (strpos($item->getPostVar(), 'tax_') !== false) {
288 $taxId = substr($item->getPostVar(), strlen('tax_'));
289 $taxFilterSelection[$taxId] = $item->getValue();
290 } elseif ($item->getPostVar() == 'question_answer_status') {
291 $answerStatusFilterSelection = $item->getValue();
292 }
293 }
294
295 $this->testSession->getQuestionSetFilterSelection()->setTaxonomySelection($taxFilterSelection);
296 $this->testSession->getQuestionSetFilterSelection()->setAnswerStatusSelection($answerStatusFilterSelection);
297 $this->testSession->saveToDb();
298
299 $this->testSequence->resetTrackedQuestionList();
300 $this->testSequence->saveToDb();
301
302
303 $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION_SELECTION);
304 }
305
306 protected function resetQuestionSelectionCmd()
307 {
309 $tableGUI->resetFilter();
310
311 $this->testSession->getQuestionSetFilterSelection()->setTaxonomySelection(array());
312 $this->testSession->getQuestionSetFilterSelection()->setAnswerStatusSelection(null);
313 $this->testSession->saveToDb();
314
315 $this->testSequence->resetTrackedQuestionList();
316 $this->testSequence->saveToDb();
317
318 $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION_SELECTION);
319 }
320
321 protected function previousQuestionCmd()
322 {
323 // nothing to do, won't be called
324 }
325
326 protected function fromPassDeletionCmd()
327 {
328 $this->resetCurrentQuestion();
329 $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
330 }
331
332 protected function nextQuestionCmd()
333 {
334 $isWorkedThrough = assQuestion::_isWorkedThrough(
335 $this->testSession->getActiveId(),
336 $this->testSession->getCurrentQuestionId(),
337 $this->testSession->getPass()
338 );
339
340 if (!$isWorkedThrough) {
341 $this->testSequence->setQuestionPostponed($this->testSession->getCurrentQuestionId());
342 $this->testSequence->saveToDb();
343 }
344
345 $this->resetCurrentQuestion();
346
347 $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
348 }
349
350 protected function markQuestionCmd()
351 {
352 global $DIC;
353 $ilUser = $DIC['ilUser'];
354 $this->object->setQuestionSetSolved(1, $this->testSession->getCurrentQuestionId(), $ilUser->getId());
355
356 $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
357 }
358
359 protected function unmarkQuestionCmd()
360 {
361 global $DIC;
362 $ilUser = $DIC['ilUser'];
363 $this->object->setQuestionSetSolved(0, $this->testSession->getCurrentQuestionId(), $ilUser->getId());
364
365 $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
366 }
367
368 protected function editSolutionCmd()
369 {
370 $this->ctrl->setParameter($this, 'pmode', ilTestPlayerAbstractGUI::PRESENTATION_MODE_EDIT);
371 $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
372 }
373
374 protected function submitSolutionAndNextCmd()
375 {
376 if ($this->object->isForceInstantFeedbackEnabled()) {
377 return $this->submitSolutionCmd();
378 }
379
380 if ($this->saveQuestionSolution(true, false)) {
381 $questionId = $this->testSession->getCurrentQuestionId();
382
383 $this->getQuestionInstance($questionId)->removeIntermediateSolution(
384 $this->testSession->getActiveId(),
385 $this->testSession->getPass()
386 );
387
389
390 $this->ctrl->setParameter($this, 'pmode', '');
391
392 $this->resetCurrentQuestion();
393 }
394
395 $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
396 }
397
398 protected function submitSolutionCmd()
399 {
400 if ($this->saveQuestionSolution(true, false)) {
401 $questionId = $this->testSession->getCurrentQuestionId();
402
403 $this->getQuestionInstance($questionId)->removeIntermediateSolution(
404 $this->testSession->getActiveId(),
405 $this->testSession->getPass()
406 );
407
409
410 if ($this->object->isForceInstantFeedbackEnabled()) {
411 $this->ctrl->setParameter($this, 'instresp', 1);
412
413 $this->testSequence->unsetQuestionPostponed($questionId);
414 $this->testSequence->setQuestionChecked($questionId);
415 $this->testSequence->saveToDb();
416 }
417
418 if ($this->getNextCommandParameter()) {
419 if ($this->getNextSequenceParameter()) {
420 $this->ctrl->setParameter($this, 'sequence', $this->getNextSequenceParameter());
421 $this->ctrl->setParameter($this, 'pmode', '');
422 }
423
424 $this->ctrl->redirect($this, $this->getNextCommandParameter());
425 }
426
427 $this->ctrl->setParameter($this, 'pmode', ilTestPlayerAbstractGUI::PRESENTATION_MODE_VIEW);
428 } else {
429 $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
430 }
431
432 // fau: testNav - remember to prevent the navigation confirmation
434 // fau.
435
436 // fau: testNav - handle navigation after saving
437 if ($this->getNavigationUrlParameter()) {
439 } else {
440 $this->ctrl->saveParameter($this, 'sequence');
441 }
442 // fau.
443 $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
444 }
445
446 protected function discardSolutionCmd()
447 {
448 $questionId = $this->testSession->getCurrentQuestionId();
449
450 $currentQuestionOBJ = $this->getQuestionInstance($questionId);
451
452 $currentQuestionOBJ->resetUsersAnswer(
453 $this->testSession->getActiveId(),
454 $this->testSession->getPass()
455 );
456
457 $this->ctrl->setParameter($this, 'pmode', ilTestPlayerAbstractGUI::PRESENTATION_MODE_VIEW);
458
459 $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
460 }
461
462 protected function skipQuestionCmd()
463 {
464 $this->nextQuestionCmd();
465 }
466
468 {
469 if (!$this->getResetCheckedParameter()) {
470 return false;
471 }
472
473 if ($this->testSession->getQuestionSetFilterSelection()->isAnswerStatusSelectionWrongAnswered()) {
474 $this->testSequence->loadQuestions(
475 $this->dynamicQuestionSetConfig,
476 $this->testSession->getQuestionSetFilterSelection()
477 );
478
479 if ($this->testSequence->hasFilteredQuestionListCheckedQuestions()) {
480 return true;
481 }
482 }
483
484 return false;
485 }
486
487 protected function showQuestionCmd()
488 {
489 $this->updateWorkingTime();
490
491 $this->testSequence->loadQuestions(
492 $this->dynamicQuestionSetConfig,
493 $this->testSession->getQuestionSetFilterSelection()
494 );
495
496 $this->testSequence->cleanupQuestions($this->testSession);
497
500 return;
501 }
502
503 if ($this->testSequence->getQuestionSet()->getSelectionQuestionList()->isInList($this->getQuestionIdParameter())) {
504 $this->testSession->setCurrentQuestionId($this->getQuestionIdParameter());
505 } else {
507 }
508
509 if (!$this->testSession->getCurrentQuestionId()) {
510 $upComingQuestionId = $this->testSequence->getUpcomingQuestionId();
511
512 $this->testSession->setCurrentQuestionId($upComingQuestionId);
513
514 // seems to be a first try of freezing answers not too hard
515 /*if( $this->testSequence->isQuestionChecked($upComingQuestionId) )
516 {
517 $this->testSequence->setQuestionUnchecked($upComingQuestionId);
518 }*/
519 }
520
521 $navigationToolbarGUI = $this->getTestNavigationToolbarGUI();
522 $navigationToolbarGUI->setQuestionSelectionButtonEnabled(true);
523
524 if ($this->testSession->getCurrentQuestionId()) {
525 $questionGui = $this->getQuestionGuiInstance($this->testSession->getCurrentQuestionId());
526 $this->testSequence->setCurrentQuestionId($this->testSession->getCurrentQuestionId());
527
528 $questionGui->setQuestionCount(
529 $this->testSequence->getLastPositionIndex()
530 );
531 $questionGui->setSequenceNumber(
532 $this->testSequence->getCurrentPositionIndex($this->testSession->getCurrentQuestionId())
533 );
534
535 if (!($questionGui instanceof assQuestionGUI)) {
537 $this->testSession->getCurrentQuestionId(),
538 $this->testSession->getCurrentQuestionId()
539 );
540 }
541
542 $isQuestionWorkedThrough = assQuestion::_isWorkedThrough(
543 $this->testSession->getActiveId(),
544 $this->testSession->getCurrentQuestionId(),
545 $this->testSession->getPass()
546 );
547
548 require_once 'Modules/Test/classes/class.ilTestQuestionHeaderBlockBuilder.php';
549 $headerBlockBuilder = new ilTestQuestionHeaderBlockBuilder($this->lng);
550 $headerBlockBuilder->setHeaderMode(
551 // avoid legacy setting combination: ctm without question titles
552 $this->object->getTitleOutput() == 2 ? 1 : $this->object->getTitleOutput()
553 );
554 $headerBlockBuilder->setQuestionTitle($questionGui->object->getTitle());
555 $headerBlockBuilder->setQuestionPoints($questionGui->object->getPoints());
556 /* avoid showing Qst X of Y within CTMs
557 $headerBlockBuilder->setQuestionPosition(
558 $this->testSequence->getCurrentPositionIndex($this->testSession->getCurrentQuestionId())
559 );
560 $headerBlockBuilder->setQuestionCount($this->testSequence->getLastPositionIndex());
561 */
562 $headerBlockBuilder->setQuestionPostponed(
563 $this->testSequence->isPostponedQuestion(
564 $this->testSession->getCurrentQuestionId()
565 )
566 );
567 $headerBlockBuilder->setQuestionObligatory(
568 $this->object->areObligationsEnabled() && ilObjTest::isQuestionObligatory($this->object->getId())
569 );
570 $questionGui->setQuestionHeaderBlockBuilder($headerBlockBuilder);
571
572 // fau: testNav - always use edit mode, except for fixed answer
573 if ($this->isParticipantsAnswerFixed($this->testSession->getCurrentQuestionId())) {
574 $instantResponse = true;
576 } else {
577 $instantResponse = $this->getInstantResponseParameter();
579 }
580 // fau.
581
582 $this->prepareTestPage(
583 $presentationMode,
584 $this->testSession->getCurrentQuestionId(),
585 $this->testSession->getCurrentQuestionId()
586 );
587
588 $this->ctrl->setParameter($this, 'sequence', $this->testSession->getCurrentQuestionId());
589 $this->ctrl->setParameter($this, 'pmode', $presentationMode);
590 $formAction = $this->ctrl->getFormAction($this, ilTestPlayerCommands::SUBMIT_INTERMEDIATE_SOLUTION);
591
592 switch ($presentationMode) {
594
595// fau: testNav - enable navigation toolbar in edit mode
596 $navigationToolbarGUI->setDisabledStateEnabled(false);
597// fau.
598 $this->showQuestionEditable($questionGui, $formAction, $isQuestionWorkedThrough, $instantResponse);
599
600 break;
601
603
604 $this->showQuestionViewable($questionGui, $formAction, $isQuestionWorkedThrough, $instantResponse);
605
606 break;
607
608 default:
609
610 require_once 'Modules/Test/exceptions/class.ilTestException.php';
611 throw new ilTestException('no presentation mode given');
612 }
613
614 $navigationToolbarGUI->build();
615 $this->populateTestNavigationToolbar($navigationToolbarGUI);
616
617 // fau: testNav - enable the question navigation in edit mode
619 $this->testSession->getCurrentQuestionId(),
620 false,
621 $this->object->isForceInstantFeedbackEnabled()
622 );
623 // fau.
624
625 if ($instantResponse) {
626 // fau: testNav - always use authorized solution for instant feedback
628 $questionGui,
629 true
630 );
631 // fau.
632 $this->testSession->getQuestionSetFilterSelection()->setForcedQuestionIds(array());
633 }
634
635 // fau: testNav - add feedback modal
639 }
640 // fau.
641 } else {
643
644 $navigationToolbarGUI->build();
645 $this->populateTestNavigationToolbar($navigationToolbarGUI);
646
648 }
649
650 $this->testSequence->saveToDb();
651 $this->testSession->saveToDb();
652 }
653
654 protected function showInstantResponseCmd()
655 {
656 $questionId = $this->testSession->getCurrentQuestionId();
657
658 $filterSelection = $this->testSession->getQuestionSetFilterSelection();
659
660 $filterSelection->setForcedQuestionIds(array($this->testSession->getCurrentQuestionId()));
661
662 $this->testSequence->loadQuestions($this->dynamicQuestionSetConfig, $filterSelection);
663 $this->testSequence->cleanupQuestions($this->testSession);
664 $this->testSequence->saveToDb();
665
666 if (!$this->isParticipantsAnswerFixed($questionId)) {
667 if ($this->saveQuestionSolution(true)) {
670 $this->setAnswerChangedParameter(false);
671 } else {
672 $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
673 }
674 $this->testSequence->unsetQuestionPostponed($questionId);
675 $this->testSequence->setQuestionChecked($questionId);
676 $this->testSequence->saveToDb();
677 }
678
679 $this->ctrl->setParameter(
680 $this,
681 'sequence',
682 $this->testSession->getCurrentQuestionId()
683 );
684
685 $this->ctrl->setParameter($this, 'instresp', 1);
686
687 // fau: testNav - handle navigation after feedback
688 if ($this->getNavigationUrlParameter()) {
691 }
692 // fau.
693 $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
694 }
695
696 protected function handleQuestionActionCmd()
697 {
698 $questionId = $this->testSession->getCurrentQuestionId();
699
700 if ($questionId && !$this->isParticipantsAnswerFixed($questionId)) {
701 $this->saveQuestionSolution(false);
702 // fau: testNav - add changed status of the question
703 $this->setAnswerChangedParameter(true);
704 // fau.
705 }
706
707 $this->ctrl->setParameter(
708 $this,
709 'sequence',
710 $this->testSession->getCurrentQuestionId()
711 );
712
713 $this->ctrl->saveParameter($this, 'pmode');
714
715 $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
716 }
717
718 private function outCurrentlyFinishedPage()
719 {
720 if ($this->testSequence->openQuestionExists()) {
721 $message = $this->lng->txt('tst_dyn_test_msg_currently_finished_selection');
722 } else {
723 $message = $this->lng->txt('tst_dyn_test_msg_currently_finished_completely');
724 $message .= "<br /><br />{$this->buildFinishPagePassDeletionLink()}";
725 }
726
727 $msgHtml = $this->tpl->getMessageHTML($message);
728
729 $tpl = new ilTemplate('tpl.test_currently_finished_msg.html', true, true, 'Modules/Test');
730 $tpl->setVariable('TEST_CURRENTLY_FINISHED_MSG', $msgHtml);
731
732 $this->tpl->setVariable('QUESTION_OUTPUT', $tpl->get());
733 }
734
735 protected function isFirstQuestionInSequence($sequenceElement)
736 {
737 return !$this->testSequence->trackedQuestionExists();
738 }
739
740 protected function isLastQuestionInSequence($sequenceElement)
741 {
742 return false; // always
743 }
744
750 protected function canSaveResult()
751 {
752 return !$this->object->endingTimeReached();
753 }
754
758 public function saveQuestionSolution($authorized = true, $force = false)
759 {
760 // what is this formtimestamp ??
761 if (!$force) {
762 $formtimestamp = $_POST["formtimestamp"];
763 if (strlen($formtimestamp) == 0) {
764 $formtimestamp = $_GET["formtimestamp"];
765 }
766 if ($formtimestamp != $_SESSION["formtimestamp"]) {
767 $_SESSION["formtimestamp"] = $formtimestamp;
768 } else {
769 return false;
770 }
771 }
772
773 // determine current question
774
775 $qId = $this->testSession->getCurrentQuestionId();
776
777 if (!$qId || $qId != $_GET["sequence"]) {
778 return false;
779 }
780
781 // save question solution
782
783 $this->saveResult = false;
784
785 if ($this->canSaveResult($qId) || $force) {
786 $questionGUI = $this->object->createQuestionGUI("", $qId);
787
788 if ($this->object->getJavaScriptOutput()) {
789 $questionGUI->object->setOutputType(OUTPUT_JAVASCRIPT);
790 }
791
792 $activeId = $this->testSession->getActiveId();
793
794 $this->saveResult = $questionGUI->object->persistWorkingState(
795 $activeId,
796 $pass = null,
797 $this->object->areObligationsEnabled(),
798 $authorized
799 );
800
801 if ($authorized && $this->object->isSkillServiceToBeConsidered()) {
802 $this->handleSkillTriggering($this->testSession);
803 }
804 }
805
806 if ($this->saveResult == false) {
807 $this->ctrl->setParameter($this, "save_error", "1");
808 $_SESSION["previouspost"] = $_POST;
809 }
810
811 return $this->saveResult;
812 }
813
814 private function isQuestionAnsweredCorrect($questionId, $activeId, $pass)
815 {
816 $questionGUI = $this->object->createQuestionGUI("", $questionId);
817
818 $reachedPoints = assQuestion::_getReachedPoints($activeId, $questionId, $pass);
819 $maxPoints = $questionGUI->object->getMaximumPoints();
820
821 if ($reachedPoints < $maxPoints) {
822 return false;
823 }
824
825 return true;
826 }
827
828 protected function buildQuestionsTableDataArray($questions, $marked_questions)
829 {
830 $data = array();
831
832 foreach ($questions as $key => $value) {
833 $this->ctrl->setParameter($this, 'sequence', $value['question_id']);
834 $href = $this->ctrl->getLinkTarget($this, 'gotoQuestion');
835 $this->ctrl->setParameter($this, 'sequence', '');
836
837 $description = "";
838 if ($this->object->getListOfQuestionsDescription()) {
839 $description = $value["description"];
840 }
841
842 $marked = false;
843 if (count($marked_questions)) {
844 if (isset($marked_questions[$value["question_id"]])) {
845 if ($marked_questions[$value["question_id"]]["solved"] == 1) {
846 $marked = true;
847 }
848 }
849 }
850
851 array_push($data, array(
852 'href' => $href,
853 'title' => $this->object->getQuestionTitle($value["title"]),
854 'description' => $description,
855 'worked_through' => $this->testSequence->isAnsweredQuestion($value["question_id"]),
856 'postponed' => $this->testSequence->isPostponedQuestion($value["question_id"]),
857 'marked' => $marked
858 ));
859 }
860
861 return $data;
862 }
863
864 protected function buildQuestionSetAnswerStatisticRowArray($questions, $trackedQuestions)
865 {
866 $questionAnswerStats = array(
867 'total_all' => count($questions),
868 'total_open' => 0,
869 'non_answered_notseen' => 0,
870 'non_answered_skipped' => 0,
871 'wrong_answered' => 0,
872 'correct_answered' => 0
873 );
874
875 foreach ($questions as $key => $value) {
876 switch ($value['question_answer_status']) {
878 if (isset($trackedQuestions[$key])) {
879 $questionAnswerStats['non_answered_skipped']++;
880 } else {
881 $questionAnswerStats['non_answered_notseen']++;
882 }
883 $questionAnswerStats['total_open']++;
884 break;
886 $questionAnswerStats['wrong_answered']++;
887 $questionAnswerStats['total_open']++;
888 break;
890 $questionAnswerStats['correct_answered']++;
891 break;
892 }
893 }
894
895 return $questionAnswerStats;
896 }
897
899 {
900 require_once 'Modules/Test/classes/tables/class.ilTestDynamicQuestionSetStatisticTableGUI.php';
903 );
904
905 $gui->initTitle('tst_dynamic_question_set_complete');
906 $gui->initColumns('tst_num_all_questions');
907
908 return $gui;
909 }
910
912 {
913 require_once 'Modules/Test/classes/tables/class.ilTestDynamicQuestionSetStatisticTableGUI.php';
916 );
917
918 $gui->initTitle('tst_dynamic_question_set_selection');
919 $gui->initColumns('tst_num_selected_questions');
920
921 require_once 'Services/Taxonomy/classes/class.ilObjTaxonomy.php';
922 $gui->setTaxIds(ilObjTaxonomy::getUsageOfObject(
923 $this->dynamicQuestionSetConfig->getSourceQuestionPoolId()
924 ));
925
926 $gui->setTaxonomyFilterEnabled($this->dynamicQuestionSetConfig->isTaxonomyFilterEnabled());
927 $gui->setAnswerStatusFilterEnabled($this->dynamicQuestionSetConfig->isAnswerStatusFilterEnabled());
928
929 $gui->setFilterSelection($this->testSession->getQuestionSetFilterSelection());
930 $gui->initFilter();
931 $gui->setFilterCommand('filterQuestionSelection');
932 $gui->setResetCommand('resetQuestionSelection');
933
934 return $gui;
935 }
936
937 private function buildQuestionSetStatisticTableGUI($tableId)
938 {
939 require_once 'Modules/Test/classes/tables/class.ilTestDynamicQuestionSetStatisticTableGUI.php';
941 $this->ctrl,
942 $this->lng,
943 $this,
945 $tableId
946 );
947
948 return $gui;
949 }
950
951 private function getEnterTestButtonLangVar()
952 {
953 if ($this->testSequence->trackedQuestionExists()) {
954 return 'tst_resume_dyn_test_with_cur_quest_sel';
955 }
956
957 return 'tst_start_dyn_test_with_cur_quest_sel';
958 }
959
960 protected function persistQuestionAnswerStatus()
961 {
962 $questionId = $this->testSession->getCurrentQuestionId();
963 $activeId = $this->testSession->getActiveId();
964 $pass = $this->testSession->getPass();
965
966 if ($this->isQuestionAnsweredCorrect($questionId, $activeId, $pass)) {
967 $this->testSequence->setQuestionAnsweredCorrect($questionId);
968 } else {
969 $this->testSequence->setQuestionAnsweredWrong($questionId);
970 }
971
972 $this->testSequence->saveToDb();
973 }
974
975 private function resetCurrentQuestion()
976 {
977 $this->testSession->setCurrentQuestionId(null);
978 $this->testSession->saveToDb();
979
980 $this->ctrl->setParameter($this, 'sequence', $this->testSession->getCurrentQuestionId());
981 $this->ctrl->setParameter($this, 'pmode', '');
982 }
983
988 {
989 $href = $this->getPassDeletionTarget();
990
991 $label = $this->lng->txt('tst_dyn_test_msg_pass_deletion_link');
992
993 return "<a href=\"{$href}\">{$label}</a>";
994 }
995
999 private function getPassDeletionTarget()
1000 {
1001 require_once 'Modules/Test/classes/confirmations/class.ilTestPassDeletionConfirmationGUI.php';
1002
1003 $this->ctrl->setParameterByClass('ilTestEvaluationGUI', 'context', ilTestPassDeletionConfirmationGUI::CONTEXT_DYN_TEST_PLAYER);
1004 $this->ctrl->setParameterByClass('ilTestEvaluationGUI', 'active_id', $this->testSession->getActiveId());
1005 $this->ctrl->setParameterByClass('ilTestEvaluationGUI', 'pass', $this->testSession->getPass());
1006
1007 return $this->ctrl->getLinkTargetByClass('ilTestEvaluationGUI', 'confirmDeletePass');
1008 }
1009
1010 protected function resetQuestionIdParameter()
1011 {
1013 }
1014
1015 protected function getQuestionIdParameter()
1016 {
1017 return $this->getSequenceElementParameter();
1018 }
1019
1020 protected function getResetCheckedParameter()
1021 {
1022 if (isset($_GET['reset_checked'])) {
1023 return $_GET['reset_checked'];
1024 }
1025
1026 return null;
1027 }
1028
1029 public function outQuestionSummaryCmd($fullpage = true, $contextFinishTest = false, $obligationsNotAnswered = false, $obligationsFilter = false)
1030 {
1031 $this->testSequence->loadQuestions(
1032 $this->dynamicQuestionSetConfig,
1033 $this->testSession->getQuestionSetFilterSelection()
1034 );
1035
1036 $this->testSequence->setCurrentQuestionId($this->testSession->getCurrentQuestionId());
1037
1038 parent::outQuestionSummaryCmd($fullpage, $contextFinishTest, $obligationsNotAnswered, $obligationsFilter);
1039 }
1040
1042 {
1043 require_once 'Services/Utilities/classes/class.ilConfirmationGUI.php';
1044 $confirmation = new ilConfirmationGUI();
1045 $confirmation->setFormAction($this->ctrl->getFormAction($this));
1046 $confirmation->setHeaderText($this->lng->txt('tst_dyn_unfreeze_answers_confirmation'));
1047 $confirmation->setConfirm($this->lng->txt('tst_dyn_unfreeze_answers'), ilTestPlayerCommands::UNFREEZE_ANSWERS);
1048 $confirmation->setCancel($this->lng->txt('tst_dyn_keep_answ_freeze'), ilTestPlayerCommands::SHOW_QUESTION);
1049
1050 $this->populateMessageContent($confirmation->getHtml());
1051 }
1052
1054 {
1055 $this->testSequence->loadQuestions(
1056 $this->dynamicQuestionSetConfig,
1057 $this->testSession->getQuestionSetFilterSelection()
1058 );
1059
1060 $this->testSequence->resetFilteredQuestionListsCheckedStatus();
1061 $this->testSequence->saveToDb();
1062
1063 $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
1064 }
1065
1066 protected function populateQuestionNavigation($sequenceElement, $disabled, $primaryNext)
1067 {
1068 if (!$this->isLastQuestionInSequence($sequenceElement)) {
1069 $this->populateNextButtons($disabled, $primaryNext);
1070 }
1071 }
1072
1074 {
1075 $this->ctrl->setParameter($this, 'reset_checked', 1);
1076 $link = $this->ctrl->getLinkTarget($this, ilTestPlayerCommands::SHOW_QUESTION);
1077 $this->ctrl->setParameter($this, 'reset_checked', '');
1078
1079 return $link;
1080 }
1081
1082 protected function isShowingPostponeStatusReguired($questionId)
1083 {
1084 return false;
1085 }
1086
1087 protected function buildTestPassQuestionList()
1088 {
1089 global $DIC;
1090 $ilPluginAdmin = $DIC['ilPluginAdmin'];
1091
1092 require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionList.php';
1093 $questionList = new ilAssQuestionList($this->db, $this->lng, $ilPluginAdmin);
1094 $questionList->setParentObjId($this->dynamicQuestionSetConfig->getSourceQuestionPoolId());
1095 $questionList->setQuestionInstanceTypeFilter(ilAssQuestionList::QUESTION_INSTANCE_TYPE_ORIGINALS);
1096
1097 return $questionList;
1098 }
1099
1101 {
1102 return false;
1103 }
1104
1106 {
1107 return false;
1108 }
1109}
$_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 _getReachedPoints($active_id, $question_id, $pass=null)
Returns the points, a learner has reached answering the question.
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 ...
const ANSWER_STATUS_FILTER_ALL_NON_CORRECT
answer status filter value domain
const QUESTION_ANSWER_STATUS_NON_ANSWERED
answer status domain for single questions
Question page GUI class.
Confirmation screen class.
static getInstance()
Factory.
static getUsageOfObject($a_obj_id, $a_include_titles=false)
Get usage of object.
static isQuestionObligatory($question_id)
checks wether the question with given id is marked as obligatory or not
static initJavascript()
Init javascript.
special template class to simplify handling of ITX/PEAR
Base Exception for all Exceptions relating to Modules/Test.
Output class for assessment test execution.
handleSkillTriggering(ilTestSession $testSession)
checkTestSessionUser(ilTestSession $testSession)
populateNextButtons($disabled, $primaryNext)
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...
saveNavigationPreventConfirmation()
Save the save the switch to prevent the navigation confirmation.
registerForcedFeedbackNavUrl($forcedFeedbackNavUrl)
showQuestionViewable(assQuestionGUI $questionGui, $formAction, $isQuestionWorkedThrough, $instantResponse)
canSaveResult()
Returns TRUE if the answers of the current user could be saved.
outQuestionSummaryCmd($fullpage=true, $contextFinishTest=false, $obligationsNotAnswered=false, $obligationsFilter=false)
Output of a summary of all test questions for test participants.
resumePlayerCmd()
Resume a test at the last position.
populateQuestionNavigation($sequenceElement, $disabled, $primaryNext)
buildQuestionSetAnswerStatisticRowArray($questions, $trackedQuestions)
saveQuestionSolution($authorized=true, $force=false)
saves the user input of a question
static redirect($a_script)
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
$key
Definition: croninfo.php:18
const OUTPUT_JAVASCRIPT
vd()
shortcut for var_dump with enhanced debug information
Definition: inc.debug.php:42
catch(Exception $e) $message
$ret
Definition: parser.php:6
global $DIC
Definition: saml.php:7
global $ilDB
$ilUser
Definition: imgupload.php:18
$data
Definition: bench.php:6