ILIAS  release_5-0 Revision 5.0.0-1144-gc4397b1f870
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 {
25  public function executeCommand()
26  {
27  global $ilUser, $ilDB, $ilPluginAdmin, $lng, $ilTabs;
28 
29  $ilTabs->clearTargets();
30 
31  $cmd = $this->ctrl->getCmd();
32  $next_class = $this->ctrl->getNextClass($this);
33 
34  $this->ctrl->saveParameter($this, "sequence");
35  $this->ctrl->saveParameter($this, "active_id");
36 
37  if (preg_match("/^gotoquestion_(\\d+)$/", $cmd, $matches))
38  {
39  $cmd = "gotoquestion";
40  if (strlen($matches[1]))
41  {
42  $this->ctrl->setParameter($this, 'gotosequence', $matches[1]);
43  }
44  }
45 
46  $testSessionFactory = new ilTestSessionFactory($this->object);
47  $this->testSession = $testSessionFactory->getSession($_GET['active_id']);
48 
49  $this->ensureExistingTestSession($this->testSession);
50 
51  $this->initProcessLocker($this->testSession->getActiveId());
52 
53  $testSequenceFactory = new ilTestSequenceFactory($ilDB, $lng, $ilPluginAdmin, $this->object);
54  $this->testSequence = $testSequenceFactory->getSequence($this->testSession);
55  $this->testSequence->loadFromDb();
56  $this->testSequence->loadQuestions();
57 
58  include_once 'Services/jQuery/classes/class.iljQueryUtil.php';
60  include_once "./Services/YUI/classes/class.ilYuiUtil.php";
62 
64 
65  $cmd = $this->getCommand($cmd);
66 
67  switch($next_class)
68  {
69  case 'ilassquestionpagegui':
70 
71  $questionId = $this->testSequence->getQuestionForSequence( $this->calculateSequence() );
72 
73  require_once "./Modules/TestQuestionPool/classes/class.ilAssQuestionPageGUI.php";
74  $page_gui = new ilAssQuestionPageGUI($questionId);
75  $ret = $this->ctrl->forwardCommand($page_gui);
76  break;
77 
78  case 'iltestsubmissionreviewgui':
79  require_once './Modules/Test/classes/class.ilTestSubmissionReviewGUI.php';
80  $gui = new ilTestSubmissionReviewGUI($this, $this->object, $this->testSession);
81  $ret = $this->ctrl->forwardCommand($gui);
82  break;
83 
84  case 'ilassquestionhintrequestgui':
85 
86  $questionGUI = $this->object->createQuestionGUI(
87  "", $this->testSequence->getQuestionForSequence( $this->calculateSequence() )
88  );
89 
90  require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionHintTracking.php';
91  $questionHintTracking = new ilAssQuestionHintTracking(
92  $questionGUI->object->getId(), $this->testSession->getActiveId(), $this->testSession->getPass()
93  );
94 
95  require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionHintRequestGUI.php';
96  $gui = new ilAssQuestionHintRequestGUI($this, 'redirectQuestion', $questionGUI, $questionHintTracking);
97 
98  $ret = $this->ctrl->forwardCommand($gui);
99 
100  break;
101 
102  case 'iltestsignaturegui':
103  require_once './Modules/Test/classes/class.ilTestSignatureGUI.php';
104  $gui = new ilTestSignatureGUI($this);
105  $ret = $this->ctrl->forwardCommand($gui);
106  break;
107 
108  case 'iltestpasswordprotectiongui':
109  require_once 'Modules/Test/classes/class.ilTestPasswordProtectionGUI.php';
110  $gui = new ilTestPasswordProtectionGUI($this->ctrl, $this->tpl, $this->lng, $this, $this->passwordChecker);
111  $ret = $this->ctrl->forwardCommand($gui);
112  break;
113 
114  default:
115 
116  $cmd .= 'Cmd';
117  $ret =& $this->$cmd();
118  break;
119  }
120  return $ret;
121  }
122 
123  protected function startTestCmd()
124  {
125  $_GET['activecommand'] = 'start';
126  $this->redirectQuestionCmd();
127  }
128 
132  protected function nextQuestionCmd()
133  {
134  $questionId = $this->testSequence->getQuestionForSequence($_GET["sequence"]);
135 
136  if( !$this->isParticipantsAnswerFixed($questionId) )
137  {
138  $this->saveQuestionSolution();
139  }
140 
141  $this->ctrl->setParameter($this, "activecommand", "next");
142  $this->ctrl->redirect($this, "redirectQuestion");
143  }
144 
148  protected function previousQuestionCmd()
149  {
150  $questionId = $this->testSequence->getQuestionForSequence($_GET["sequence"]);
151 
152  if( !$this->isParticipantsAnswerFixed($questionId) )
153  {
154  $this->saveQuestionSolution();
155  }
156 
157  $this->ctrl->setParameter($this, "activecommand", "previous");
158  $this->ctrl->redirect($this, "redirectQuestion");
159  }
160 
168  protected function redirectQuestionCmd()
169  {
170  global $ilUser;
171 
172  // check the test restrictions to access the test in case one
173  // of the test navigation commands was called by an external script
174  // e.g. $ilNavigationHistory
175  $executable = $this->object->isExecutable($this->testSession, $ilUser->getId());
176  if (!$executable["executable"])
177  {
178  ilUtil::sendInfo($executable["errormessage"], TRUE);
179  $this->ctrl->redirectByClass("ilobjtestgui", "infoScreen");
180  }
181  switch ($_GET["activecommand"])
182  {
183  case "next":
184  $this->sequence = $this->calculateSequence();
185  if ($this->sequence === FALSE)
186  {
187  if ($this->object->getListOfQuestionsEnd())
188  {
189 
190  $allObligationsAnswered = ilObjTest::allObligationsAnswered(
191  $this->testSession->getTestId(),
192  $this->testSession->getActiveId(),
193  $this->testSession->getPass()
194  );
195 
196  if( $this->object->areObligationsEnabled() && !$allObligationsAnswered )
197  {
198  $this->ctrl->redirect($this, "outQuestionSummaryWithObligationsInfo");
199  }
200 
201  $this->outQuestionSummaryCmd();
202  }
203  else
204  {
205  $this->ctrl->redirect($this, "finishTest");
206  }
207  }
208  else
209  {
210  $this->testSession->setLastSequence($this->sequence);
211  $this->testSession->saveToDb();
212  $this->outTestPage(false);
213  }
214  break;
215  case "previous":
216  $this->sequence = $this->calculateSequence();
217  $this->testSession->setLastSequence($this->sequence);
218  $this->testSession->saveToDb();
219  if ($this->sequence === FALSE)
220  {
221  $this->ctrl->redirect($this, "outIntroductionPage");
222  }
223  else
224  {
225  $this->outTestPage(false);
226  }
227  break;
228  case "postpone":
229  $this->sequence = $this->calculateSequence();
230  $nextSequence = $this->testSequence->getNextSequence($this->sequence);
231  $this->testSequence->postponeSequence($this->sequence);
232  $this->testSequence->saveToDb();
233  $this->testSession->setLastSequence($nextSequence);
234  $this->testSession->saveToDb();
235  $this->sequence = $nextSequence;
236  $this->outTestPage(false);
237  break;
238  case "setmarked":
239  $this->sequence = $this->calculateSequence();
240  $this->testSession->setLastSequence($this->sequence);
241  $this->testSession->saveToDb();
242  $q_id = $this->testSequence->getQuestionForSequence($_GET["sequence"]);
243  $this->object->setQuestionSetSolved(1, $q_id, $ilUser->getId());
244  $this->outTestPage(false);
245  break;
246  case "resetmarked":
247  $this->sequence = $this->calculateSequence();
248  $this->testSession->setLastSequence($this->sequence);
249  $this->testSession->saveToDb();
250  $q_id = $this->testSequence->getQuestionForSequence($_GET["sequence"]);
251  $this->object->setQuestionSetSolved(0, $q_id, $ilUser->getId());
252  $this->outTestPage(false);
253  break;
254  case "directfeedback":
255  $this->sequence = $this->calculateSequence();
256  $this->testSession->setLastSequence($this->sequence);
257  $this->testSession->saveToDb();
258  $this->outTestPage(true);
259  break;
260  case "handleQuestionAction":
261  $this->sequence = $this->calculateSequence();
262  $this->testSession->setLastSequence($this->sequence);
263  $this->testSession->saveToDb();
264  $this->outTestPage(false);
265  break;
266  case "summary":
267  $this->ctrl->redirect($this, "outQuestionSummary");
268  break;
269  case "summary_obligations":
270  $this->ctrl->redirect($this, "outQuestionSummaryWithObligationsInfo");
271  break;
272  case "summary_obligations_only":
273  $this->ctrl->redirect($this, "outObligationsOnlySummary");
274  break;
275  case "start":
276  $_SESSION['tst_pass_finish'] = 0;
277 
278  // ensure existing test session
279  $this->testSession->setUserId($ilUser->getId());
280  $this->testSession->setAnonymousId($_SESSION["tst_access_code"][$this->object->getTestId()]);
281  $this->testSession->setObjectiveOrientedContainerId($this->getObjectiveOrientedContainerId());
282  $this->testSession->saveToDb();
283 
284  $active_id = $this->testSession->getActiveId();
285  $this->ctrl->setParameter($this, "active_id", $active_id);
286  $shuffle = $this->object->getShuffleQuestions();
287  if ($this->object->isRandomTest())
288  {
290 
291  $this->object->loadQuestions();
292  $shuffle = FALSE; // shuffle is already done during the creation of the random questions
293  }
294 
295  assQuestion::_updateTestPassResults(
296  $active_id, $this->testSession->getPass(), $this->object->areObligationsEnabled(), null, $this->object->id
297  );
298 
299  // ensure existing test sequence
300  if( !$this->testSequence->hasSequence() )
301  {
302  $this->testSequence->createNewSequence($this->object->getQuestionCount(), $shuffle);
303  $this->testSequence->saveToDb();
304  }
305 
306  if( $this->testSession->isObjectiveOriented() )
307  {
308  $this->testSequence->loadFromDb();
309  $this->testSequence->loadQuestions();
310 
312  $this->testSession, $this->testSequence
313  );
314  }
315 
316  $active_time_id = $this->object->startWorkingTime($this->testSession->getActiveId(), $this->testSession->getPass());
317  $_SESSION["active_time_id"] = $active_time_id;
318  if ($this->object->getListOfQuestionsStart())
319  {
320  $this->ctrl->setParameter($this, "activecommand", "summary");
321  $this->ctrl->redirect($this, "redirectQuestion");
322  }
323  else
324  {
325  $this->ctrl->setParameter($this, "sequence", $this->sequence);
326  $this->ctrl->setParameter($this, "activecommand", "gotoquestion");
327  $this->ctrl->saveParameter($this, "tst_javascript");
328  $this->ctrl->redirect($this, "redirectQuestion");
329  }
330  break;
331  case "resume":
332  $_SESSION['tst_pass_finish'] = 0;
333  $active_id = $this->testSession->getActiveId();
334  $this->ctrl->setParameter($this, "active_id", $active_id);
335 
336  if ($this->object->isRandomTest())
337  {
338  if (!$this->testSequence->hasRandomQuestionsForPass($active_id, $this->testSession->getPass()))
339  {
340  // create a new set of random questions
342  }
343  }
344  $shuffle = $this->object->getShuffleQuestions();
345  if ($this->object->isRandomTest())
346  {
347  $shuffle = FALSE;
348  }
349 
350  assQuestion::_updateTestPassResults(
351  $active_id, $this->testSession->getPass(), $this->object->areObligationsEnabled(), null, $this->object->id
352  );
353 
354  // ensure existing test sequence
355  if( !$this->testSequence->hasSequence() )
356  {
357  $this->testSequence->createNewSequence($this->object->getQuestionCount(), $shuffle);
358  $this->testSequence->saveToDb();
359  }
360 
361  $this->sequence = $this->testSession->getLastSequence();
362  $active_time_id = $this->object->startWorkingTime($active_id, $this->testSession->getPass());
363  $_SESSION["active_time_id"] = $active_time_id;
364  if ($this->object->getListOfQuestionsStart())
365  {
366  $this->ctrl->setParameter($this, "activecommand", "summary");
367  $this->ctrl->redirect($this, "redirectQuestion");
368  }
369  else
370  {
371  $this->ctrl->setParameter($this, "sequence", $this->sequence);
372  $this->ctrl->setParameter($this, "activecommand", "gotoquestion");
373  $this->ctrl->saveParameter($this, "tst_javascript");
374  $this->ctrl->redirect($this, "redirectQuestion");
375  }
376  break;
377 
378  case 'test_submission_overview':
379  require_once './Modules/Test/classes/class.ilTestSubmissionReviewGUI.php';
380  $this->ctrl->redirectByClass('ilTestSubmissionReviewGUI', "show");
381  break;
382 
383  case "back":
384  case "gotoquestion":
385  default:
386  $_SESSION['tst_pass_finish'] = 0;
387  if (array_key_exists("tst_javascript", $_GET))
388  {
389  $ilUser->writePref("tst_javascript", $_GET["tst_javascript"]);
390  }
391  $this->sequence = $this->calculateSequence();
392  if (strlen($_GET['gotosequence'])) $this->sequence = $_GET['gotosequence'];
393  $this->testSession->setLastSequence($this->sequence);
394  $this->testSession->saveToDb();
395  $this->outTestPage(false);
396  break;
397  }
398  }
399 
400  private function isValidSequenceElement($sequenceElement)
401  {
402  if( $sequenceElement < 1 )
403  {
404  return false;
405  }
406 
407  if( !$this->testSequence->getPositionOfSequence($sequenceElement) )
408  {
409  return false;
410  }
411 
412  return true;
413  }
414 
418  protected function outWorkingForm($sequence = "", $test_id, $postpone_allowed, $directfeedback = false)
419  {
420  global $ilUser;
421 
422  if( !$this->isValidSequenceElement($sequence) )
423  {
424  $sequence = $this->testSequence->getFirstSequence();
425  }
426 
427  $_SESSION["active_time_id"]= $this->object->startWorkingTime($this->testSession->getActiveId(),
428  $this->testSession->getPass()
429  );
430 
431  $this->populateContentStyleBlock();
432  $this->populateSyntaxStyleBlock();
433 
434  if ($this->object->getListOfQuestions())
435  {
436  $this->showSideList();
437  }
438 
439  $questionId = $this->testSequence->getQuestionForSequence($sequence);
440 
441  if( !(int)$questionId && $this->testSession->isObjectiveOriented() )
442  {
444  sprintf($this->lng->txt('tst_objective_oriented_test_pass_without_questions'), $this->object->getTitle()), true
445  );
446  $this->performCustomRedirect();
447  }
448 
449  $question_gui = $this->object->createQuestionGUI("", $questionId);
450 
451  if( !is_object($question_gui) )
452  {
453  global $ilLog;
454 
455  $ilLog->write(
456  "INV SEQ: active={$this->testSession->getActiveId()} qId=$questionId seq=$sequence "
457  .serialize($this->testSequence)
458  );
459 
460  $ilLog->logStack('INV SEQ');
461 
462  $this->ctrl->setParameter($this, 'gotosequence', $this->testSequence->getFirstSequence());
463  $this->ctrl->setParameter($this, 'activecommand', 'gotoquestion');
464  $this->ctrl->redirect($this, 'redirectQuestion');
465  }
466 
467  $question_gui->setTargetGui($this);
468 
469  if ($this->object->getJavaScriptOutput())
470  {
471  $question_gui->object->setOutputType(OUTPUT_JAVASCRIPT);
472  }
473 
474  $is_postponed = $this->testSequence->isPostponedQuestion($question_gui->object->getId());
475  $this->ctrl->setParameter($this, "sequence", "$sequence");
476  $formaction = $this->ctrl->getFormAction($this, "gotoQuestion");
477 
478  $question_gui->setSequenceNumber($this->testSequence->getPositionOfSequence($sequence));
479  $question_gui->setQuestionCount($this->testSequence->getUserQuestionCount());
480 
481 
482  // output question
483  $user_post_solution = FALSE;
484  if (array_key_exists("previouspost", $_SESSION))
485  {
486  $user_post_solution = $_SESSION["previouspost"];
487  unset($_SESSION["previouspost"]);
488  }
489 
490  // Determine $answer_feedback: It should hold a boolean stating if answer-specific-feedback is to be given.
491  // It gets the parameter "Scoring and Results" -> "Instant Feedback" -> "Show Answer-Specific Feedback"
492  // $directfeedback holds a boolean stating if the instant feedback was requested using the "Check" button.
493  $answer_feedback = FALSE;
494  if (($directfeedback) && ($this->object->getSpecificAnswerFeedback()))
495  {
496  $answer_feedback = TRUE;
497  }
498 
499  if( $this->isParticipantsAnswerFixed($questionId) )
500  {
501  $solutionoutput = $question_gui->getSolutionOutput(
502  $this->testSession->getActiveId(), #active_id
503  NULL, #pass
504  FALSE, #graphical_output
505  false, #result_output
506  true, #show_question_only
507  $answer_feedback, #show_feedback
508  false, #show_correct_solution
509  FALSE, #show_manual_scoring
510  true #show_question_text
511  );
512 
513  $pageoutput = $question_gui->outQuestionPage(
514  "", $this->testSequence->isPostponedQuestion($questionId),
515  $this->testSession->getActiveId(),
516  $solutionoutput
517  );
518 
519  $this->tpl->setVariable("QUESTION_OUTPUT", $pageoutput);
520  $this->tpl->setVariable("FORMACTION", $formaction);
521 
522  $directfeedback = true;
523  }
524  else
525  {
526  // Answer specific feedback is rendered into the display of the test question with in the concrete question types outQuestionForTest-method.
527  // Notation of the params prior to getting rid of this crap in favor of a class
528  $question_gui->outQuestionForTest(
529  $formaction, #form_action
530  $this->testSession->getActiveId(), #active_id
531  NULL, #pass
532  $is_postponed, #is_postponed
533  $user_post_solution, #user_post_solution
534  $answer_feedback #answer_feedback == inline_specific_feedback
535  );
536  // The display of specific inline feedback and specific feedback in an own block is to honor questions, which
537  // have the possibility to embed the specific feedback into their output while maintaining compatibility to
538  // questions, which do not have such facilities. E.g. there can be no "specific inline feedback" for essay
539  // questions, while the multiple-choice questions do well.
540 
541  $this->fillQuestionRelatedNavigation($question_gui);
542  }
543 
544  if ($directfeedback)
545  {
546  // This controls if the solution should be shown.
547  // It gets the parameter "Scoring and Results" -> "Instant Feedback" -> "Show Solutions"
548  if ($this->object->getInstantFeedbackSolution())
549  {
550  $show_question_inline_score = $this->determineInlineScoreDisplay();
551 
552  // Notation of the params prior to getting rid of this crap in favor of a class
553  $solutionoutput = $question_gui->getSolutionOutput(
554  $this->testSession->getActiveId(), #active_id
555  NULL, #pass
556  FALSE, #graphical_output
557  $show_question_inline_score, #result_output
558  FALSE, #show_question_only
559  FALSE, #show_feedback
560  TRUE, #show_correct_solution
561  FALSE, #show_manual_scoring
562  FALSE #show_question_text
563  );
564  $this->populateSolutionBlock( $solutionoutput );
565  }
566 
567  // This controls if the score should be shown.
568  // It gets the parameter "Scoring and Results" -> "Instant Feedback" -> "Show Results (Only Points)"
569  if ($this->object->getAnswerFeedbackPoints())
570  {
571  $reachedPoints = $question_gui->object->getAdjustedReachedPoints($this->testSession->getActiveId(), NULL);
572  $maxPoints = $question_gui->object->getMaximumPoints();
573 
574  $this->populateScoreBlock( $reachedPoints, $maxPoints );
575  }
576 
577  // This controls if the generic feedback should be shown.
578  // It gets the parameter "Scoring and Results" -> "Instant Feedback" -> "Show Solutions"
579  if ($this->object->getGenericAnswerFeedback())
580  {
581  $this->populateGenericFeedbackBlock( $question_gui );
582  }
583 
584  // This controls if the specific feedback should be shown.
585  // It gets the parameter "Scoring and Results" -> "Instant Feedback" -> "Show Answer-Specific Feedback"
586  if ($this->object->getSpecificAnswerFeedback())
587  {
588  $this->populateSpecificFeedbackBlock( $question_gui );
589  }
590  }
591 
593 
594  if ($postpone_allowed && !$is_postponed)
595  {
596  $this->populatePostponeButtons();
597  }
598 
599  if ($this->object->getListOfQuestions())
600  {
601  $this->populateSummaryButtons();
602  }
603 
604  if ($this->object->getShowCancel())
605  {
606  $this->populateCancelButtonBlock();
607  }
608 
609  if ($this->isLastQuestionInSequence( $question_gui ))
610  {
611  if ($this->object->getListOfQuestionsEnd())
612  {
614  }
615  else
616  {
618  }
619  }
620  else
621  {
623  }
624 
625  if ($this->object->getShowMarker())
626  {
627  include_once "./Modules/Test/classes/class.ilObjTest.php";
628  $solved_array = ilObjTest::_getSolvedQuestions($this->testSession->getActiveId(), $question_gui->object->getId());
629  $solved = 0;
630 
631  if (count ($solved_array) > 0)
632  {
633  $solved = array_pop($solved_array);
634  $solved = $solved["solved"];
635  }
636 
637  if ($solved==1)
638  {
640  }
641  else
642  {
644  }
645  }
646 
647  $this->populateCharSelector();
648 
649  if ($this->object->getJavaScriptOutput())
650  {
651  $this->tpl->setVariable("JAVASCRIPT_TITLE", $this->lng->txt("disable_javascript"));
652  $this->ctrl->setParameter($this, "tst_javascript", "0");
653  $this->tpl->setVariable("JAVASCRIPT_URL", $this->ctrl->getLinkTarget($this, "gotoQuestion"));
654  }
655  else
656  {
657  $this->tpl->setVariable("JAVASCRIPT_TITLE", $this->lng->txt("enable_javascript"));
658  $this->ctrl->setParameter($this, "tst_javascript", "1");
659  $this->tpl->setVariable("JAVASCRIPT_URL", $this->ctrl->getLinkTarget($this, "gotoQuestion"));
660  }
661 
662  if ($question_gui->object->requiresJsSwitch() && !$this->object->getForceJS())
663  {
664  $this->tpl->touchBlock("jsswitch");
665  }
666 
667  $this->tpl->addJavaScript(ilUtil::getJSLocation("autosave.js", "Modules/Test"));
668 
669  $this->tpl->setVariable("AUTOSAVE_URL", $this->ctrl->getFormAction($this, "autosave", "", true));
670 
671  if ($question_gui->isAutosaveable()&& $this->object->getAutosave())
672  {
673  $this->tpl->touchBlock('autosave');
674  //$this->tpl->setVariable("BTN_SAVE", "Zwischenspeichern");
675  //$this->tpl->setVariable("CMD_SAVE", "gotoquestion_{$sequence}");
676  //$this->tpl->setVariable("AUTOSAVEFORMACTION", str_replace("&amp;", "&", $this->ctrl->getFormAction($this)));
677  $this->tpl->setVariable("AUTOSAVEFORMACTION", str_replace("&amp;", "&", $this->ctrl->getLinkTarget($this, "autosave")));
678  $this->tpl->setVariable("AUTOSAVEINTERVAL", $this->object->getAutosaveIval());
679  }
680 
681  if( $this->object->areObligationsEnabled() && ilObjTest::isQuestionObligatory($question_gui->object->getId()) )
682  {
683  $this->tpl->touchBlock('question_obligatory');
684  $this->tpl->setVariable('QUESTION_OBLIGATORY', $this->lng->txt('required_field'));
685  }
686  }
687 
688  protected function isFirstPageInSequence($sequence)
689  {
690  return $sequence == $this->testSequence->getFirstSequence();
691  }
692 
693  protected function isLastQuestionInSequence(assQuestionGUI $question_gui)
694  {
695  return $this->testSequence->getQuestionForSequence($this->testSequence->getLastSequence()) == $question_gui->object->getId();
696  }
697 
703  protected function canSaveResult()
704  {
705  return !$this->object->endingTimeReached() && !$this->isMaxProcessingTimeReached() && !$this->isNrOfTriesReached();
706  }
707 
711  protected function getCurrentQuestionId()
712  {
713  return $this->testSequence->getQuestionForSequence($_GET["sequence"]);
714  }
715 
719  public function saveQuestionSolution($force = FALSE)
720  {
721  $this->updateWorkingTime();
722  $this->saveResult = FALSE;
723  if (!$force)
724  {
725  $formtimestamp = $_POST["formtimestamp"];
726  if (strlen($formtimestamp) == 0) $formtimestamp = $_GET["formtimestamp"];
727  if ($formtimestamp != $_SESSION["formtimestamp"])
728  {
729  $_SESSION["formtimestamp"] = $formtimestamp;
730  }
731  else
732  {
733  return FALSE;
734  }
735  }
736  // save question solution
737  if ($this->canSaveResult() || $force)
738  {
739  // but only if the ending time is not reached
740  $q_id = $this->testSequence->getQuestionForSequence($_GET["sequence"]);
741  if (is_numeric($q_id) && (int)$q_id)
742  {
743  global $ilUser;
744 
745  $question_gui = $this->object->createQuestionGUI("", $q_id);
746  if ($this->object->getJavaScriptOutput())
747  {
748  $question_gui->object->setOutputType(OUTPUT_JAVASCRIPT);
749  }
750  $pass = NULL;
751  $active_id = $this->testSession->getActiveId();
752  if ($this->object->isRandomTest())
753  {
754  $pass = $this->object->_getPass($active_id);
755  }
756  $this->saveResult = $question_gui->object->persistWorkingState(
757  $active_id, $pass, $this->object->areObligationsEnabled()
758  );
759 
760  // update learning progress (is done in ilTestSession)
761  //include_once("./Services/Tracking/classes/class.ilLPStatusWrapper.php");
762  //ilLPStatusWrapper::_updateStatus($this->object->getId(), $ilUser->getId());
763 
764  if( $this->testSession->isObjectiveOriented() )
765  {
767  $this->testSession, $this->testSequence, $question_gui->object
768  );
769  }
770  }
771  }
772  if ($this->saveResult == FALSE)
773  {
774  $this->ctrl->setParameter($this, "save_error", "1");
775  $_SESSION["previouspost"] = $_POST;
776  }
777  return $this->saveResult;
778  }
779 
780  protected function showInstantResponseCmd()
781  {
782  $questionId = $this->testSequence->getQuestionForSequence($_GET["sequence"]);
783 
784  if( !$this->isParticipantsAnswerFixed($questionId) )
785  {
786  $this->saveQuestionSolution();
787 
788  $this->testSequence->setQuestionChecked($questionId);
789  $this->testSequence->saveToDb();
790  }
791 
792  $this->ctrl->setParameter($this, "activecommand", "directfeedback");
793  $this->ctrl->redirect($this, "redirectQuestion");
794  }
795 
796  protected function showQuestionListCmd()
797  {
798  $questionId = $this->testSequence->getQuestionForSequence($_GET["sequence"]);
799 
800  if( !$this->isParticipantsAnswerFixed($questionId) )
801  {
802  $this->saveQuestionSolution();
803  }
804 
805  if ($this->saveResult == FALSE)
806  {
807  $this->ctrl->setParameter($this, "activecommand", "");
808  $this->ctrl->redirect($this, "redirectQuestion");
809  }
810  else
811  {
812  $this->ctrl->setParameter($this, "activecommand", "summary");
813  $this->ctrl->redirect($this, "redirectQuestion");
814  }
815  }
816 
817  protected function showQuestionListWithoutSavingCmd()
818  {
819  $this->ctrl->setParameter($this, "activecommand", "summary");
820  $this->ctrl->redirect($this, "redirectQuestion");
821  }
822 
828  protected function postponeQuestionCmd()
829  {
830  $questionId = $this->testSequence->getQuestionForSequence($_GET["sequence"]);
831 
832  if( !$this->isParticipantsAnswerFixed($questionId) )
833  {
834  $this->saveQuestionSolution();
835  }
836 
837  $this->ctrl->setParameter($this, "activecommand", "postpone");
838  $this->ctrl->redirect($this, "redirectQuestion");
839  }
840 
841  protected function handleQuestionActionCmd()
842  {
843  $questionId = $this->testSequence->getQuestionForSequence($_GET["sequence"]);
844 
845  if( !$this->isParticipantsAnswerFixed($questionId) )
846  {
847  $this->updateWorkingTime();
848  $this->saveQuestionSolution();
849  }
850 
851  $this->ctrl->setParameter($this, 'activecommand', 'handleQuestionAction');
852  $this->ctrl->redirect($this, 'redirectQuestion');
853  }
854 
856  {
857  if ($this->testSession->getActiveId() > 0)
858  {
859  if ($this->testSequence->hasRandomQuestionsForPass($this->testSession->getActiveId(), $this->testSession->getPass()) > 0)
860  {
861  // Something went wrong. Maybe the user pressed the start button twice
862  // Questions already exist so there is no need to create new questions
863 
864  global $ilLog, $ilUser;
865 
866  $ilLog->write(
867  __METHOD__.' Random Questions allready exists for user '.
868  $ilUser->getId().' in test '.$this->object->getTestId()
869  );
870 
871  return true;
872  }
873  }
874  else
875  {
876  // This may not happen! If it happens, raise a fatal error...
877 
878  global $ilLog, $ilUser;
879 
880  $ilLog->write(__METHOD__.' '.sprintf(
881  $this->lng->txt("error_random_question_generation"), $ilUser->getId(), $this->object->getTestId()
882  ));
883 
884  return true;
885  };
886 
887  return false;
888  }
889 
891  {
892  global $tree, $ilDB, $ilPluginAdmin;
893 
894  require_once 'Modules/Test/classes/class.ilTestRandomQuestionSetConfig.php';
895  $questionSetConfig = new ilTestRandomQuestionSetConfig($tree, $ilDB, $ilPluginAdmin, $this->object);
896  $questionSetConfig->loadFromDb();
897 
898  require_once 'Modules/Test/classes/class.ilTestRandomQuestionSetSourcePoolDefinitionFactory.php';
899  $sourcePoolDefinitionFactory = new ilTestRandomQuestionSetSourcePoolDefinitionFactory($ilDB, $this->object);
900 
901  require_once 'Modules/Test/classes/class.ilTestRandomQuestionSetSourcePoolDefinitionList.php';
902  $sourcePoolDefinitionList = new ilTestRandomQuestionSetSourcePoolDefinitionList($ilDB, $this->object, $sourcePoolDefinitionFactory);
903  $sourcePoolDefinitionList->loadDefinitions();
904 
905  $this->processLocker->requestRandomPassBuildLock($sourcePoolDefinitionList->hasTaxonomyFilters());
906 
908  {
909  require_once 'Modules/Test/classes/class.ilTestRandomQuestionSetStagingPoolQuestionList.php';
910  $stagingPoolQuestionList = new ilTestRandomQuestionSetStagingPoolQuestionList($ilDB, $ilPluginAdmin);
911 
912  require_once 'Modules/Test/classes/class.ilTestRandomQuestionSetBuilder.php';
913  $questionSetBuilder = ilTestRandomQuestionSetBuilder::getInstance($ilDB, $this->object, $questionSetConfig, $sourcePoolDefinitionList, $stagingPoolQuestionList);
914 
915  $questionSetBuilder->performBuild($this->testSession);
916  }
917 
918  $this->processLocker->releaseRandomPassBuildLock();
919  }
920 
921  protected function getObjectiveOrientedContainerId()
922  {
923  require_once 'Modules/Course/classes/Objectives/class.ilLOSettings.php';
924 
925  return (int)ilLOSettings::isObjectiveTest($this->testSession->getRefId());
926  }
927 
929  {
930  require_once 'Modules/Course/classes/Objectives/class.ilLOTestQuestionAdapter.php';
931 
932  ilLOTestQuestionAdapter::filterQuestions($testSession, $testSequence);
933  }
934 
936  {
937  require_once 'Modules/Course/classes/Objectives/class.ilLOTestQuestionAdapter.php';
938 
939  ilLOTestQuestionAdapter::updateObjectiveStatus($testSession, $testSequence, $question);
940 
941  $testSequence->saveToDb();
942  }
943 
944  protected function customRedirectRequired()
945  {
946  return $this->testSession->isObjectiveOriented();
947  }
948 
949  protected function performCustomRedirect()
950  {
951  $containerRefId = current(ilObject::_getAllReferences($this->testSession->getObjectiveOrientedContainerId()));
952 
953  require_once 'Services/Link/classes/class.ilLink.php';
954  $redirectTarget = ilLink::_getLink($containerRefId);
955 
956  ilUtil::redirect($redirectTarget);
957  }
958 }
< a tabindex="-1" style="border-style: none;" href="#" title="Refresh Image" onclick="document.getElementById('siimage').src = './securimage_show.php?sid=' + Math.random(); this.blur(); return false">< img src="./images/refresh.png" alt="Reload Image" height="32" width="32" onclick="this.blur()" align="bottom" border="0"/></a >< br/>< strong > Enter Code *if($_SERVER['REQUEST_METHOD']=='POST' &&@ $_POST['do']=='contact') $_SESSION['ctform']['success']
isValidSequenceElement($sequenceElement)
updateContainerObjectivesWithAnsweredQuestion(ilTestSession $testSession, ilTestSequence $testSequence, assQuestion $question)
static allObligationsAnswered($test_id, $active_id, $pass)
checks wether all questions marked as obligatory were answered within the test pass with given testId...
$_POST['username']
Definition: cron.php:12
outTestPage($directfeedback)
Outputs the question of the active sequence.
Signature Plugin Class.
$_GET["client_id"]
Abstract basic class which is to be extended by the concrete assessment question type classes...
static getInstance(ilDB $db, ilObjTest $testOBJ, ilTestRandomQuestionSetConfig $questionSetConfig, ilTestRandomQuestionSetSourcePoolDefinitionList $sourcePoolDefinitionList, ilTestRandomQuestionSetStagingPoolQuestionList $stagingPoolQuestionList)
Output class for assessment test execution.
static updateObjectiveStatus(ilTestSession $a_test_session, ilTestSequence $a_test_sequence, assQuestion $a_question)
Store result and update objective 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
previousQuestionCmd()
Go to the previous question.
static isObjectiveTest($a_trst_ref_id)
Check if test ref_id is used in an objective course.
isLastQuestionInSequence(assQuestionGUI $question_gui)
executeCommand()
Execute Command.
_getSolvedQuestions($active_id, $question_fi=null)
get solved questions
const OUTPUT_JAVASCRIPT
Question page GUI class.
static _getAllReferences($a_id)
get all reference ids of object
Test sequence handler.
saveQuestionSolution($force=FALSE)
saves the user input of a question
calculateSequence()
Calculates the sequence to determine the next question.
static isQuestionObligatory($question_id)
checks wether the question with given id is marked as obligatory or not
static sendInfo($a_info="", $a_keep=false)
Send Info Message to Screen.
saveToDb()
Saves the sequence data for a given pass to the database.
ensureExistingTestSession(ilTestSession $testSession)
filterTestSequenceByObjectives(ilTestSession $testSession, ilTestSequence $testSequence)
fillQuestionRelatedNavigation(assQuestionGUI $questionGUI)
renders the elements for the question related navigation
static filterQuestions(ilTestSession $a_test_session, ilTestSequence $a_test_sequence)
Called from learning objective test.
Class ilTestSubmissionReviewGUI.
static getJSLocation($a_js_name, $a_js_location="", $add_version=FALSE)
get full javascript file name (path inclusive) of current user
getCommand($cmd)
Retrieves the ilCtrl command.
postponeQuestionCmd()
Postpone a question to the end of the test.
nextQuestionCmd()
Go to the next question.
Test session handler.
isFirstPageInSequence($sequence)
Basic GUI class for assessment questions.
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
redirectQuestionCmd()
Called when a user answered a question to perform a redirect after POST.
outQuestionSummaryCmd($fullpage=true, $contextFinishTest=false, $obligationsNotAnswered=false, $obligationsFilter=false)
Output of a summary of all test questions for test participants.
global $ilUser
Definition: imgupload.php:15
global $ilDB
static initjQuery($a_tpl=null)
Init jQuery.
isMaxProcessingTimeReached()
Checks wheather the maximum processing time is reached or not.
static redirect($a_script)
http redirect to other script
static initConnectionWithAnimation()
Init YUI Connection module.
canSaveResult()
Returns TRUE if the answers of the current user could be saved.
populateScoreBlock($reachedPoints, $maxPoints)
outWorkingForm($sequence="", $test_id, $postpone_allowed, $directfeedback=false)
Creates the learners output of a question.
Output class for assessment test execution.