ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
class.ilTestOutputGUI.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 
21 {
26 
30  public function executeCommand()
31  {
32  global $ilDB, $ilPluginAdmin, $lng, $ilTabs;
33 
34  $this->checkReadAccess();
35 
36  $ilTabs->clearTargets();
37 
38  $cmd = $this->ctrl->getCmd();
39  $next_class = $this->ctrl->getNextClass($this);
40 
41  $this->ctrl->saveParameter($this, "sequence");
42  $this->ctrl->saveParameter($this, "pmode");
43  $this->ctrl->saveParameter($this, "active_id");
44 
45  $this->initAssessmentSettings();
46 
47  $testSessionFactory = new ilTestSessionFactory($this->object);
48  $this->testSession = $testSessionFactory->getSession($_GET['active_id']);
49 
50  $this->ensureExistingTestSession($this->testSession);
51  $this->checkTestSessionUser($this->testSession);
52 
53  $this->initProcessLocker($this->testSession->getActiveId());
54 
55  $testSequenceFactory = new ilTestSequenceFactory($ilDB, $lng, $ilPluginAdmin, $this->object);
56  $this->testSequence = $testSequenceFactory->getSequenceByTestSession($this->testSession);
57  $this->testSequence->loadFromDb();
58  $this->testSequence->loadQuestions();
59 
60  require_once 'Modules/Test/classes/class.ilTestQuestionRelatedObjectivesList.php';
61  $this->questionRelatedObjectivesList = new ilTestQuestionRelatedObjectivesList();
62 
63  include_once 'Services/jQuery/classes/class.iljQueryUtil.php';
65  include_once "./Services/YUI/classes/class.ilYuiUtil.php";
67 
69 
70  $cmd = $this->getCommand($cmd);
71 
72  switch($next_class)
73  {
74  case 'ilassquestionpagegui':
75 
76  $this->checkTestExecutable();
77 
78  $questionId = $this->testSequence->getQuestionForSequence($this->getCurrentSequenceElement());
79 
80  require_once "./Modules/TestQuestionPool/classes/class.ilAssQuestionPageGUI.php";
81  $page_gui = new ilAssQuestionPageGUI($questionId);
82  $ret = $this->ctrl->forwardCommand($page_gui);
83  break;
84 
85  case 'iltestsubmissionreviewgui':
86 
87  $this->checkTestExecutable();
88 
89  require_once './Modules/Test/classes/class.ilTestSubmissionReviewGUI.php';
90  $gui = new ilTestSubmissionReviewGUI($this, $this->object, $this->testSession);
91  $gui->setObjectiveOrientedContainer($this->getObjectiveOrientedContainer());
92  $ret = $this->ctrl->forwardCommand($gui);
93  break;
94 
95  case 'ilassquestionhintrequestgui':
96 
97  $this->checkTestExecutable();
98 
99  $questionGUI = $this->object->createQuestionGUI(
100  "", $this->testSequence->getQuestionForSequence($this->getCurrentSequenceElement())
101  );
102 
103  require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionHintTracking.php';
104  $questionHintTracking = new ilAssQuestionHintTracking(
105  $questionGUI->object->getId(), $this->testSession->getActiveId(), $this->testSession->getPass()
106  );
107 
108  require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionHintRequestGUI.php';
109  $gui = new ilAssQuestionHintRequestGUI($this, ilTestPlayerCommands::SHOW_QUESTION, $questionGUI, $questionHintTracking);
110 
111 // fau: testNav - save the 'answer changed' status for viewing hint requests
113 // fau.
114  $ret = $this->ctrl->forwardCommand($gui);
115 
116  break;
117 
118  case 'iltestsignaturegui':
119 
120  $this->checkTestExecutable();
121 
122  require_once './Modules/Test/classes/class.ilTestSignatureGUI.php';
123  $gui = new ilTestSignatureGUI($this);
124  $ret = $this->ctrl->forwardCommand($gui);
125  break;
126 
127  case 'iltestpasswordprotectiongui':
128 
129  $this->checkTestExecutable();
130 
131  require_once 'Modules/Test/classes/class.ilTestPasswordProtectionGUI.php';
132  $gui = new ilTestPasswordProtectionGUI($this->ctrl, $this->tpl, $this->lng, $this, $this->passwordChecker);
133  $ret = $this->ctrl->forwardCommand($gui);
134  break;
135 
136  default:
137 
139  {
140  $this->checkTestExecutable();
141  }
142 
143  $cmd .= 'Cmd';
144  $ret =& $this->$cmd();
145  break;
146  }
147  return $ret;
148  }
149 
150  protected function startTestCmd()
151  {
152  global $ilUser;
153 
154  $_SESSION['tst_pass_finish'] = 0;
155 
156  // ensure existing test session
157  $this->testSession->setUserId($ilUser->getId());
158  $this->testSession->setAnonymousId($_SESSION["tst_access_code"][$this->object->getTestId()]);
159  $this->testSession->setObjectiveOrientedContainerId($this->getObjectiveOrientedContainer()->getObjId());
160  $this->testSession->saveToDb();
161 
162  $active_id = $this->testSession->getActiveId();
163  $this->ctrl->setParameter($this, "active_id", $active_id);
164 
165  $shuffle = $this->object->getShuffleQuestions();
166  if ($this->object->isRandomTest())
167  {
169 
170  $this->object->loadQuestions();
171  $shuffle = FALSE; // shuffle is already done during the creation of the random questions
172  }
173 
174  assQuestion::_updateTestPassResults(
175  $active_id, $this->testSession->getPass(), $this->object->areObligationsEnabled(), null, $this->object->id
176  );
177 
178  // ensure existing test sequence
179  if( !$this->testSequence->hasSequence() )
180  {
181  $this->testSequence->createNewSequence($this->object->getQuestionCount(), $shuffle);
182  $this->testSequence->saveToDb();
183  }
184 
185  $this->testSequence->loadFromDb();
186  $this->testSequence->loadQuestions();
187 
188  if( $this->testSession->isObjectiveOriented() )
189  {
190  require_once 'Modules/Course/classes/Objectives/class.ilLOTestQuestionAdapter.php';
191  $objectivesAdapter = ilLOTestQuestionAdapter::getInstance($this->testSession);
192 
193  $objectivesAdapter->notifyTestStart($this->testSession, $this->object->getId());
194  $objectivesAdapter->prepareTestPass($this->testSession, $this->testSequence);
195 
196  $objectivesAdapter->buildQuestionRelatedObjectiveList(
197  $this->testSequence, $this->questionRelatedObjectivesList
198  );
199 
200  if( $this->testSequence->hasOptionalQuestions() )
201  {
203 
204  $this->testSequence->reorderOptionalQuestionsToSequenceEnd();
205  $this->testSequence->saveToDb();
206  }
207  }
208 
209  $active_time_id = $this->object->startWorkingTime(
210  $this->testSession->getActiveId(), $this->testSession->getPass()
211  );
212  $_SESSION["active_time_id"] = $active_time_id;
213 
215 
216  $sequenceElement = $this->testSequence->getFirstSequence();
217 
218  $this->ctrl->setParameter($this, 'sequence', $sequenceElement);
219  $this->ctrl->setParameter($this, 'pmode', '');
220 
221  if ($this->object->getListOfQuestionsStart())
222  {
223  $this->ctrl->redirect($this, ilTestPlayerCommands::QUESTION_SUMMARY);
224  }
225 
226  $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
227  }
228 
230  {
231  global $ilUser;
232 
233  require_once ('./Modules/Test/classes/class.ilObjTestAccess.php');
234  require_once('./Services/Tracking/classes/class.ilLPStatusWrapper.php');
235  ilLPStatusWrapper::_updateStatus($this->object->getId(), $ilUser->getId());
236  }
237 
238  private function isValidSequenceElement($sequenceElement)
239  {
240  if( $sequenceElement === false )
241  {
242  return false;
243  }
244 
245  if( $sequenceElement < 1 )
246  {
247  return false;
248  }
249 
250  if( !$this->testSequence->getPositionOfSequence($sequenceElement) )
251  {
252  return false;
253  }
254 
255  return true;
256  }
257 
258  protected function showQuestionCmd()
259  {
260  $_SESSION['tst_pass_finish'] = 0;
261 
262  $_SESSION["active_time_id"]= $this->object->startWorkingTime(
263  $this->testSession->getActiveId(), $this->testSession->getPass()
264  );
265 
266  $sequenceElement = $this->getCurrentSequenceElement();
267 
268  if( !$this->isValidSequenceElement($sequenceElement) )
269  {
270  $sequenceElement = $this->testSequence->getFirstSequence();
271  }
272 
273  $this->testSession->setLastSequence($sequenceElement);
274  $this->testSession->saveToDb();
275 
276 
277  $questionId = $this->testSequence->getQuestionForSequence($sequenceElement);
278 
279  if( !(int)$questionId && $this->testSession->isObjectiveOriented() )
280  {
282  }
283 
284  $isQuestionWorkedThrough = assQuestion::_isWorkedThrough(
285  $this->testSession->getActiveId(), $questionId, $this->testSession->getPass()
286  );
287 
288 // fau: testNav - always use edit mode, except for fixed answer
289  if( $this->isParticipantsAnswerFixed($questionId) )
290  {
292  $instantResponse = true;
293  }
294  else
295  {
297  $instantResponse = $this->getInstantResponseParameter();
298  }
299 // fau.
300 
301  $questionGui = $this->getQuestionGuiInstance($questionId);
302 
303  if( !($questionGui instanceof assQuestionGUI) )
304  {
305  $this->handleTearsAndAngerQuestionIsNull($questionId, $sequenceElement);
306  }
307 
308  $questionGui->setSequenceNumber($this->testSequence->getPositionOfSequence($sequenceElement));
309  $questionGui->setQuestionCount($this->testSequence->getUserQuestionCount());
310 
311  require_once 'Modules/Test/classes/class.ilTestQuestionHeaderBlockBuilder.php';
312  $headerBlockBuilder = new ilTestQuestionHeaderBlockBuilder($this->lng);
313  $headerBlockBuilder->setHeaderMode($this->object->getTitleOutput());
314  $headerBlockBuilder->setQuestionTitle($questionGui->object->getTitle());
315  $headerBlockBuilder->setQuestionPoints($questionGui->object->getPoints());
316  $headerBlockBuilder->setQuestionPosition($this->testSequence->getPositionOfSequence($sequenceElement));
317  $headerBlockBuilder->setQuestionCount($this->testSequence->getUserQuestionCount());
318  $headerBlockBuilder->setQuestionPostponed($this->testSequence->isPostponedQuestion($questionId));
319  $headerBlockBuilder->setQuestionObligatory(
320  $this->object->areObligationsEnabled() && ilObjTest::isQuestionObligatory($questionGui->object->getId())
321  );
322  if( $this->testSession->isObjectiveOriented() )
323  {
324  require_once 'Modules/Course/classes/Objectives/class.ilLOTestQuestionAdapter.php';
325  $objectivesAdapter = ilLOTestQuestionAdapter::getInstance($this->testSession);
326  $objectivesAdapter->buildQuestionRelatedObjectiveList($this->testSequence, $this->questionRelatedObjectivesList);
327  $this->questionRelatedObjectivesList->loadObjectivesTitles();
328 
329  $objectivesString = $this->questionRelatedObjectivesList->getQuestionRelatedObjectiveTitles($questionId);
330  $headerBlockBuilder->setQuestionRelatedObjectives($objectivesString);
331  }
332  $questionGui->setQuestionHeaderBlockBuilder($headerBlockBuilder);
333 
334  $this->prepareTestPage($presentationMode, $sequenceElement, $questionId);
335 
336  $navigationToolbarGUI = $this->getTestNavigationToolbarGUI();
337  $navigationToolbarGUI->setFinishTestButtonEnabled(true);
338 
339  $isNextPrimary = $this->handlePrimaryButton($navigationToolbarGUI, $questionId);
340 
341  $this->ctrl->setParameter($this, 'sequence', $sequenceElement);
342  $this->ctrl->setParameter($this, 'pmode', $presentationMode);
343  $formAction = $this->ctrl->getFormAction($this, ilTestPlayerCommands::SUBMIT_INTERMEDIATE_SOLUTION);
344 
345  switch($presentationMode)
346  {
348 
349 // fau: testNav - enable navigation toolbar in edit mode
350  $navigationToolbarGUI->setDisabledStateEnabled(false);
351 // fau.
352  $this->showQuestionEditable($questionGui, $formAction, $isQuestionWorkedThrough, $instantResponse);
353 
354  break;
355 
357 
358  if( $this->testSequence->isQuestionOptional($questionGui->object->getId()) )
359  {
361  }
362 
363  $this->showQuestionViewable($questionGui, $formAction, $isQuestionWorkedThrough, $instantResponse);
364 
365  break;
366 
367  default:
368 
369  require_once 'Modules/Test/exceptions/class.ilTestException.php';
370  throw new ilTestException('no presentation mode given');
371  }
372 
373  $navigationToolbarGUI->build();
374  $this->populateTestNavigationToolbar($navigationToolbarGUI);
375 
376 // fau: testNav - enable the question navigation in edit mode
377  $this->populateQuestionNavigation($sequenceElement, false, $isNextPrimary);
378 // fau.
379 
380  if ($instantResponse)
381  {
382 // fau: testNav - always use authorized solution for instant feedback
384  $questionGui, true
385  );
386 // fau.
387  }
388 
389 // fau: testNav - add feedback modal
391  {
394  }
395 // fau.
396 
397  }
398 
399  protected function editSolutionCmd()
400  {
401  $this->ctrl->setParameter($this, 'pmode', ilTestPlayerAbstractGUI::PRESENTATION_MODE_EDIT);
402  $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
403  }
404 
405  protected function submitSolutionAndNextCmd()
406  {
407  if( $this->object->isForceInstantFeedbackEnabled() )
408  {
409  return $this->submitSolutionCmd();
410  }
411 
412  if( $this->saveQuestionSolution(true, false) )
413  {
414  $questionId = $this->testSequence->getQuestionForSequence(
416  );
417 
419 
420  $nextSequenceElement = $this->testSequence->getNextSequence($this->getCurrentSequenceElement());
421 
422  if(!$this->isValidSequenceElement($nextSequenceElement))
423  {
424  $nextSequenceElement = $this->testSequence->getFirstSequence();
425  }
426 
427  $this->testSession->setLastSequence($nextSequenceElement);
428  $this->testSession->saveToDb();
429 
430  $this->ctrl->setParameter($this, 'sequence', $nextSequenceElement);
431  $this->ctrl->setParameter($this, 'pmode', '');
432  }
433 
434  $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
435  }
436 
437  protected function submitSolutionCmd()
438  {
439  if( $this->saveQuestionSolution(true, false) )
440  {
441  $questionId = $this->testSequence->getQuestionForSequence(
443  );
444 
446 
447  if( $this->object->isForceInstantFeedbackEnabled() )
448  {
449  $this->ctrl->setParameter($this, 'instresp', 1);
450 
451  $this->testSequence->setQuestionChecked($questionId);
452  $this->testSequence->saveToDb();
453  }
454 
455  if( $this->getNextCommandParameter() )
456  {
457  if( $this->getNextSequenceParameter() )
458  {
459  $this->ctrl->setParameter($this, 'sequence', $this->getNextSequenceParameter());
460  $this->ctrl->setParameter($this, 'pmode', '');
461  }
462 
463  $this->ctrl->redirect($this, $this->getNextCommandParameter());
464  }
465 
466  $this->ctrl->setParameter($this, 'pmode', ilTestPlayerAbstractGUI::PRESENTATION_MODE_VIEW);
467  }
468  else
469  {
470  $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
471  }
472 
473 // fau: testNav - remember to prevent the navigation confirmation
475 // fau.
476 
477 // fau: testNav - handle navigation after saving
478  if ($this->getNavigationUrlParameter())
479  {
481  }
482  else
483  {
484  $this->ctrl->saveParameter($this, 'sequence');
485  }
486 // fau.
487  $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
488  }
489 
490  protected function discardSolutionCmd()
491  {
492  $currentSequenceElement = $this->getCurrentSequenceElement();
493 
494  $currentQuestionOBJ = $this->getQuestionInstance(
495  $this->testSequence->getQuestionForSequence($currentSequenceElement)
496  );
497 
498  $currentQuestionOBJ->resetUsersAnswer(
499  $this->testSession->getActiveId(), $this->testSession->getPass()
500  );
501 
502  $this->ctrl->saveParameter($this, 'sequence');
503 
504  $this->ctrl->setParameter($this, 'pmode', ilTestPlayerAbstractGUI::PRESENTATION_MODE_VIEW);
505 
506  $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
507  }
508 
509  protected function skipQuestionCmd()
510  {
511  $curSequenceElement = $this->getCurrentSequenceElement();
512  $nextSequenceElement = $this->testSequence->getNextSequence($curSequenceElement);
513 
514  if(!$this->isValidSequenceElement($nextSequenceElement))
515  {
516  $nextSequenceElement = $this->testSequence->getFirstSequence();
517  }
518 
519  if( $this->object->isPostponingEnabled() )
520  {
521  $this->testSequence->postponeSequence($curSequenceElement);
522  $this->testSequence->saveToDb();
523  }
524 
525  $this->ctrl->setParameter($this, 'sequence', $nextSequenceElement);
526  $this->ctrl->setParameter($this, 'pmode', '');
527 
528  $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
529  }
530 
531  protected function handleQuestionPostponing($sequenceElement)
532  {
533  $questionId = $this->testSequence->getQuestionForSequence($sequenceElement);
534 
535  $isQuestionWorkedThrough = assQuestion::_isWorkedThrough(
536  $this->testSession->getActiveId(), $questionId, $this->testSession->getPass()
537  );
538 
539  if( !$isQuestionWorkedThrough )
540  {
541  $this->testSequence->postponeQuestion($questionId);
542  $this->testSequence->saveToDb();
543  }
544  }
545 
546  protected function nextQuestionCmd()
547  {
548  $lastSequenceElement = $this->getCurrentSequenceElement();
549  $nextSequenceElement = $this->testSequence->getNextSequence($lastSequenceElement);
550 
551  if( $this->object->isPostponingEnabled() )
552  {
553  $this->handleQuestionPostponing($lastSequenceElement);
554  }
555 
556  if(!$this->isValidSequenceElement($nextSequenceElement))
557  {
558  $nextSequenceElement = $this->testSequence->getFirstSequence();
559  }
560 
561  $this->ctrl->setParameter($this, 'sequence', $nextSequenceElement);
562  $this->ctrl->setParameter($this, 'pmode', '');
563 
564  $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
565  }
566 
567  protected function previousQuestionCmd()
568  {
569  $sequenceElement = $this->testSequence->getPreviousSequence(
571  );
572 
573  if(!$this->isValidSequenceElement($sequenceElement))
574  {
575  $sequenceElement = $this->testSequence->getLastSequence();
576  }
577 
578  $this->ctrl->setParameter($this, 'sequence', $sequenceElement);
579  $this->ctrl->setParameter($this, 'pmode', '');
580 
581  $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
582  }
583 
584  protected function isFirstQuestionInSequence($sequenceElement)
585  {
586  return $sequenceElement == $this->testSequence->getFirstSequence();
587  }
588 
589  protected function isLastQuestionInSequence($sequenceElement)
590  {
591  return $sequenceElement == $this->testSequence->getLastSequence();
592  }
593 
599  protected function canSaveResult()
600  {
601  return !$this->object->endingTimeReached() && !$this->isMaxProcessingTimeReached() && !$this->isNrOfTriesReached();
602  }
603 
607  protected function getCurrentQuestionId()
608  {
609  return $this->testSequence->getQuestionForSequence($_GET["sequence"]);
610  }
611 
615  public function saveQuestionSolution($authorized = true, $force = false)
616  {
617  $this->updateWorkingTime();
618  $this->saveResult = FALSE;
619  if (!$force)
620  {
621  $formtimestamp = $_POST["formtimestamp"];
622  if (strlen($formtimestamp) == 0) $formtimestamp = $_GET["formtimestamp"];
623  if ($formtimestamp != $_SESSION["formtimestamp"])
624  {
625  $_SESSION["formtimestamp"] = $formtimestamp;
626  }
627  else
628  {
629  return FALSE;
630  }
631  }
632  // save question solution
633  if ($this->canSaveResult() || $force)
634  {
635  // but only if the ending time is not reached
636  $q_id = $this->testSequence->getQuestionForSequence($_GET["sequence"]);
637  if (is_numeric($q_id) && (int)$q_id)
638  {
639  $questionOBJ = $this->getQuestionInstance($q_id);
640  $pass = NULL;
641  $active_id = $this->testSession->getActiveId();
642  if ($this->object->isRandomTest())
643  {
644  $pass = ilObjTest::_getPass($active_id);
645  }
646  $this->saveResult = $questionOBJ->persistWorkingState(
647  $active_id, $pass, $this->object->areObligationsEnabled(), $authorized
648  );
649 
650  if( $authorized && $this->testSession->isObjectiveOriented() )
651  {
652  require_once 'Modules/Course/classes/Objectives/class.ilLOTestQuestionAdapter.php';
653  $objectivesAdapter = ilLOTestQuestionAdapter::getInstance($this->testSession);
654  $objectivesAdapter->updateQuestionResult($this->testSession, $questionOBJ);
655  }
656 
657  if( $authorized && $this->object->isSkillServiceToBeConsidered() )
658  {
659  $this->handleSkillTriggering($this->testSession);
660  }
661  }
662  }
663 
664  if ($this->saveResult == FALSE)
665  {
666  $this->ctrl->setParameter($this, "save_error", "1");
667  $_SESSION["previouspost"] = $_POST;
668  }
669 
670  return $this->saveResult;
671  }
672 
673  protected function showInstantResponseCmd()
674  {
675  $questionId = $this->testSequence->getQuestionForSequence(
677  );
678 
679  if( $this->getAnswerChangedParameter() && !$this->isParticipantsAnswerFixed($questionId) )
680  {
681  if( $this->saveQuestionSolution(true) )
682  {
684  $this->setAnswerChangedParameter(false);
685  }
686  else
687  {
688  $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
689  }
690  $this->testSequence->setQuestionChecked($questionId);
691  $this->testSequence->saveToDb();
692  }
693 
694  $this->ctrl->setParameter($this, 'instresp', 1);
695 
696 // fau: testNav - handle navigation after feedback
697  if ($this->getNavigationUrlParameter())
698  {
701  }
702 // fau.
703  $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
704  }
705 
706  protected function handleQuestionActionCmd()
707  {
708  $questionId = $this->testSequence->getQuestionForSequence(
710  );
711 
712  if( !$this->isParticipantsAnswerFixed($questionId) )
713  {
714  $this->updateWorkingTime();
715  $this->saveQuestionSolution(false);
716 // fau: testNav - add changed status of the question
717  $this->setAnswerChangedParameter(true);
718 // fau.
719  }
720 
721  $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
722  }
723 
725  {
726  if ($this->testSession->getActiveId() > 0)
727  {
728  if ($this->testSequence->hasRandomQuestionsForPass($this->testSession->getActiveId(), $this->testSession->getPass()) > 0)
729  {
730  // Something went wrong. Maybe the user pressed the start button twice
731  // Questions already exist so there is no need to create new questions
732 
733  global $ilLog, $ilUser;
734 
735  $ilLog->write(
736  __METHOD__.' Random Questions allready exists for user '.
737  $ilUser->getId().' in test '.$this->object->getTestId()
738  );
739 
740  return true;
741  }
742  }
743  else
744  {
745  // This may not happen! If it happens, raise a fatal error...
746 
747  global $ilLog, $ilUser;
748 
749  $ilLog->write(__METHOD__.' '.sprintf(
750  $this->lng->txt("error_random_question_generation"), $ilUser->getId(), $this->object->getTestId()
751  ));
752 
753  return true;
754  };
755 
756  return false;
757  }
758 
760  {
761  global $tree, $ilDB, $ilPluginAdmin;
762 
763  require_once 'Modules/Test/classes/class.ilTestRandomQuestionSetConfig.php';
764  $questionSetConfig = new ilTestRandomQuestionSetConfig($tree, $ilDB, $ilPluginAdmin, $this->object);
765  $questionSetConfig->loadFromDb();
766 
767  require_once 'Modules/Test/classes/class.ilTestRandomQuestionSetSourcePoolDefinitionFactory.php';
768  $sourcePoolDefinitionFactory = new ilTestRandomQuestionSetSourcePoolDefinitionFactory($ilDB, $this->object);
769 
770  require_once 'Modules/Test/classes/class.ilTestRandomQuestionSetSourcePoolDefinitionList.php';
771  $sourcePoolDefinitionList = new ilTestRandomQuestionSetSourcePoolDefinitionList($ilDB, $this->object, $sourcePoolDefinitionFactory);
772  $sourcePoolDefinitionList->loadDefinitions();
773 
774  $this->processLocker->executeRandomPassBuildOperation(function() use ($ilDB, $ilPluginAdmin, $questionSetConfig, $sourcePoolDefinitionList) {
775 
777  {
778  require_once 'Modules/Test/classes/class.ilTestRandomQuestionSetStagingPoolQuestionList.php';
779  $stagingPoolQuestionList = new ilTestRandomQuestionSetStagingPoolQuestionList($ilDB, $ilPluginAdmin);
780 
781  require_once 'Modules/Test/classes/class.ilTestRandomQuestionSetBuilder.php';
782  $questionSetBuilder = ilTestRandomQuestionSetBuilder::getInstance($ilDB, $this->object, $questionSetConfig, $sourcePoolDefinitionList, $stagingPoolQuestionList);
783 
784  $questionSetBuilder->performBuild($this->testSession);
785  }
786 
787  }, $sourcePoolDefinitionList->hasTaxonomyFilters());
788  }
789 
793  protected function resumePlayerCmd()
794  {
795  $this->handleUserSettings();
796 
797  $active_id = $this->testSession->getActiveId();
798  $this->ctrl->setParameter($this, "active_id", $active_id);
799 
800  $active_time_id = $this->object->startWorkingTime($active_id, $this->testSession->getPass());
801  $_SESSION["active_time_id"] = $active_time_id;
802  $_SESSION['tst_pass_finish'] = 0;
803 
804  if ($this->object->isRandomTest())
805  {
806  if (!$this->testSequence->hasRandomQuestionsForPass($active_id, $this->testSession->getPass()))
807  {
808  // create a new set of random questions
810  }
811  }
812 
813  $shuffle = $this->object->getShuffleQuestions();
814  if ($this->object->isRandomTest())
815  {
816  $shuffle = FALSE;
817  }
818 
819  assQuestion::_updateTestPassResults(
820  $active_id, $this->testSession->getPass(), $this->object->areObligationsEnabled(), null, $this->object->id
821  );
822 
823  // ensure existing test sequence
824  if( !$this->testSequence->hasSequence() )
825  {
826  $this->testSequence->createNewSequence($this->object->getQuestionCount(), $shuffle);
827  $this->testSequence->saveToDb();
828  }
829 
830  if ($this->object->getListOfQuestionsStart())
831  {
832  $this->ctrl->redirect($this, ilTestPlayerCommands::QUESTION_SUMMARY);
833  }
834 
835  $this->ctrl->setParameter($this, 'sequence', $this->testSession->getLastSequence());
836  $this->ctrl->setParameter($this, 'pmode', '');
837  $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
838  }
839 
840  protected function isShowingPostponeStatusReguired($questionId)
841  {
842  return $this->testSequence->isPostponedQuestion($questionId);
843  }
844 
846  {
847  global $ilDB, $ilUser;
848 
849  $assSettings = new ilSetting('assessment');
850 
851  include_once ("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
852  $isAssessmentLogEnabled = ilObjAssessmentFolder::_enabledAssessmentLogging();
853 
854  require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionUserSolutionAdopter.php';
855  $userSolutionAdopter = new ilAssQuestionUserSolutionAdopter($ilDB, $assSettings, $isAssessmentLogEnabled);
856 
857  $userSolutionAdopter->setUserId($ilUser->getId());
858  $userSolutionAdopter->setActiveId($this->testSession->getActiveId());
859  $userSolutionAdopter->setTargetPass($this->testSequence->getPass());
860  $userSolutionAdopter->setQuestionIds($this->testSequence->getOptionalQuestions());
861 
862  $userSolutionAdopter->perform();
863  }
864 
865  abstract protected function populateQuestionOptionalMessage();
866 
867  protected function isOptionalQuestionAnsweringConfirmationRequired($sequenceKey)
868  {
869  if( $this->testSequence->isAnsweringOptionalQuestionsConfirmed() )
870  {
871  return false;
872  }
873 
874  $questionId = $this->testSequence->getQuestionForSequence($sequenceKey);
875 
876  if( !$this->testSequence->isQuestionOptional($questionId) )
877  {
878  return false;
879  }
880 
881  return true;
882  }
883 
885  {
886  return true;
887  }
888 
890  {
891  ilUtil::sendFailure(sprintf($this->lng->txt('tst_objective_oriented_test_pass_without_questions'), $this->object->getTitle()), true);
892 
893  $this->backToInfoScreenCmd();
894  }
895 
899  protected function handlePrimaryButton(ilTestNavigationToolbarGUI $navigationToolbarGUI, $currentQuestionId)
900  {
901  $isNextPrimary = true;
902 
903  if( $this->object->isForceInstantFeedbackEnabled() )
904  {
905  $isNextPrimary = false;
906  }
907 
908  $questionsMissingResult = assQuestion::getQuestionsMissingResultRecord(
909  $this->testSession->getActiveId(), $this->testSession->getPass(),
910  $this->testSequence->getOrderedSequenceQuestions()
911  );
912 
913  if( !count($questionsMissingResult) )
914  {
915  $navigationToolbarGUI->setFinishTestButtonPrimary(true);
916  $isNextPrimary = false;
917  }
918  elseif( count($questionsMissingResult) == 1 )
919  {
920  $lastOpenQuestion = current($questionsMissingResult);
921 
922  if($currentQuestionId == $lastOpenQuestion)
923  {
924  $navigationToolbarGUI->setFinishTestButtonPrimary(true);
925  $isNextPrimary = false;
926  }
927  }
928 
929  return $isNextPrimary;
930  }
931 }
isShowingPostponeStatusReguired($questionId)
checkTestSessionUser(ilTestSession $testSession)
isValidSequenceElement($sequenceElement)
ILIAS Setting Class.
removeIntermediateSolution()
remove an auto-saved solution of the current question
populateQuestionOptionalMessage()
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test.
setAnswerChangedParameter($changed=true)
Set the &#39;answer changed&#39; url parameter for generated links.
$_SESSION["AccountId"]
Signature Plugin Class.
$_GET["client_id"]
static getQuestionsMissingResultRecord($activeId, $pass, $questionIds)
showQuestionEditable(assQuestionGUI $questionGui, $formAction, $isQuestionWorkedThrough, $instantResponse)
Output class for assessment test execution.
static _updateStatus($a_obj_id, $a_usr_id, $a_obj=null, $a_percentage=false, $a_force_raise=false)
Update status.
updateWorkingTime()
updates working time and stores state saveresult to see if question has to be stored or not ...
$cmd
Definition: sahs_server.php:35
isLastQuestionInSequence($sequenceElement)
isFirstQuestionInSequence($sequenceElement)
executeCommand()
Execute Command.
resumePlayerCmd()
Resume a test at the last position.
handleUserSettings()
Handles some form parameters on starting and resuming a test.
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)
populateQuestionNavigation($sequenceElement, $disabled, $primaryNext)
static getInstance(ilTestSession $a_test_session)
static _enabledAssessmentLogging()
check wether assessment logging is enabled or not
isOptionalQuestionAnsweringConfirmationRequired($sequenceKey)
handleSkillTriggering(ilTestSession $testSession)
Class ilTestSubmissionReviewGUI.
handleQuestionPostponing($sequenceElement)
getCommand($cmd)
Retrieves the ilCtrl command.
saveNavigationPreventConfirmation()
Save the save the switch to prevent the navigation confirmation.
populateTestNavigationToolbar(ilTestNavigationToolbarGUI $toolbarGUI)
$ilUser
Definition: imgupload.php:18
static getInstance(ilDBInterface $db, ilObjTest $testOBJ, ilTestRandomQuestionSetConfig $questionSetConfig, ilTestRandomQuestionSetSourcePoolDefinitionList $sourcePoolDefinitionList, ilTestRandomQuestionSetStagingPoolQuestionList $stagingPoolQuestionList)
handlePrimaryButton(ilTestNavigationToolbarGUI $navigationToolbarGUI, $currentQuestionId)
getAnswerChangedParameter()
Get the &#39;answer changed&#39; status from the current request It may be set by ilTestPlayerNavigationContr...
Basic GUI class for assessment questions.
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
setFinishTestButtonPrimary($finishTestButtonPrimary)
registerForcedFeedbackNavUrl($forcedFeedbackNavUrl)
saveQuestionSolution($authorized=true, $force=false)
saves the user input of a question
showQuestionViewable(assQuestionGUI $questionGui, $formAction, $isQuestionWorkedThrough, $instantResponse)
Create new PHPExcel object
obj_idprivate
populateInstantResponseModal(assQuestionGUI $questionGui, $navUrl)
global $ilDB
$ret
Definition: parser.php:6
getQuestionGuiInstance($questionId, $fromCache=true)
static initjQuery($a_tpl=null)
Init jQuery.
getQuestionInstance($questionId, $fromCache=true)
handleTearsAndAngerQuestionIsNull($questionId, $sequenceElement)
isMaxProcessingTimeReached()
Checks wheather the maximum processing time is reached or not.
static redirect($a_script)
http redirect to other script
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 ...
$_POST["username"]
static initConnectionWithAnimation()
Init YUI Connection module.
canSaveResult()
Returns TRUE if the answers of the current user could be saved.
Output class for assessment test execution.