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