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