ILIAS  release_5-0 Revision 5.0.0-1144-gc4397b1f870
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
31{
32 const CMD_SHOW_QUESTION_SELECTION = 'showQuestionSelection';
33 const CMD_SHOW_QUESTION = 'showQuestion';
34 const CMD_FROM_PASS_DELETION = 'fromPassDeletion';
35
40
44 protected $testSequence;
45
49 protected $testSession;
50
54 function executeCommand()
55 {
56 global $ilDB, $lng, $ilPluginAdmin, $ilTabs, $tree;
57
58 $ilTabs->clearTargets();
59
60 $this->ctrl->saveParameter($this, "sequence");
61 $this->ctrl->saveParameter($this, "active_id");
62
63 require_once 'Modules/Test/classes/class.ilObjTestDynamicQuestionSetConfig.php';
64 $this->dynamicQuestionSetConfig = new ilObjTestDynamicQuestionSetConfig($tree, $ilDB, $ilPluginAdmin, $this->object);
65 $this->dynamicQuestionSetConfig->loadFromDb();
66
67 $testSessionFactory = new ilTestSessionFactory($this->object);
68 $this->testSession = $testSessionFactory->getSession($_GET['active_id']);
69
70 $this->ensureExistingTestSession($this->testSession);
71 $this->initProcessLocker($this->testSession->getActiveId());
72
73 $testSequenceFactory = new ilTestSequenceFactory($ilDB, $lng, $ilPluginAdmin, $this->object);
74 $this->testSequence = $testSequenceFactory->getSequence($this->testSession);
75 $this->testSequence->loadFromDb();
76
77 include_once 'Services/jQuery/classes/class.iljQueryUtil.php';
79 include_once "./Services/YUI/classes/class.ilYuiUtil.php";
81 if( $this->object->getKioskMode() )
82 {
83 include_once 'Services/UIComponent/Overlay/classes/class.ilOverlayGUI.php';
85 }
86
88
89 $cmd = $this->ctrl->getCmd();
90 $nextClass = $this->ctrl->getNextClass($this);
91
92 switch($nextClass)
93 {
94 case 'ilassquestionpagegui':
95
96 $questionId = $this->testSequence->getQuestionForSequence( $this->calculateSequence() );
97
98 require_once "./Modules/TestQuestionPool/classes/class.ilAssQuestionPageGUI.php";
99 $page_gui = new ilAssQuestionPageGUI($questionId);
100 $ret = $this->ctrl->forwardCommand($page_gui);
101 break;
102
103 case 'ilassquestionhintrequestgui':
104
105 $questionGUI = $this->object->createQuestionGUI(
106 "", $this->testSequenceFactory->getSequence()->getQuestionForSequence( $this->calculateSequence() )
107 );
108
109 require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionHintRequestGUI.php';
110 $gui = new ilAssQuestionHintRequestGUI($this, self::CMD_SHOW_QUESTION, $this->testSession, $questionGUI);
111
112 $this->ctrl->forwardCommand($gui);
113
114 break;
115
116 case 'ildynamicquestionsetstatistictablegui':
117
118 $this->ctrl->forwardCommand( $this->buildQuestionSetFilteredStatisticTableGUI() );
119
120 break;
121
122 case 'iltestpasswordprotectiongui':
123 require_once 'Modules/Test/classes/class.ilTestPasswordProtectionGUI.php';
124 $gui = new ilTestPasswordProtectionGUI($this->ctrl, $this->tpl, $this->lng, $this, $this->passwordChecker);
125 $ret = $this->ctrl->forwardCommand($gui);
126 break;
127
128 default:
129
130 $cmd .= 'Cmd';
131 $ret =& $this->$cmd();
132 break;
133 }
134
135 return $ret;
136 }
137
141 protected function getCurrentQuestionId()
142 {
143 return $this->testSession->getCurrentQuestionId();
144 }
145
149 protected function resumePlayerCmd()
150 {
151 if ($this->object->checkMaximumAllowedUsers() == FALSE)
152 {
154 }
155
156 $this->handleUserSettings();
157
158 if( $this->dynamicQuestionSetConfig->isAnyQuestionFilterEnabled() )
159 {
160 $this->ctrl->redirect($this, self::CMD_SHOW_QUESTION_SELECTION);
161 }
162
163 $this->ctrl->redirect($this, self::CMD_SHOW_QUESTION);
164 }
165
166 protected function startTestCmd()
167 {
168 global $ilUser;
169
170 $this->testSession->setCurrentQuestionId(null); // no question "came up" yet
171
172 $this->testSession->saveToDb();
173
174 $this->ctrl->setParameter($this, 'active_id', $this->testSession->getActiveId());
175
176 assQuestion::_updateTestPassResults($this->testSession->getActiveId(), $this->testSession->getPass(), false, null, $this->object->id);
177
178 $_SESSION['active_time_id'] = $this->object->startWorkingTime(
179 $this->testSession->getActiveId(), $this->testSession->getPass()
180 );
181
182 $this->ctrl->saveParameter($this, 'tst_javascript');
183
184 if( $this->dynamicQuestionSetConfig->isAnyQuestionFilterEnabled() )
185 {
186 $this->ctrl->redirect($this, self::CMD_SHOW_QUESTION_SELECTION);
187 }
188
189 $this->ctrl->redirect($this, self::CMD_SHOW_QUESTION);
190 }
191
192 protected function showQuestionSelectionCmd()
193 {
194 $this->prepareSummaryPage();
195
196 $questionId = $this->testSession->getCurrentQuestionId();
197
198 if( $questionId && !$this->isParticipantsAnswerFixed($questionId) )
199 {
200 $this->updateWorkingTime();
201 $this->saveQuestionSolution();
203
204 $this->testSequence->unsetQuestionPostponed($questionId);
205 }
206
207 $this->testSequence->loadQuestions(
208 $this->dynamicQuestionSetConfig, $this->testSession->getQuestionSetFilterSelection()
209 );
210
211 $this->testSequence->cleanupQuestions($this->testSession);
212
213 $this->testSequence->saveToDb();
214
215 require_once 'Services/UIComponent/Toolbar/classes/class.ilToolbarGUI.php';
216 $toolbarGUI = new ilToolbarGUI();
217
218 $toolbarGUI->addButton(
219 $this->getEnterTestButtonLangVar(), $this->ctrl->getLinkTarget($this, self::CMD_SHOW_QUESTION),
220 '', '', '', '', 'submit emphsubmit'
221 );
222
223 if( $this->object->isPassDeletionAllowed() )
224 {
225 require_once 'Modules/Test/classes/confirmations/class.ilTestPassDeletionConfirmationGUI.php';
226
227 $toolbarGUI->addButton(
228 $this->lng->txt('tst_dyn_test_pass_deletion_button'),
230 );
231 }
232
233 $filteredData = array($this->buildQuestionSetAnswerStatisticRowArray(
234 $this->testSequence->getFilteredQuestionsData(), $this->getMarkedQuestions()
235 )); #vd($filteredData);
236 $filteredTableGUI = $this->buildQuestionSetFilteredStatisticTableGUI();
237 $filteredTableGUI->setData($filteredData);
238
239 $completeData = array($this->buildQuestionSetAnswerStatisticRowArray(
240 $this->testSequence->getCompleteQuestionsData(), $this->getMarkedQuestions()
241 )); #vd($completeData);
242 $completeTableGUI = $this->buildQuestionSetCompleteStatisticTableGUI();
243 $completeTableGUI->setData($completeData);
244
245 $content = $this->ctrl->getHTML($toolbarGUI);
246 $content .= $this->ctrl->getHTML($filteredTableGUI);
247 $content .= $this->ctrl->getHTML($completeTableGUI);
248
249 $this->tpl->setVariable('TABLE_LIST_OF_QUESTIONS', $content);
250
251 if( $this->object->getEnableProcessingTime() )
252 {
253 $this->outProcessingTime($this->testSession->getActiveId());
254 }
255 }
256
257 protected function filterQuestionSelectionCmd()
258 {
260 $tableGUI->writeFilterToSession();
261
262 $taxFilterSelection = array();
263 $answerStatusFilterSelection = ilAssQuestionList::ANSWER_STATUS_FILTER_ALL_NON_CORRECT;
264
265 foreach( $tableGUI->getFilterItems() as $item )
266 {
267 if( strpos($item->getPostVar(), 'tax_') !== false )
268 {
269 $taxId = substr( $item->getPostVar(), strlen('tax_') );
270 $taxFilterSelection[$taxId] = $item->getValue();
271 }
272 elseif( $item->getPostVar() == 'question_answer_status' )
273 {
274 $answerStatusFilterSelection = $item->getValue();
275 }
276 }
277
278 $this->testSession->getQuestionSetFilterSelection()->setTaxonomySelection($taxFilterSelection);
279 $this->testSession->getQuestionSetFilterSelection()->setAnswerStatusSelection($answerStatusFilterSelection);
280 $this->testSession->saveToDb();
281
282 $this->testSequence->resetTrackedQuestionList();
283 $this->testSequence->saveToDb();
284
285 $this->ctrl->redirect($this, 'showQuestionSelection');
286 }
287
288 protected function resetQuestionSelectionCmd()
289 {
291 $tableGUI->resetFilter();
292
293 $this->testSession->getQuestionSetFilterSelection()->setTaxonomySelection( array() );
294 $this->testSession->getQuestionSetFilterSelection()->setAnswerStatusSelection( null );
295 $this->testSession->saveToDb();
296
297 $this->testSequence->resetTrackedQuestionList();
298 $this->testSequence->saveToDb();
299
300 $this->ctrl->redirect($this, 'showQuestionSelection');
301 }
302
303 protected function showTrackedQuestionListCmd()
304 {
305 if( !$this->dynamicQuestionSetConfig->isPreviousQuestionsListEnabled() )
306 {
307 $this->ctrl->redirect($this, self::CMD_SHOW_QUESTION);
308 }
309
310 $this->prepareSummaryPage();
311
312 $questionId = $this->testSession->getCurrentQuestionId();
313
314 if( $questionId && !$this->isParticipantsAnswerFixed($questionId) )
315 {
316 $this->updateWorkingTime();
317 $this->saveQuestionSolution();
319
320 $this->testSequence->unsetQuestionPostponed($questionId);
321 }
322
323 $this->testSequence->loadQuestions(
324 $this->dynamicQuestionSetConfig, $this->testSession->getQuestionSetFilterSelection()
325 );
326
327 $this->testSequence->cleanupQuestions($this->testSession);
328
329 $this->testSequence->saveToDb();
330
332 $this->testSequence->getTrackedQuestionList( $this->testSession->getCurrentQuestionId() ),
333 $this->getMarkedQuestions()
334 );
335
336 include_once "./Modules/Test/classes/tables/class.ilTrackedQuestionsTableGUI.php";
337 $table_gui = new ilTrackedQuestionsTableGUI(
338 $this, 'showTrackedQuestionList', $this->object->getSequenceSettings(), $this->object->getShowMarker()
339 );
340
341 $table_gui->setData($data);
342
343 $this->tpl->setVariable('TABLE_LIST_OF_QUESTIONS', $table_gui->getHTML());
344
345 if( $this->object->getEnableProcessingTime() )
346 {
347 $this->outProcessingTime($this->testSession->getActiveId());
348 }
349 }
350
351 protected function previousQuestionCmd()
352 {
353
354 }
355
356 protected function fromPassDeletionCmd()
357 {
358 $this->resetCurrentQuestion();
359 $this->ctrl->redirect($this, 'showQuestion');
360 }
361
362 protected function nextQuestionCmd()
363 {
364 $questionId = $this->testSession->getCurrentQuestionId();
365
366 if( $questionId && !$this->isParticipantsAnswerFixed($questionId) )
367 {
368 $this->updateWorkingTime();
369 $this->saveQuestionSolution();
371
372 $this->testSequence->unsetQuestionPostponed($questionId);
373 $this->testSequence->saveToDb();
374 }
375
376 $this->resetCurrentQuestion();
377
378 $this->ctrl->redirect($this, 'showQuestion');
379 }
380
381 protected function postponeQuestionCmd()
382 {
383 $questionId = $this->testSession->getCurrentQuestionId();
384
385 if( $questionId && !$this->isParticipantsAnswerFixed($questionId) )
386 {
387 $this->updateWorkingTime();
388 $this->saveQuestionSolution();
390
391 $this->testSequence->setQuestionPostponed($questionId);
392 }
393
394 $this->testSession->setCurrentQuestionId(null);
395
396 $this->testSequence->saveToDb();
397 $this->testSession->saveToDb();
398
399 $this->ctrl->redirect($this, 'showQuestion');
400 }
401
402 protected function markQuestionCmd()
403 {
404 $questionId = $this->testSession->getCurrentQuestionId();
405
406 if( $questionId && !$this->isParticipantsAnswerFixed($questionId) )
407 {
408 $this->updateWorkingTime();
409 $this->saveQuestionSolution();
411
412 $this->testSequence->unsetQuestionPostponed($questionId);
413 $this->testSequence->saveToDb();
414 }
415
416 global $ilUser;
417 $this->object->setQuestionSetSolved(1, $this->testSession->getCurrentQuestionId(), $ilUser->getId());
418
419 $this->ctrl->redirect($this, 'showQuestion');
420 }
421
422 protected function unmarkQuestionCmd()
423 {
424 $questionId = $this->testSession->getCurrentQuestionId();
425
426 if( $questionId && !$this->isParticipantsAnswerFixed($questionId) )
427 {
428 $this->updateWorkingTime();
429 $this->saveQuestionSolution();
431
432 $this->testSequence->unsetQuestionPostponed($questionId);
433 $this->testSequence->saveToDb();
434 }
435
436 global $ilUser;
437 $this->object->setQuestionSetSolved(0, $this->testSession->getCurrentQuestionId(), $ilUser->getId());
438
439 $this->ctrl->redirect($this, 'showQuestion');
440 }
441
442 protected function gotoQuestionCmd()
443 {
444 $this->testSequence->loadQuestions(
445 $this->dynamicQuestionSetConfig, $this->testSession->getQuestionSetFilterSelection()
446 );
447
448 $this->testSequence->cleanupQuestions($this->testSession);
449
450 if( isset($_GET['sequence']) && (int)$_GET['sequence'] )
451 {
452 $this->testSession->setCurrentQuestionId( (int)$_GET['sequence'] );
453 $this->testSession->saveToDb();
454
455 $this->ctrl->setParameter(
456 $this, 'sequence', $this->testSession->getCurrentQuestionId()
457 );
458 }
459
460 $this->ctrl->redirect($this, 'showQuestion');
461 }
462
463 protected function showQuestionCmd()
464 {
466
467 $this->testSequence->loadQuestions(
468 $this->dynamicQuestionSetConfig, $this->testSession->getQuestionSetFilterSelection()
469 );
470
471 $this->testSequence->cleanupQuestions($this->testSession);
472
473 if( !$this->testSession->getCurrentQuestionId() )
474 {
475 $upComingQuestionId = $this->testSequence->getUpcomingQuestionId();
476
477 $this->testSession->setCurrentQuestionId($upComingQuestionId);
478
479 if( $this->testSequence->isQuestionChecked($upComingQuestionId) )
480 {
481 $this->testSequence->setQuestionUnchecked($upComingQuestionId);
482 }
483 }
484
485 if( $this->testSession->getCurrentQuestionId() )
486 {
487 $this->ctrl->setParameter(
488 $this, 'sequence', $this->testSession->getCurrentQuestionId()
489 );
490
491 $this->outTestPage(false);
492 }
493 else
494 {
496 }
497
498 $this->testSequence->saveToDb();
499 $this->testSession->saveToDb();
500 }
501
502 protected function showInstantResponseCmd()
503 {
504 $questionId = $this->testSession->getCurrentQuestionId();
505
506 if( $questionId && !$this->isParticipantsAnswerFixed($questionId) )
507 {
508 $this->updateWorkingTime();
509 $this->saveQuestionSolution();
511
512 $this->testSequence->unsetQuestionPostponed($questionId);
513 $this->testSequence->setQuestionChecked($questionId);
514 }
515
517
518 $filterSelection = $this->testSession->getQuestionSetFilterSelection();
519
520 $filterSelection->setForcedQuestionIds(array($this->testSession->getCurrentQuestionId()));
521
522 $this->testSequence->loadQuestions($this->dynamicQuestionSetConfig, $filterSelection);
523
524 $this->testSequence->cleanupQuestions($this->testSession);
525
526 $this->ctrl->setParameter(
527 $this, 'sequence', $this->testSession->getCurrentQuestionId()
528 );
529
530 $this->outTestPage(true);
531
532 $this->testSequence->saveToDb();
533 $this->testSession->saveToDb();
534 }
535
536 protected function handleQuestionActionCmd()
537 {
538 $questionId = $this->testSession->getCurrentQuestionId();
539
540 if( $questionId && !$this->isParticipantsAnswerFixed($questionId) )
541 {
542 $this->updateWorkingTime();
543 $this->saveQuestionSolution();
545
546 $this->testSequence->unsetQuestionPostponed($questionId);
547 $this->testSequence->saveToDb();
548 }
549
550 $this->ctrl->setParameter(
551 $this, 'sequence', $this->testSession->getCurrentQuestionId()
552 );
553
554 $this->ctrl->redirect($this, 'showQuestion');
555 }
556
560 protected function outWorkingForm($sequence = "", $test_id, $postpone_allowed, $directfeedback = false)
561 {
562 global $ilUser;
563
564 $_SESSION["active_time_id"] = $this->object->startWorkingTime(
565 $this->testSession->getActiveId(), $this->testSession->getPass()
566 );
567
570
571 $question_gui = $this->object->createQuestionGUI(
572 "", $this->testSession->getCurrentQuestionId()
573 );
574
575 if( !is_object($question_gui) )
576 {
577 global $ilLog;
578
579 $ilLog->write(
580 "INV SEQ: active={$this->testSession->getActiveId()} qId={$this->testSession->getCurrentQuestionId()} "
581 .serialize($this->testSequence)
582 );
583
584 $ilLog->logStack('INV SEQ');
585
586 $this->resetCurrentQuestion();
587 $this->ctrl->redirect($this, 'showQuestion');
588 }
589
590 $question_gui->setTargetGui($this);
591
592 $question_gui->setQuestionCount(
593 $this->testSequence->getLastPositionIndex()
594 );
595 $question_gui->setSequenceNumber( $this->testSequence->getCurrentPositionIndex(
596 $this->testSession->getCurrentQuestionId()
597 ));
598
599 $this->ctrl->setParameter($this, 'sequence', $this->testSession->getCurrentQuestionId());
600
601 if ($this->object->getJavaScriptOutput())
602 {
603 $question_gui->object->setOutputType(OUTPUT_JAVASCRIPT);
604 }
605
606 $is_postponed = $this->testSequence->isPostponedQuestion($question_gui->object->getId());
607 $formaction = $this->ctrl->getFormAction($this);
608
609 // output question
610 $user_post_solution = FALSE;
611 if( isset($_SESSION['previouspost']) )
612 {
613 $user_post_solution = $_SESSION['previouspost'];
614 unset($_SESSION['previouspost']);
615 }
616
617 global $ilNavigationHistory;
618 $ilNavigationHistory->addItem($_GET["ref_id"], $this->ctrl->getLinkTarget($this, "resumePlayer"), "tst");
619
620 // Determine $answer_feedback: It should hold a boolean stating if answer-specific-feedback is to be given.
621 // It gets the parameter "Scoring and Results" -> "Instant Feedback" -> "Show Answer-Specific Feedback"
622 // $directfeedback holds a boolean stating if the instant feedback was requested using the "Check" button.
623 $answer_feedback = FALSE;
624 if (($directfeedback) && ($this->object->getSpecificAnswerFeedback()))
625 {
626 $answer_feedback = TRUE;
627 }
628
629 if( $this->isParticipantsAnswerFixed($this->testSession->getCurrentQuestionId()) )
630 {
631 $solutionoutput = $question_gui->getSolutionOutput(
632 $this->testSession->getActiveId(), #active_id
633 NULL, #pass
634 FALSE, #graphical_output
635 false, #result_output
636 true, #show_question_only
637 $answer_feedback, #show_feedback
638 false, #show_correct_solution
639 FALSE, #show_manual_scoring
640 true #show_question_text
641 );
642
643 $pageoutput = $question_gui->outQuestionPage(
644 "", $this->testSequence->isPostponedQuestion($this->testSession->getCurrentQuestionId()),
645 $this->testSession->getActiveId(),
646 $solutionoutput
647 );
648
649 $this->tpl->setVariable("QUESTION_OUTPUT", $pageoutput);
650 $this->tpl->setVariable("FORMACTION", $formaction);
651
652 $directfeedback = true;
653 }
654 else
655 {
656 // Answer specific feedback is rendered into the display of the test question with in the concrete question types outQuestionForTest-method.
657 // Notation of the params prior to getting rid of this crap in favor of a class
658 $question_gui->outQuestionForTest(
659 $formaction, #form_action
660 $this->testSession->getActiveId(), #active_id
661 NULL, #pass
662 $is_postponed, #is_postponed
663 $user_post_solution, #user_post_solution
664 $answer_feedback #answer_feedback == inline_specific_feedback
665 );
666 // The display of specific inline feedback and specific feedback in an own block is to honor questions, which
667 // have the possibility to embed the specific feedback into their output while maintaining compatibility to
668 // questions, which do not have such facilities. E.g. there can be no "specific inline feedback" for essay
669 // questions, while the multiple-choice questions do well.
670
671 $this->fillQuestionRelatedNavigation($question_gui);
672 }
673
674 if ($directfeedback)
675 {
676 // This controls if the solution should be shown.
677 // It gets the parameter "Scoring and Results" -> "Instant Feedback" -> "Show Solutions"
678 if ($this->object->getInstantFeedbackSolution())
679 {
680 $show_question_inline_score = $this->determineInlineScoreDisplay();
681
682 // Notation of the params prior to getting rid of this crap in favor of a class
683 $solutionoutput = $question_gui->getSolutionOutput(
684 $this->testSession->getActiveId(), #active_id
685 NULL, #pass
686 TRUE, #graphical_output
687 $show_question_inline_score, #result_output
688 FALSE, #show_question_only
689 FALSE, #show_feedback
690 TRUE, #show_correct_solution
691 FALSE, #show_manual_scoring
692 FALSE #show_question_text
693 );
694 $this->populateSolutionBlock( $solutionoutput );
695 }
696
697 // This controls if the score should be shown.
698 // It gets the parameter "Scoring and Results" -> "Instant Feedback" -> "Show Results (Only Points)"
699 if ($this->object->getAnswerFeedbackPoints())
700 {
701 $reachedPoints = $question_gui->object->getAdjustedReachedPoints($this->testSession->getActiveId(), NULL);
702 $maxPoints = $question_gui->object->getMaximumPoints();
703
704 $this->populateScoreBlock( $reachedPoints, $maxPoints );
705 }
706
707 // This controls if the generic feedback should be shown.
708 // It gets the parameter "Scoring and Results" -> "Instant Feedback" -> "Show Solutions"
709 if ($this->object->getGenericAnswerFeedback())
710 {
711 $this->populateGenericFeedbackBlock( $question_gui );
712 }
713
714 // This controls if the specific feedback should be shown.
715 // It gets the parameter "Scoring and Results" -> "Instant Feedback" -> "Show Answer-Specific Feedback"
716 if ($this->object->getSpecificAnswerFeedback())
717 {
718 $this->populateSpecificFeedbackBlock( $question_gui );
719 }
720 }
721
722 $this->populatePreviousButtons( $this->testSession->getCurrentQuestionId() );
723
724 if( $postpone_allowed )
725 {
727 }
728
729 if ($this->object->getShowCancel())
730 {
732 }
733
734 if ($this->isLastQuestionInSequence( $question_gui ))
735 {
736 if ($this->object->getListOfQuestionsEnd())
737 {
739 }
740 else
741 {
743 }
744 }
745 else
746 {
748 }
749
750 if( $this->dynamicQuestionSetConfig->isAnyQuestionFilterEnabled() )
751 {
753 }
754
755 if ($this->object->getShowMarker())
756 {
757 include_once "./Modules/Test/classes/class.ilObjTest.php";
758 $solved_array = ilObjTest::_getSolvedQuestions($this->testSession->getActiveId(), $question_gui->object->getId());
759 $solved = 0;
760
761 if (count ($solved_array) > 0)
762 {
763 $solved = array_pop($solved_array);
764 $solved = $solved["solved"];
765 }
766
767 if ($solved==1)
768 {
770 }
771 else
772 {
774 }
775 }
776
777 $this->populateCharSelector();
778
779 if ($this->object->getJavaScriptOutput())
780 {
781 $this->tpl->setVariable("JAVASCRIPT_TITLE", $this->lng->txt("disable_javascript"));
782 $this->ctrl->setParameter($this, "tst_javascript", "0");
783 $this->tpl->setVariable("JAVASCRIPT_URL", $this->ctrl->getLinkTarget($this, "gotoQuestion"));
784 }
785 else
786 {
787 $this->tpl->setVariable("JAVASCRIPT_TITLE", $this->lng->txt("enable_javascript"));
788 $this->ctrl->setParameter($this, "tst_javascript", "1");
789 $this->tpl->setVariable("JAVASCRIPT_URL", $this->ctrl->getLinkTarget($this, "gotoQuestion"));
790 }
791
792 if ($question_gui->object->supportsJavascriptOutput())
793 {
794 $this->tpl->touchBlock("jsswitch");
795 }
796
797 $this->tpl->addJavaScript(ilUtil::getJSLocation("autosave.js", "Modules/Test"));
798
799 $this->tpl->setVariable("AUTOSAVE_URL", $this->ctrl->getFormAction($this, "autosave", "", true));
800
801 if ($question_gui->isAutosaveable()&& $this->object->getAutosave())
802 {
803 $this->tpl->touchBlock('autosave');
804 //$this->tpl->setVariable("BTN_SAVE", "Zwischenspeichern");
805 //$this->tpl->setVariable("CMD_SAVE", "gotoquestion_{$sequence}");
806 //$this->tpl->setVariable("AUTOSAVEFORMACTION", str_replace("&amp;", "&", $this->ctrl->getFormAction($this)));
807 $this->tpl->setVariable("AUTOSAVEFORMACTION", str_replace("&amp;", "&", $this->ctrl->getLinkTarget($this, "autosave")));
808 $this->tpl->setVariable("AUTOSAVEINTERVAL", $this->object->getAutosaveIval());
809 }
810
811 if( $this->object->areObligationsEnabled() && ilObjTest::isQuestionObligatory($question_gui->object->getId()) )
812 {
813 $this->tpl->touchBlock('question_obligatory');
814 $this->tpl->setVariable('QUESTION_OBLIGATORY', $this->lng->txt('required_field'));
815 }
816 }
817
818 private function outCurrentlyFinishedPage()
819 {
820 $this->prepareTestPageOutput();
821
822 $this->populatePreviousButtons( $this->testSession->getCurrentQuestionId() );
823
824 if ($this->object->getKioskMode())
825 {
826 $this->populateKioskHead();
827 }
828
829 if ($this->object->getEnableProcessingTime())
830 {
831 $this->outProcessingTime($this->testSession->getActiveId());
832 }
833
834 $this->tpl->setVariable("FORMACTION", $this->ctrl->getFormAction($this));
835 $this->tpl->setVariable("FORM_TIMESTAMP", time());
836
837 $this->tpl->setVariable("PAGETITLE", "- " . $this->object->getTitle());
838
839 if ($this->object->isShowExamIdInTestPassEnabled() && !$this->object->getKioskMode())
840 {
841 $this->tpl->setCurrentBlock('exam_id');
842 $this->tpl->setVariable('EXAM_ID', ilObjTest::lookupExamId(
843 $this->testSession->getActiveId(), $this->testSession->getPass(), $this->object->getId()
844 ));
845 $this->tpl->setVariable('EXAM_ID_TXT', $this->lng->txt('exam_id'));
846 $this->tpl->parseCurrentBlock();
847 }
848
849 if ($this->object->getShowCancel())
850 {
852 }
853
854 if( $this->dynamicQuestionSetConfig->isAnyQuestionFilterEnabled() )
855 {
857 }
858
859 if( $this->testSequence->openQuestionExists() )
860 {
861 $message = $this->lng->txt('tst_dyn_test_msg_currently_finished_selection');
862 }
863 else
864 {
865 $message = $this->lng->txt('tst_dyn_test_msg_currently_finished_completely');
866 $message .= "<br /><br />{$this->buildFinishPagePassDeletionLink()}";
867 }
868
869 $msgHtml = $this->tpl->getMessageHTML($message);
870
871 $this->tpl->addBlockFile(
872 'QUESTION_OUTPUT', 'test_currently_finished_msg_block',
873 'tpl.test_currently_finished_msg.html', 'Modules/Test'
874 );
875
876 $this->tpl->setCurrentBlock('test_currently_finished_msg_block');
877 $this->tpl->setVariable('TEST_CURRENTLY_FINISHED_MSG', $msgHtml);
878 $this->tpl->parseCurrentBlock();
879
880 }
881
883 {
884 return !$this->testSequence->trackedQuestionExists();
885 }
886
887 protected function isLastQuestionInSequence(assQuestionGUI $questionGUI)
888 {
889 return false; // always
890 }
891
893 {
894 global $ilUser;
895
896 if( isset($_GET['tst_javascript']) )
897 {
898 $ilUser->writePref('tst_javascript', $_GET['tst_javascript']);
899 }
900 }
901
907 protected function canSaveResult()
908 {
909 return !$this->object->endingTimeReached();
910 }
911
915 public function saveQuestionSolution($force = FALSE)
916 {
917 // what is this formtimestamp ??
918 if (!$force)
919 {
920 $formtimestamp = $_POST["formtimestamp"];
921 if (strlen($formtimestamp) == 0) $formtimestamp = $_GET["formtimestamp"];
922 if ($formtimestamp != $_SESSION["formtimestamp"])
923 {
924 $_SESSION["formtimestamp"] = $formtimestamp;
925 }
926 else
927 {
928 return FALSE;
929 }
930 }
931
932 // determine current question
933
934 $qId = $this->testSession->getCurrentQuestionId();
935
936 if( !$qId || $qId != $_GET["sequence"])
937 {
938 return false;
939 }
940
941 // save question solution
942
943 $this->saveResult = FALSE;
944
945 if ($this->canSaveResult($qId) || $force)
946 {
947 global $ilUser;
948
949 $questionGUI = $this->object->createQuestionGUI("", $qId);
950
951 if( $this->object->getJavaScriptOutput() )
952 {
953 $questionGUI->object->setOutputType(OUTPUT_JAVASCRIPT);
954 }
955
956 $activeId = $this->testSession->getActiveId();
957
958 $this->saveResult = $questionGUI->object->persistWorkingState(
959 $activeId, $pass = null, $this->object->areObligationsEnabled()
960 );
961 }
962
963 if ($this->saveResult == FALSE)
964 {
965 $this->ctrl->setParameter($this, "save_error", "1");
966 $_SESSION["previouspost"] = $_POST;
967 }
968
969 return $this->saveResult;
970 }
971
972 private function isQuestionAnsweredCorrect($questionId, $activeId, $pass)
973 {
974 $questionGUI = $this->object->createQuestionGUI("", $questionId);
975
976 $reachedPoints = assQuestion::_getReachedPoints($activeId, $questionId, $pass);
977 $maxPoints = $questionGUI->object->getMaximumPoints();
978
979 if($reachedPoints < $maxPoints)
980 {
981 return false;
982 }
983
984 return true;
985 }
986
987
989 {
990 if( !$this->dynamicQuestionSetConfig->isPreviousQuestionsListEnabled() )
991 {
992 return;
993 }
994
995 if( $this->isFirstPageInSequence($sequence) )
996 {
997 return;
998 }
999
1001 'showTrackedQuestionList', "&lt;&lt; " . $this->lng->txt( "save_previous" )
1002 );
1004 'showTrackedQuestionList', "&lt;&lt; " . $this->lng->txt( "save_previous" )
1005 );
1006 }
1007
1008 protected function buildQuestionsTableDataArray($questions, $marked_questions)
1009 {
1010 $data = array();
1011
1012 foreach($questions as $key => $value )
1013 {
1014 $this->ctrl->setParameter($this, 'sequence', $value['question_id']);
1015 $href = $this->ctrl->getLinkTarget($this, 'gotoQuestion');
1016 $this->ctrl->setParameter($this, 'sequence', '');
1017
1018 $description = "";
1019 if( $this->object->getListOfQuestionsDescription() )
1020 {
1021 $description = $value["description"];
1022 }
1023
1024 $marked = false;
1025 if( count($marked_questions) )
1026 {
1027 if( isset($marked_questions[$value["question_id"]]) )
1028 {
1029 if( $marked_questions[$value["question_id"]]["solved"] == 1 )
1030 {
1031 $marked = true;
1032 }
1033 }
1034 }
1035
1036 array_push($data, array(
1037 'href' => $href,
1038 'title' => $this->object->getQuestionTitle($value["title"]),
1039 'description' => $description,
1040 'worked_through' => $this->testSequence->isAnsweredQuestion($value["question_id"]),
1041 'postponed' => $this->testSequence->isPostponedQuestion($value["question_id"]),
1042 'marked' => $marked
1043 ));
1044 }
1045
1046 return $data;
1047 }
1048
1049 protected function buildQuestionSetAnswerStatisticRowArray($questions, $marked_questions)
1050 {
1051 $questionAnswerStats = array(
1052 'total_all' => count($questions),
1053 'total_open' => 0,
1054 'non_answered' => 0,
1055 'wrong_answered' => 0,
1056 'correct_answered' => 0,
1057 'postponed' => 0,
1058 'marked' => 0
1059 );
1060
1061 foreach($questions as $key => $value )
1062 {
1063 switch( $value['question_answer_status'] )
1064 {
1066 $questionAnswerStats['non_answered']++;
1067 $questionAnswerStats['total_open']++;
1068 break;
1070 $questionAnswerStats['wrong_answered']++;
1071 $questionAnswerStats['total_open']++;
1072 break;
1074 $questionAnswerStats['correct_answered']++;
1075 break;
1076 }
1077
1078 if( $this->testSequence->isPostponedQuestion($value["question_id"]) )
1079 {
1080 $questionAnswerStats['postponed']++;
1081 }
1082
1083 if( isset($marked_questions[$value["question_id"]]) )
1084 {
1085 if( $marked_questions[$value["question_id"]]["solved"] == 1 )
1086 {
1087 $questionAnswerStats['marked']++;
1088 }
1089 }
1090 }
1091
1092 return $questionAnswerStats;
1093 }
1094
1096 {
1097 require_once 'Modules/Test/classes/tables/class.ilTestDynamicQuestionSetStatisticTableGUI.php';
1100 );
1101
1102 $gui->initTitle('tst_dynamic_question_set_complete');
1103 $gui->initColumns('tst_num_all_questions');
1104
1105 return $gui;
1106 }
1107
1109 {
1110 require_once 'Modules/Test/classes/tables/class.ilTestDynamicQuestionSetStatisticTableGUI.php';
1113 );
1114
1115 $gui->initTitle('tst_dynamic_question_set_selection');
1116 $gui->initColumns('tst_num_selected_questions');
1117
1118 require_once 'Services/Taxonomy/classes/class.ilObjTaxonomy.php';
1119 $gui->setTaxIds(ilObjTaxonomy::getUsageOfObject(
1120 $this->dynamicQuestionSetConfig->getSourceQuestionPoolId()
1121 ));
1122
1123 $gui->setTaxonomyFilterEnabled($this->dynamicQuestionSetConfig->isTaxonomyFilterEnabled());
1124 $gui->setAnswerStatusFilterEnabled($this->dynamicQuestionSetConfig->isAnswerStatusFilterEnabled());
1125
1126 $gui->setFilterSelection($this->testSession->getQuestionSetFilterSelection());
1127 $gui->initFilter();
1128 $gui->setFilterCommand('filterQuestionSelection');
1129 $gui->setResetCommand('resetQuestionSelection');
1130
1131 return $gui;
1132 }
1133
1134 private function buildQuestionSetStatisticTableGUI($tableId)
1135 {
1136 require_once 'Modules/Test/classes/tables/class.ilTestDynamicQuestionSetStatisticTableGUI.php';
1138 $this->ctrl, $this->lng, $this, 'showQuestionSelection', $tableId
1139 );
1140
1141 $gui->setShowNumMarkedQuestionsEnabled($this->object->getShowMarker());
1142 $gui->setShowNumPostponedQuestionsEnabled($this->object->getSequenceSettings());
1143
1144 return $gui;
1145 }
1146
1147 private function getEnterTestButtonLangVar()
1148 {
1149 if( $this->testSequence->trackedQuestionExists() )
1150 {
1151 return $this->lng->txt('tst_resume_dyn_test_with_cur_quest_sel');
1152 }
1153
1154 return $this->lng->txt('tst_start_dyn_test_with_cur_quest_sel');
1155 }
1156
1157 protected function persistQuestionAnswerStatus()
1158 {
1159 $questionId = $this->testSession->getCurrentQuestionId();
1160 $activeId = $this->testSession->getActiveId();
1161 $pass = $this->testSession->getPass();
1162
1163 if($this->isQuestionAnsweredCorrect($questionId, $activeId, $pass))
1164 {
1165 $this->testSequence->setQuestionAnsweredCorrect($questionId);
1166 }
1167 else
1168 {
1169 $this->testSequence->setQuestionAnsweredWrong($questionId);
1170 }
1171 }
1172
1173 private function resetCurrentQuestion()
1174 {
1175 $this->testSession->setCurrentQuestionId(null);
1176
1177 $this->testSequence->saveToDb();
1178 $this->testSession->saveToDb();
1179
1180 $this->ctrl->setParameter($this, 'sequence', $this->testSession->getCurrentQuestionId());
1181 }
1182
1187 {
1188 $href = $this->getPassDeletionTarget();
1189
1190 $label = $this->lng->txt('tst_dyn_test_msg_pass_deletion_link');
1191
1192 return "<a href=\"{$href}\">{$label}</a>";
1193 }
1194
1198 private function getPassDeletionTarget()
1199 {
1200 require_once 'Modules/Test/classes/confirmations/class.ilTestPassDeletionConfirmationGUI.php';
1201
1202 $this->ctrl->setParameterByClass('ilTestEvaluationGUI', 'context', ilTestPassDeletionConfirmationGUI::CONTEXT_DYN_TEST_PLAYER);
1203 $this->ctrl->setParameterByClass('ilTestEvaluationGUI', 'active_id', $this->testSession->getActiveId());
1204 $this->ctrl->setParameterByClass('ilTestEvaluationGUI', 'pass', $this->testSession->getPass());
1205
1206 return $this->ctrl->getLinkTargetByClass('ilTestEvaluationGUI', 'confirmDeletePass');
1207 }
1208}
$_GET["client_id"]
Basic GUI class for assessment questions.
_getReachedPoints($active_id, $question_id, $pass=NULL)
Returns the points, a learner has reached answering the question.
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.
static getUsageOfObject($a_obj_id, $a_include_titles=false)
Get usage of object.
_getSolvedQuestions($active_id, $question_fi=null)
get solved questions
lookupExamId($active_id, $pass)
static isQuestionObligatory($question_id)
checks wether the question with given id is marked as obligatory or not
static initJavascript()
Init javascript.
Output class for assessment test execution.
fillQuestionRelatedNavigation(assQuestionGUI $questionGUI)
renders the elements for the question related navigation
calculateSequence()
Calculates the sequence to determine the next question.
ensureExistingTestSession(ilTestSession $testSession)
populateScoreBlock($reachedPoints, $maxPoints)
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.
outTestPage($directfeedback)
Outputs the question of the active sequence.
outWorkingForm($sequence="", $test_id, $postpone_allowed, $directfeedback=false)
Creates the learners output of a question.
canSaveResult()
Returns TRUE if the answers of the current user could be saved.
resumePlayerCmd()
Resume a test at the last position.
gotoQuestionCmd()
Go to the question with the active sequence.
buildQuestionSetAnswerStatisticRowArray($questions, $marked_questions)
saveQuestionSolution($force=FALSE)
saves the user input of a question
static getJSLocation($a_js_name, $a_js_location="", $add_version=FALSE)
get full javascript file name (path inclusive) of current user
static initConnectionWithAnimation()
Init YUI Connection module.
static initjQuery($a_tpl=null)
Init jQuery.
$_POST['username']
Definition: cron.php:12
< a tabindex="-1" style="border-style: none;" href="#" title="Refresh Image" onclick="document.getElementById('siimage').src = './securimage_show.php?sid=' + Math.random(); this.blur(); return false">< img src="./images/refresh.png" alt="Reload Image" height="32" width="32" onclick="this.blur()" align="bottom" border="0"/></a >< br/>< strong > Enter Code *if($_SERVER['REQUEST_METHOD']=='POST' &&@ $_POST['do']=='contact') $_SESSION['ctform']['success']
const OUTPUT_JAVASCRIPT
vd()
shortcut for var_dump with enhanced debug information
Definition: inc.debug.php:42
$cmd
Definition: sahs_server.php:35
global $ilDB
global $ilUser
Definition: imgupload.php:15