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