ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
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  case 'ilassquestionpagegui':
74 
75  $this->checkTestExecutable();
76 
77  $questionId = $this->testSequence->getQuestionForSequence($this->getCurrentSequenceElement());
78 
79  require_once "./Modules/TestQuestionPool/classes/class.ilAssQuestionPageGUI.php";
80  $page_gui = new ilAssQuestionPageGUI($questionId);
81  $ret = $this->ctrl->forwardCommand($page_gui);
82  break;
83 
84  case 'iltestsubmissionreviewgui':
85 
86  $this->checkTestExecutable();
87 
88  require_once './Modules/Test/classes/class.ilTestSubmissionReviewGUI.php';
89  $gui = new ilTestSubmissionReviewGUI($this, $this->object, $this->testSession);
90  $gui->setObjectiveOrientedContainer($this->getObjectiveOrientedContainer());
91  $ret = $this->ctrl->forwardCommand($gui);
92  break;
93 
94  case 'ilassquestionhintrequestgui':
95 
96  $this->checkTestExecutable();
97 
98  $questionGUI = $this->object->createQuestionGUI(
99  "",
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(),
106  $this->testSession->getActiveId(),
107  $this->testSession->getPass()
108  );
109 
110  require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionHintRequestGUI.php';
111  $gui = new ilAssQuestionHintRequestGUI($this, ilTestPlayerCommands::SHOW_QUESTION, $questionGUI, $questionHintTracking);
112 
113 // fau: testNav - save the 'answer changed' status for viewing hint requests
115 // fau.
116  $ret = $this->ctrl->forwardCommand($gui);
117 
118  break;
119 
120  case 'iltestsignaturegui':
121 
122  $this->checkTestExecutable();
123 
124  require_once './Modules/Test/classes/class.ilTestSignatureGUI.php';
125  $gui = new ilTestSignatureGUI($this);
126  $ret = $this->ctrl->forwardCommand($gui);
127  break;
128 
129  case 'iltestpasswordprotectiongui':
130 
131  $this->checkTestExecutable();
132 
133  require_once 'Modules/Test/classes/class.ilTestPasswordProtectionGUI.php';
134  $gui = new ilTestPasswordProtectionGUI($this->ctrl, $this->tpl, $this->lng, $this, $this->passwordChecker);
135  $ret = $this->ctrl->forwardCommand($gui);
136  break;
137 
138  default:
139 
141  $this->checkTestExecutable();
142  }
143 
144  $cmd .= 'Cmd';
145  $ret =&$this->$cmd();
146  break;
147  }
148  return $ret;
149  }
150 
151  protected function startTestCmd()
152  {
153  global $ilUser;
154 
155  $_SESSION['tst_pass_finish'] = 0;
156 
157  // ensure existing test session
158  $this->testSession->setUserId($ilUser->getId());
159  $this->testSession->setAnonymousId($_SESSION["tst_access_code"][$this->object->getTestId()]);
160  $this->testSession->setObjectiveOrientedContainerId($this->getObjectiveOrientedContainer()->getObjId());
161  $this->testSession->saveToDb();
162 
163  $active_id = $this->testSession->getActiveId();
164  $this->ctrl->setParameter($this, "active_id", $active_id);
165 
166  $shuffle = $this->object->getShuffleQuestions();
167  if ($this->object->isRandomTest()) {
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,
176  $this->testSession->getPass(),
177  $this->object->areObligationsEnabled(),
178  null,
179  $this->object->id
180  );
181 
182  // ensure existing test sequence
183  if (!$this->testSequence->hasSequence()) {
184  $this->testSequence->createNewSequence($this->object->getQuestionCount(), $shuffle);
185  $this->testSequence->saveToDb();
186  }
187 
188  $this->testSequence->loadFromDb();
189  $this->testSequence->loadQuestions();
190 
191  if ($this->testSession->isObjectiveOriented()) {
192  require_once 'Modules/Course/classes/Objectives/class.ilLOTestQuestionAdapter.php';
193  $objectivesAdapter = ilLOTestQuestionAdapter::getInstance($this->testSession);
194 
195  $objectivesAdapter->notifyTestStart($this->testSession, $this->object->getId());
196  $objectivesAdapter->prepareTestPass($this->testSession, $this->testSequence);
197 
198  $objectivesAdapter->buildQuestionRelatedObjectiveList(
199  $this->testSequence,
200  $this->questionRelatedObjectivesList
201  );
202 
203  if ($this->testSequence->hasOptionalQuestions()) {
205 
206  $this->testSequence->reorderOptionalQuestionsToSequenceEnd();
207  $this->testSequence->saveToDb();
208  }
209  }
210 
211  $active_time_id = $this->object->startWorkingTime(
212  $this->testSession->getActiveId(),
213  $this->testSession->getPass()
214  );
215  $_SESSION["active_time_id"] = $active_time_id;
216 
218 
219  $sequenceElement = $this->testSequence->getFirstSequence();
220 
221  $this->ctrl->setParameter($this, 'sequence', $sequenceElement);
222  $this->ctrl->setParameter($this, 'pmode', '');
223 
224  if ($this->object->getListOfQuestionsStart()) {
225  $this->ctrl->redirect($this, ilTestPlayerCommands::QUESTION_SUMMARY);
226  }
227 
228  $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
229  }
230 
232  {
233  global $ilUser;
234 
235  require_once('./Modules/Test/classes/class.ilObjTestAccess.php');
236  require_once('./Services/Tracking/classes/class.ilLPStatusWrapper.php');
237  ilLPStatusWrapper::_updateStatus($this->object->getId(), $ilUser->getId());
238  }
239 
240  private function isValidSequenceElement($sequenceElement)
241  {
242  if ($sequenceElement === false) {
243  return false;
244  }
245 
246  if ($sequenceElement < 1) {
247  return false;
248  }
249 
250  if (!$this->testSequence->getPositionOfSequence($sequenceElement)) {
251  return false;
252  }
253 
254  return true;
255  }
256 
257  protected function showQuestionCmd()
258  {
259  $_SESSION['tst_pass_finish'] = 0;
260 
261  $_SESSION["active_time_id"]= $this->object->startWorkingTime(
262  $this->testSession->getActiveId(),
263  $this->testSession->getPass()
264  );
265 
266  $sequenceElement = $this->getCurrentSequenceElement();
267 
268  if (!$this->isValidSequenceElement($sequenceElement)) {
269  $sequenceElement = $this->testSequence->getFirstSequence();
270  }
271 
272  $this->testSession->setLastSequence($sequenceElement);
273  $this->testSession->saveToDb();
274 
275 
276  $questionId = $this->testSequence->getQuestionForSequence($sequenceElement);
277 
278  if (!(int) $questionId && $this->testSession->isObjectiveOriented()) {
280  }
281 
282  $isQuestionWorkedThrough = assQuestion::_isWorkedThrough(
283  $this->testSession->getActiveId(),
284  $questionId,
285  $this->testSession->getPass()
286  );
287 
288  // fau: testNav - always use edit mode, except for fixed answer
289  if ($this->isParticipantsAnswerFixed($questionId)) {
291  $instantResponse = true;
292  } else {
294  $instantResponse = $this->getInstantResponseParameter();
295  }
296  // fau.
297 
298  $questionGui = $this->getQuestionGuiInstance($questionId);
299 
300  if (!($questionGui instanceof assQuestionGUI)) {
301  $this->handleTearsAndAngerQuestionIsNull($questionId, $sequenceElement);
302  }
303 
304  $questionGui->setSequenceNumber($this->testSequence->getPositionOfSequence($sequenceElement));
305  $questionGui->setQuestionCount($this->testSequence->getUserQuestionCount());
306 
307  require_once 'Modules/Test/classes/class.ilTestQuestionHeaderBlockBuilder.php';
308  $headerBlockBuilder = new ilTestQuestionHeaderBlockBuilder($this->lng);
309  $headerBlockBuilder->setHeaderMode($this->object->getTitleOutput());
310  $headerBlockBuilder->setQuestionTitle($questionGui->object->getTitle());
311  $headerBlockBuilder->setQuestionPoints($questionGui->object->getPoints());
312  $headerBlockBuilder->setQuestionPosition($this->testSequence->getPositionOfSequence($sequenceElement));
313  $headerBlockBuilder->setQuestionCount($this->testSequence->getUserQuestionCount());
314  $headerBlockBuilder->setQuestionPostponed($this->testSequence->isPostponedQuestion($questionId));
315  $headerBlockBuilder->setQuestionObligatory(
316  $this->object->areObligationsEnabled() && ilObjTest::isQuestionObligatory($questionGui->object->getId())
317  );
318  if ($this->testSession->isObjectiveOriented()) {
319  require_once 'Modules/Course/classes/Objectives/class.ilLOTestQuestionAdapter.php';
320  $objectivesAdapter = ilLOTestQuestionAdapter::getInstance($this->testSession);
321  $objectivesAdapter->buildQuestionRelatedObjectiveList($this->testSequence, $this->questionRelatedObjectivesList);
322  $this->questionRelatedObjectivesList->loadObjectivesTitles();
323 
324  $objectivesString = $this->questionRelatedObjectivesList->getQuestionRelatedObjectiveTitles($questionId);
325  $headerBlockBuilder->setQuestionRelatedObjectives($objectivesString);
326  }
327  $questionGui->setQuestionHeaderBlockBuilder($headerBlockBuilder);
328 
329  $this->prepareTestPage($presentationMode, $sequenceElement, $questionId);
330 
331  $navigationToolbarGUI = $this->getTestNavigationToolbarGUI();
332  $navigationToolbarGUI->setFinishTestButtonEnabled(true);
333 
334  $isNextPrimary = $this->handlePrimaryButton($navigationToolbarGUI, $questionId);
335 
336  $this->ctrl->setParameter($this, 'sequence', $sequenceElement);
337  $this->ctrl->setParameter($this, 'pmode', $presentationMode);
338  $formAction = $this->ctrl->getFormAction($this, ilTestPlayerCommands::SUBMIT_INTERMEDIATE_SOLUTION);
339 
340  switch ($presentationMode) {
342 
343 // fau: testNav - enable navigation toolbar in edit mode
344  $navigationToolbarGUI->setDisabledStateEnabled(false);
345 // fau.
346  $this->showQuestionEditable($questionGui, $formAction, $isQuestionWorkedThrough, $instantResponse);
347 
348  break;
349 
351 
352  if ($this->testSequence->isQuestionOptional($questionGui->object->getId())) {
354  }
355 
356  $this->showQuestionViewable($questionGui, $formAction, $isQuestionWorkedThrough, $instantResponse);
357 
358  break;
359 
360  default:
361 
362  require_once 'Modules/Test/exceptions/class.ilTestException.php';
363  throw new ilTestException('no presentation mode given');
364  }
365 
366  $navigationToolbarGUI->build();
367  $this->populateTestNavigationToolbar($navigationToolbarGUI);
368 
369  // fau: testNav - enable the question navigation in edit mode
370  $this->populateQuestionNavigation($sequenceElement, false, $isNextPrimary);
371  // fau.
372 
373  if ($instantResponse) {
374  // fau: testNav - always use authorized solution for instant feedback
376  $questionGui,
377  true
378  );
379  // fau.
380  }
381 
382  // fau: testNav - add feedback modal
383  if ($this->isForcedFeedbackNavUrlRegistered()) {
386  }
387  // fau.
388  }
389 
390  protected function editSolutionCmd()
391  {
392  $this->ctrl->setParameter($this, 'pmode', ilTestPlayerAbstractGUI::PRESENTATION_MODE_EDIT);
393  $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
394  }
395 
396  protected function submitSolutionAndNextCmd()
397  {
398  if ($this->object->isForceInstantFeedbackEnabled()) {
399  return $this->submitSolutionCmd();
400  }
401 
402  if ($this->saveQuestionSolution(true, false)) {
403  $questionId = $this->testSequence->getQuestionForSequence(
405  );
406 
408 
409  $nextSequenceElement = $this->testSequence->getNextSequence($this->getCurrentSequenceElement());
410 
411  if (!$this->isValidSequenceElement($nextSequenceElement)) {
412  $nextSequenceElement = $this->testSequence->getFirstSequence();
413  }
414 
415  $this->testSession->setLastSequence($nextSequenceElement);
416  $this->testSession->saveToDb();
417 
418  $this->ctrl->setParameter($this, 'sequence', $nextSequenceElement);
419  $this->ctrl->setParameter($this, 'pmode', '');
420  }
421 
422  $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
423  }
424 
425  protected function submitSolutionCmd()
426  {
427  if ($this->saveQuestionSolution(true, false)) {
428  $questionId = $this->testSequence->getQuestionForSequence(
430  );
431 
433 
434  if ($this->object->isForceInstantFeedbackEnabled()) {
435  $this->ctrl->setParameter($this, 'instresp', 1);
436 
437  $this->testSequence->setQuestionChecked($questionId);
438  $this->testSequence->saveToDb();
439  }
440 
441  if ($this->getNextCommandParameter()) {
442  if ($this->getNextSequenceParameter()) {
443  $this->ctrl->setParameter($this, 'sequence', $this->getNextSequenceParameter());
444  $this->ctrl->setParameter($this, 'pmode', '');
445  }
446 
447  $this->ctrl->redirect($this, $this->getNextCommandParameter());
448  }
449 
450  $this->ctrl->setParameter($this, 'pmode', ilTestPlayerAbstractGUI::PRESENTATION_MODE_VIEW);
451  } else {
452  $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
453  }
454 
455  // fau: testNav - remember to prevent the navigation confirmation
457  // fau.
458 
459  // fau: testNav - handle navigation after saving
460  if ($this->getNavigationUrlParameter()) {
462  } else {
463  $this->ctrl->saveParameter($this, 'sequence');
464  }
465  // fau.
466  $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
467  }
468 
469  protected function discardSolutionCmd()
470  {
471  $currentSequenceElement = $this->getCurrentSequenceElement();
472 
473  $currentQuestionOBJ = $this->getQuestionInstance(
474  $this->testSequence->getQuestionForSequence($currentSequenceElement)
475  );
476 
477  $currentQuestionOBJ->resetUsersAnswer(
478  $this->testSession->getActiveId(),
479  $this->testSession->getPass()
480  );
481 
482  $this->ctrl->saveParameter($this, 'sequence');
483 
484  $this->ctrl->setParameter($this, 'pmode', ilTestPlayerAbstractGUI::PRESENTATION_MODE_VIEW);
485 
486  $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
487  }
488 
489  protected function skipQuestionCmd()
490  {
491  $curSequenceElement = $this->getCurrentSequenceElement();
492  $nextSequenceElement = $this->testSequence->getNextSequence($curSequenceElement);
493 
494  if (!$this->isValidSequenceElement($nextSequenceElement)) {
495  $nextSequenceElement = $this->testSequence->getFirstSequence();
496  }
497 
498  if ($this->object->isPostponingEnabled()) {
499  $this->testSequence->postponeSequence($curSequenceElement);
500  $this->testSequence->saveToDb();
501  }
502 
503  $this->ctrl->setParameter($this, 'sequence', $nextSequenceElement);
504  $this->ctrl->setParameter($this, 'pmode', '');
505 
506  $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
507  }
508 
509  protected function handleQuestionPostponing($sequenceElement)
510  {
511  $questionId = $this->testSequence->getQuestionForSequence($sequenceElement);
512 
513  $isQuestionWorkedThrough = assQuestion::_isWorkedThrough(
514  $this->testSession->getActiveId(),
515  $questionId,
516  $this->testSession->getPass()
517  );
518 
519  if (!$isQuestionWorkedThrough) {
520  $this->testSequence->postponeQuestion($questionId);
521  $this->testSequence->saveToDb();
522  }
523  }
524 
525  protected function nextQuestionCmd()
526  {
527  $lastSequenceElement = $this->getCurrentSequenceElement();
528  $nextSequenceElement = $this->testSequence->getNextSequence($lastSequenceElement);
529 
530  if ($this->object->isPostponingEnabled()) {
531  $this->handleQuestionPostponing($lastSequenceElement);
532  }
533 
534  if (!$this->isValidSequenceElement($nextSequenceElement)) {
535  $nextSequenceElement = $this->testSequence->getFirstSequence();
536  }
537 
538  $this->ctrl->setParameter($this, 'sequence', $nextSequenceElement);
539  $this->ctrl->setParameter($this, 'pmode', '');
540 
541  $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
542  }
543 
544  protected function previousQuestionCmd()
545  {
546  $sequenceElement = $this->testSequence->getPreviousSequence(
548  );
549 
550  if (!$this->isValidSequenceElement($sequenceElement)) {
551  $sequenceElement = $this->testSequence->getLastSequence();
552  }
553 
554  $this->ctrl->setParameter($this, 'sequence', $sequenceElement);
555  $this->ctrl->setParameter($this, 'pmode', '');
556 
557  $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
558  }
559 
560  protected function isFirstQuestionInSequence($sequenceElement)
561  {
562  return $sequenceElement == $this->testSequence->getFirstSequence();
563  }
564 
565  protected function isLastQuestionInSequence($sequenceElement)
566  {
567  return $sequenceElement == $this->testSequence->getLastSequence();
568  }
569 
575  protected function canSaveResult()
576  {
577  return !$this->object->endingTimeReached() && !$this->isMaxProcessingTimeReached() && !$this->isNrOfTriesReached();
578  }
579 
583  protected function getCurrentQuestionId()
584  {
585  return $this->testSequence->getQuestionForSequence($_GET["sequence"]);
586  }
587 
591  public function saveQuestionSolution($authorized = true, $force = false)
592  {
593  $this->updateWorkingTime();
594  $this->saveResult = false;
595  if (!$force) {
596  $formtimestamp = $_POST["formtimestamp"];
597  if (strlen($formtimestamp) == 0) {
598  $formtimestamp = $_GET["formtimestamp"];
599  }
600  if ($formtimestamp != $_SESSION["formtimestamp"]) {
601  $_SESSION["formtimestamp"] = $formtimestamp;
602  } else {
603  return false;
604  }
605  }
606  // save question solution
607  if ($this->canSaveResult() || $force) {
608  // but only if the ending time is not reached
609  $q_id = $this->testSequence->getQuestionForSequence($_GET["sequence"]);
610  if (is_numeric($q_id) && (int) $q_id) {
611  $questionOBJ = $this->getQuestionInstance($q_id);
612  $pass = null;
613  $active_id = $this->testSession->getActiveId();
614  if ($this->object->isRandomTest()) {
615  $pass = ilObjTest::_getPass($active_id);
616  }
617  $this->saveResult = $questionOBJ->persistWorkingState(
618  $active_id,
619  $pass,
620  $this->object->areObligationsEnabled(),
621  $authorized
622  );
623 
624  if ($authorized && $this->testSession->isObjectiveOriented()) {
625  require_once 'Modules/Course/classes/Objectives/class.ilLOTestQuestionAdapter.php';
626  $objectivesAdapter = ilLOTestQuestionAdapter::getInstance($this->testSession);
627  $objectivesAdapter->updateQuestionResult($this->testSession, $questionOBJ);
628  }
629 
630  if ($authorized && $this->object->isSkillServiceToBeConsidered()) {
631  $this->handleSkillTriggering($this->testSession);
632  }
633  }
634  }
635 
636  if ($this->saveResult == false) {
637  $this->ctrl->setParameter($this, "save_error", "1");
638  $_SESSION["previouspost"] = $_POST;
639  }
640 
641  return $this->saveResult;
642  }
643 
644  protected function showInstantResponseCmd()
645  {
646  $questionId = $this->testSequence->getQuestionForSequence(
648  );
649 
650  if ($this->getAnswerChangedParameter() && !$this->isParticipantsAnswerFixed($questionId)) {
651  if ($this->saveQuestionSolution(true)) {
653  $this->setAnswerChangedParameter(false);
654  } else {
655  $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
656  }
657  $this->testSequence->setQuestionChecked($questionId);
658  $this->testSequence->saveToDb();
659  }
660 
661  $this->ctrl->setParameter($this, 'instresp', 1);
662 
663  // fau: testNav - handle navigation after feedback
664  if ($this->getNavigationUrlParameter()) {
667  }
668  // fau.
669  $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
670  }
671 
672  protected function handleQuestionActionCmd()
673  {
674  $questionId = $this->testSequence->getQuestionForSequence(
676  );
677 
678  if (!$this->isParticipantsAnswerFixed($questionId)) {
679  $this->updateWorkingTime();
680  $this->saveQuestionSolution(false);
681  // fau: testNav - add changed status of the question
682  $this->setAnswerChangedParameter(true);
683  // fau.
684  }
685 
686  $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
687  }
688 
690  {
691  if ($this->testSession->getActiveId() > 0) {
692  if ($this->testSequence->hasRandomQuestionsForPass($this->testSession->getActiveId(), $this->testSession->getPass()) > 0) {
693  // Something went wrong. Maybe the user pressed the start button twice
694  // Questions already exist so there is no need to create new questions
695 
696  global $ilLog, $ilUser;
697 
698  $ilLog->write(
699  __METHOD__ . ' Random Questions allready exists for user ' .
700  $ilUser->getId() . ' in test ' . $this->object->getTestId()
701  );
702 
703  return true;
704  }
705  } else {
706  // This may not happen! If it happens, raise a fatal error...
707 
708  global $ilLog, $ilUser;
709 
710  $ilLog->write(__METHOD__ . ' ' . sprintf(
711  $this->lng->txt("error_random_question_generation"),
712  $ilUser->getId(),
713  $this->object->getTestId()
714  ));
715 
716  return true;
717  };
718 
719  return false;
720  }
721 
723  {
724  global $tree, $ilDB, $ilPluginAdmin;
725 
726  require_once 'Modules/Test/classes/class.ilTestRandomQuestionSetConfig.php';
727  $questionSetConfig = new ilTestRandomQuestionSetConfig($tree, $ilDB, $ilPluginAdmin, $this->object);
728  $questionSetConfig->loadFromDb();
729 
730  require_once 'Modules/Test/classes/class.ilTestRandomQuestionSetSourcePoolDefinitionFactory.php';
731  $sourcePoolDefinitionFactory = new ilTestRandomQuestionSetSourcePoolDefinitionFactory($ilDB, $this->object);
732 
733  require_once 'Modules/Test/classes/class.ilTestRandomQuestionSetSourcePoolDefinitionList.php';
734  $sourcePoolDefinitionList = new ilTestRandomQuestionSetSourcePoolDefinitionList($ilDB, $this->object, $sourcePoolDefinitionFactory);
735  $sourcePoolDefinitionList->loadDefinitions();
736 
737  $this->processLocker->executeRandomPassBuildOperation(function () use ($ilDB, $ilPluginAdmin, $questionSetConfig, $sourcePoolDefinitionList) {
739  require_once 'Modules/Test/classes/class.ilTestRandomQuestionSetStagingPoolQuestionList.php';
740  $stagingPoolQuestionList = new ilTestRandomQuestionSetStagingPoolQuestionList($ilDB, $ilPluginAdmin);
741 
742  require_once 'Modules/Test/classes/class.ilTestRandomQuestionSetBuilder.php';
743  $questionSetBuilder = ilTestRandomQuestionSetBuilder::getInstance($ilDB, $this->object, $questionSetConfig, $sourcePoolDefinitionList, $stagingPoolQuestionList);
744 
745  $questionSetBuilder->performBuild($this->testSession);
746  }
747  }, $sourcePoolDefinitionList->hasTaxonomyFilters());
748  }
749 
753  protected function resumePlayerCmd()
754  {
755  $this->handleUserSettings();
756 
757  $active_id = $this->testSession->getActiveId();
758  $this->ctrl->setParameter($this, "active_id", $active_id);
759 
760  $active_time_id = $this->object->startWorkingTime($active_id, $this->testSession->getPass());
761  $_SESSION["active_time_id"] = $active_time_id;
762  $_SESSION['tst_pass_finish'] = 0;
763 
764  if ($this->object->isRandomTest()) {
765  if (!$this->testSequence->hasRandomQuestionsForPass($active_id, $this->testSession->getPass())) {
766  // create a new set of random questions
768  }
769  }
770 
771  $shuffle = $this->object->getShuffleQuestions();
772  if ($this->object->isRandomTest()) {
773  $shuffle = false;
774  }
775 
776  assQuestion::_updateTestPassResults(
777  $active_id,
778  $this->testSession->getPass(),
779  $this->object->areObligationsEnabled(),
780  null,
781  $this->object->id
782  );
783 
784  // ensure existing test sequence
785  if (!$this->testSequence->hasSequence()) {
786  $this->testSequence->createNewSequence($this->object->getQuestionCount(), $shuffle);
787  $this->testSequence->saveToDb();
788  }
789 
790  if ($this->object->getListOfQuestionsStart()) {
791  $this->ctrl->redirect($this, ilTestPlayerCommands::QUESTION_SUMMARY);
792  }
793 
794  $this->ctrl->setParameter($this, 'sequence', $this->testSession->getLastSequence());
795  $this->ctrl->setParameter($this, 'pmode', '');
796  $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION);
797  }
798 
799  protected function isShowingPostponeStatusReguired($questionId)
800  {
801  return $this->testSequence->isPostponedQuestion($questionId);
802  }
803 
805  {
806  global $ilDB, $ilUser;
807 
808  $assSettings = new ilSetting('assessment');
809 
810  include_once("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
811  $isAssessmentLogEnabled = ilObjAssessmentFolder::_enabledAssessmentLogging();
812 
813  require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionUserSolutionAdopter.php';
814  $userSolutionAdopter = new ilAssQuestionUserSolutionAdopter($ilDB, $assSettings, $isAssessmentLogEnabled);
815 
816  $userSolutionAdopter->setUserId($ilUser->getId());
817  $userSolutionAdopter->setActiveId($this->testSession->getActiveId());
818  $userSolutionAdopter->setTargetPass($this->testSequence->getPass());
819  $userSolutionAdopter->setQuestionIds($this->testSequence->getOptionalQuestions());
820 
821  $userSolutionAdopter->perform();
822  }
823 
824  abstract protected function populateQuestionOptionalMessage();
825 
826  protected function isOptionalQuestionAnsweringConfirmationRequired($sequenceKey)
827  {
828  if ($this->testSequence->isAnsweringOptionalQuestionsConfirmed()) {
829  return false;
830  }
831 
832  $questionId = $this->testSequence->getQuestionForSequence($sequenceKey);
833 
834  if (!$this->testSequence->isQuestionOptional($questionId)) {
835  return false;
836  }
837 
838  return true;
839  }
840 
842  {
843  return true;
844  }
845 
847  {
848  ilUtil::sendFailure(sprintf($this->lng->txt('tst_objective_oriented_test_pass_without_questions'), $this->object->getTitle()), true);
849 
850  $this->backToInfoScreenCmd();
851  }
852 
856  protected function handlePrimaryButton(ilTestNavigationToolbarGUI $navigationToolbarGUI, $currentQuestionId)
857  {
858  $isNextPrimary = true;
859 
860  if ($this->object->isForceInstantFeedbackEnabled()) {
861  $isNextPrimary = false;
862  }
863 
864  $questionsMissingResult = assQuestion::getQuestionsMissingResultRecord(
865  $this->testSession->getActiveId(),
866  $this->testSession->getPass(),
867  $this->testSequence->getOrderedSequenceQuestions()
868  );
869 
870  if (!count($questionsMissingResult)) {
871  $navigationToolbarGUI->setFinishTestButtonPrimary(true);
872  $isNextPrimary = false;
873  } elseif (count($questionsMissingResult) == 1) {
874  $lastOpenQuestion = current($questionsMissingResult);
875 
876  if ($currentQuestionId == $lastOpenQuestion) {
877  $navigationToolbarGUI->setFinishTestButtonPrimary(true);
878  $isNextPrimary = false;
879  }
880  }
881 
882  return $isNextPrimary;
883  }
884 }
isShowingPostponeStatusReguired($questionId)
checkTestSessionUser(ilTestSession $testSession)
isValidSequenceElement($sequenceElement)
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 ...
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)
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 ...
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)
inits and adds the jQuery JS-File to the global or a passed template
getQuestionInstance($questionId, $fromCache=true)
handleTearsAndAngerQuestionIsNull($questionId, $sequenceElement)
isMaxProcessingTimeReached()
Checks wheather the maximum processing time is reached or not.
static redirect($a_script)
$_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.