ILIAS  Release_4_2_x_branch Revision 61807
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilTestOutputGUI.php
Go to the documentation of this file.
1 <?php
2 
3 /* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
4 
5 include_once "./Modules/Test/classes/inc.AssessmentConstants.php";
6 include_once "./Modules/Test/classes/class.ilTestServiceGUI.php";
7 
21 {
22  var $ref_id;
23 
25  var $sequence;
26  var $cmdCtrl;
29 
38  function ilTestOutputGUI($a_object)
39  {
40  parent::ilTestServiceGUI($a_object);
41  $this->ref_id = $_GET["ref_id"];
42  }
43 
44  /*
45  * Save tags for tagging gui
46  *
47  * Needed this function here because the test info page
48  * uses another class to send its form results
49  */
50  function saveTags()
51  {
52  include_once("./Services/Tagging/classes/class.ilTaggingGUI.php");
53  $tagging_gui = new ilTaggingGUI();
54  $tagging_gui->setObject($this->object->getId(), $this->object->getType());
55  $tagging_gui->saveInput();
56  $this->ctrl->redirectByClass("ilobjtestgui", "infoScreen");
57  }
58 
62  function executeCommand()
63  {
64  $cmd = $this->ctrl->getCmd();
65  $next_class = $this->ctrl->getNextClass($this);
66  $this->ctrl->saveParameter($this, "sequence");
67  $this->ctrl->saveParameter($this, "active_id");
68  if (preg_match("/^gotoquestion_(\\d+)$/", $cmd, $matches))
69  {
70  $cmd = "gotoquestion";
71  if (strlen($matches[1]))
72  {
73  $this->ctrl->setParameter($this, 'gotosequence', $matches[1]);
74  }
75 
76  }
77  if ($_GET["active_id"])
78  {
79  $this->object->setTestSession($_GET["active_id"]);
80  }
81  else
82  {
83  $this->object->setTestSession();
84  }
85  include_once 'Services/jQuery/classes/class.iljQueryUtil.php';
87  include_once "./Services/YUI/classes/class.ilYuiUtil.php";
89  $cmd = $this->getCommand($cmd);
90  switch($next_class)
91  {
92  default:
93  $ret =& $this->$cmd();
94  break;
95  }
96  return $ret;
97  }
98 
103  function updateWorkingTime()
104  {
105  if ($_SESSION["active_time_id"])
106  {
107  $this->object->updateWorkingTime($_SESSION["active_time_id"]);
108  }
109  }
110 
114  function saveQuestionSolution($force = FALSE)
115  {
116  $this->updateWorkingTime();
117  $this->saveResult = FALSE;
118  if (!$force)
119  {
120  $formtimestamp = $_POST["formtimestamp"];
121  if (strlen($formtimestamp) == 0) $formtimestamp = $_GET["formtimestamp"];
122  if ($formtimestamp != $_SESSION["formtimestamp"])
123  {
124  $_SESSION["formtimestamp"] = $formtimestamp;
125  }
126  else
127  {
128  return FALSE;
129  }
130  }
131  // save question solution
132  if ($this->canSaveResult() || $force)
133  {
134  // but only if the ending time is not reached
135  $q_id = $this->object->getTestSequence()->getQuestionForSequence($_GET["sequence"]);
136  if (is_numeric($q_id))
137  {
138  global $ilUser;
139 
140  $question_gui = $this->object->createQuestionGUI("", $q_id);
141  if ($this->object->getJavaScriptOutput())
142  {
143  $question_gui->object->setOutputType(OUTPUT_JAVASCRIPT);
144  }
145  $pass = NULL;
146  $active_id = $this->object->getTestSession()->getActiveId();
147  if ($this->object->isRandomTest())
148  {
149  $pass = $this->object->_getPass($active_id);
150  }
151  $this->saveResult = $question_gui->object->saveWorkingData($active_id, $pass);
152 
153  // update learning progress (is done in ilTestSession)
154  //include_once("./Services/Tracking/classes/class.ilLPStatusWrapper.php");
155  //ilLPStatusWrapper::_updateStatus($this->object->getId(), $ilUser->getId());
156  }
157  }
158  if ($this->saveResult == FALSE)
159  {
160  $this->ctrl->setParameter($this, "save_error", "1");
161  $_SESSION["previouspost"] = $_POST;
162  }
163  return $this->saveResult;
164  }
165 
174  function canSaveResult()
175  {
176  return !$this->object->endingTimeReached() && !$this->isMaxProcessingTimeReached() && !$this->isNrOfTriesReached();
177  }
178 
187  {
188  $this->ctrl->redirectByClass("ilobjtestgui", "infoScreen");
189  }
190 
200  {
201  global $ilUser;
202  $active_id = $this->object->getTestSession()->getActiveId();
203  $starting_time = $this->object->getStartingTimeOfUser($active_id);
204  if ($starting_time === FALSE)
205  {
206  return FALSE;
207  }
208  else
209  {
210  return $this->object->isMaxProcessingTimeReached($starting_time);
211  }
212  }
213 
217  public function outWorkingForm($sequence = "", $test_id, $postpone_allowed, $directfeedback = 0)
218  {
219  global $ilUser;
220 
221  if ($sequence < 1) $sequence = $this->object->getTestSequence()->getFirstSequence();
222  $active_time_id = $this->object->startWorkingTime($this->object->getTestSession()->getActiveId(), $this->object->getTestSession()->getPass());
223  $_SESSION["active_time_id"] = $active_time_id;
224 
225  include_once("./Services/Style/classes/class.ilObjStyleSheet.php");
226  $this->tpl->setCurrentBlock("ContentStyle");
227  $this->tpl->setVariable("LOCATION_CONTENT_STYLESHEET",
229  $this->tpl->parseCurrentBlock();
230 
231  // syntax style
232  $this->tpl->setCurrentBlock("SyntaxStyle");
233  $this->tpl->setVariable("LOCATION_SYNTAX_STYLESHEET",
235  $this->tpl->parseCurrentBlock();
236 
237  if ($this->object->getListOfQuestions())
238  {
239  $show_side_list = $ilUser->getPref('side_list_of_questions');
240  $this->tpl->setCurrentBlock('view_sidelist');
241  $this->tpl->setVariable('IMAGE_SIDELIST', ($show_side_list) ? ilUtil::getImagePath('view_remove.png') : ilUtil::getImagePath('view_choose.png'));
242  $this->tpl->setVariable('TEXT_SIDELIST', ($show_side_list) ? $this->lng->txt('tst_hide_side_list') : $this->lng->txt('tst_show_side_list'));
243  $this->tpl->parseCurrentBlock();
244  if ($show_side_list)
245  {
246  $this->tpl->addCss(ilUtil::getStyleSheetLocation("output", "ta_split.css", "Modules/Test"), "screen");
247  $this->outQuestionSummary(false);
248  }
249  }
250 
251  $question_gui = $this->object->createQuestionGUI("", $this->object->getTestSequence()->getQuestionForSequence($sequence));
252  if ($this->object->getJavaScriptOutput())
253  {
254  $question_gui->object->setOutputType(OUTPUT_JAVASCRIPT);
255  }
256 
257  $is_postponed = $this->object->getTestSequence()->isPostponedQuestion($question_gui->object->getId());
258  $this->ctrl->setParameter($this, "sequence", "$sequence");
259  $formaction = $this->ctrl->getFormAction($this, "gotoQuestion");
260 
261  $question_gui->setSequenceNumber($this->object->getTestSequence()->getPositionOfSequence($sequence));
262  $question_gui->setQuestionCount($this->object->getTestSequence()->getUserQuestionCount());
263  // output question
264  $user_post_solution = FALSE;
265  if (array_key_exists("previouspost", $_SESSION))
266  {
267  $user_post_solution = $_SESSION["previouspost"];
268  unset($_SESSION["previouspost"]);
269  }
270  $answer_feedback = FALSE;
271  if (($directfeedback) && ($this->object->getAnswerFeedback()))
272  {
273  $answer_feedback = TRUE;
274  }
275  global $ilNavigationHistory;
276  $ilNavigationHistory->addItem($_GET["ref_id"], $this->ctrl->getLinkTarget($this, "resume"), "tst");
277  $question_gui->outQuestionForTest($formaction, $this->object->getTestSession()->getActiveId(), NULL, $is_postponed, $user_post_solution, $answer_feedback);
278  if ($directfeedback)
279  {
280  if ($this->object->getInstantFeedbackSolution())
281  {
282  $solutionoutput = $question_gui->getSolutionOutput($this->object->getTestSession()->getActiveId(), NULL, FALSE, FALSE, FALSE, FALSE, TRUE);
283  $this->tpl->setCurrentBlock("solution_output");
284  $this->tpl->setVariable("CORRECT_SOLUTION", $this->lng->txt("tst_best_solution_is"));
285  $this->tpl->setVariable("QUESTION_FEEDBACK", $solutionoutput);
286  $this->tpl->parseCurrentBlock();
287  }
288  if ($this->object->getAnswerFeedbackPoints())
289  {
290  $this->tpl->setCurrentBlock("solution_output");
291  $this->tpl->setVariable("RECEIVED_POINTS_INFORMATION", sprintf($this->lng->txt("you_received_a_of_b_points"), $question_gui->object->calculateReachedPoints($this->object->getTestSession()->getActiveId(), NULL), $question_gui->object->getMaximumPoints()));
292  $this->tpl->parseCurrentBlock();
293  }
294  if ($this->object->getAnswerFeedback())
295  {
296  $this->tpl->setCurrentBlock("answer_feedback");
297  $this->tpl->setVariable("ANSWER_FEEDBACK", $question_gui->getAnswerFeedbackOutput($this->object->getTestSession()->getActiveId(), NULL));
298  $this->tpl->parseCurrentBlock();
299  }
300  }
301 
302  if ($sequence == $this->object->getTestSequence()->getFirstSequence())
303  {
304  $this->tpl->setCurrentBlock("prev");
305  $this->tpl->setVariable("BTN_PREV", "&lt;&lt; " . $this->lng->txt("save_introduction"));
306  $this->tpl->parseCurrentBlock();
307  $this->tpl->setCurrentBlock("prev_bottom");
308  $this->tpl->setVariable("BTN_PREV", "&lt;&lt; " . $this->lng->txt("save_introduction"));
309  $this->tpl->parseCurrentBlock();
310  }
311  else
312  {
313  $this->tpl->setCurrentBlock("prev");
314  $this->tpl->setVariable("BTN_PREV", "&lt;&lt; " . $this->lng->txt("save_previous"));
315  $this->tpl->parseCurrentBlock();
316  $this->tpl->setCurrentBlock("prev_bottom");
317  $this->tpl->setVariable("BTN_PREV", "&lt;&lt; " . $this->lng->txt("save_previous"));
318  $this->tpl->parseCurrentBlock();
319  }
320 
321  if ($postpone_allowed)
322  {
323  if (!$is_postponed)
324  {
325  if (!$finish)
326  {
327  $this->tpl->setCurrentBlock("postpone");
328  $this->tpl->setVariable("BTN_POSTPONE", $this->lng->txt("postpone"));
329  $this->tpl->parseCurrentBlock();
330  $this->tpl->setCurrentBlock("postpone_bottom");
331  $this->tpl->setVariable("BTN_POSTPONE", $this->lng->txt("postpone"));
332  $this->tpl->parseCurrentBlock();
333  }
334  }
335  }
336 
337  if ($this->object->getListOfQuestions())
338  {
339  if (!(($finish) && ($this->object->getListOfQuestionsEnd())))
340  {
341  $this->tpl->setCurrentBlock("summary");
342  $this->tpl->setVariable("BTN_SUMMARY", $this->lng->txt("question_summary"));
343  $this->tpl->parseCurrentBlock();
344  $this->tpl->setCurrentBlock("summary_bottom");
345  $this->tpl->setVariable("BTN_SUMMARY", $this->lng->txt("question_summary"));
346  $this->tpl->parseCurrentBlock();
347  }
348  }
349 
350  if ($this->object->getShowCancel())
351  {
352  $this->tpl->setCurrentBlock("cancel_test");
353  $this->tpl->setVariable("TEXT_CANCELTEST", $this->lng->txt("cancel_test"));
354  $this->tpl->setVariable("TEXT_ALTCANCELTEXT", $this->lng->txt("cancel_test"));
355  $this->tpl->setVariable("TEXT_TITLECANCELTEXT", $this->lng->txt("cancel_test"));
356  $this->tpl->setVariable("HREF_IMGCANCELTEST", $this->ctrl->getLinkTargetByClass(get_class($this), "outIntroductionPage") . "&cancelTest=true");
357  $this->tpl->setVariable("HREF_CANCELTEXT", $this->ctrl->getLinkTargetByClass(get_class($this), "outIntroductionPage") . "&cancelTest=true");
358  $this->tpl->setVariable("IMAGE_CANCEL", ilUtil::getImagePath("cancel.gif"));
359  $this->tpl->parseCurrentBlock();
360  }
361 
362  if ($this->object->getTestSequence()->getQuestionForSequence($this->object->getTestSequence()->getLastSequence()) == $question_gui->object->getId())
363  {
364  if ($this->object->getListOfQuestionsEnd())
365  {
366  $this->tpl->setCurrentBlock("next");
367  $this->tpl->setVariable("BTN_NEXT", $this->lng->txt("question_summary") . " &gt;&gt;");
368  $this->tpl->parseCurrentBlock();
369  $this->tpl->setCurrentBlock("next_bottom");
370  $this->tpl->setVariable("BTN_NEXT", $this->lng->txt("question_summary") . " &gt;&gt;");
371  $this->tpl->parseCurrentBlock();
372  }
373  else
374  {
375  $this->tpl->setCurrentBlock("next");
376  $this->tpl->setVariable("BTN_NEXT", $this->lng->txt("save_finish") . " &gt;&gt;");
377  $this->tpl->parseCurrentBlock();
378  $this->tpl->setCurrentBlock("next_bottom");
379  $this->tpl->setVariable("BTN_NEXT", $this->lng->txt("save_finish") . " &gt;&gt;");
380  $this->tpl->parseCurrentBlock();
381  }
382  }
383  else
384  {
385  $this->tpl->setCurrentBlock("next");
386  $this->tpl->setVariable("BTN_NEXT", $this->lng->txt("save_next") . " &gt;&gt;");
387  $this->tpl->parseCurrentBlock();
388  $this->tpl->setCurrentBlock("next_bottom");
389  $this->tpl->setVariable("BTN_NEXT", $this->lng->txt("save_next") . " &gt;&gt;");
390  $this->tpl->parseCurrentBlock();
391  }
392 
393  if ($this->object->getShowMarker())
394  {
395  include_once "./Modules/Test/classes/class.ilObjTest.php";
396  $solved_array = ilObjTest::_getSolvedQuestions($this->object->getTestSession()->getActiveId(), $question_gui->object->getId());
397  $solved = 0;
398 
399  if (count ($solved_array) > 0)
400  {
401  $solved = array_pop($solved_array);
402  $solved = $solved["solved"];
403  }
404 
405  if ($solved==1)
406  {
407  $this->tpl->setCurrentBlock("ismarked");
408  $this->tpl->setVariable("IMAGE_SET", ilUtil::getImagePath("marked.png"));
409  $this->tpl->setVariable("TEXT_SET", $this->lng->txt("tst_remove_mark"));
410  $this->tpl->parseCurrentBlock();
411  }
412  else
413  {
414  $this->tpl->setCurrentBlock("isnotmarked");
415  $this->tpl->setVariable("IMAGE_UNSET", ilUtil::getImagePath("marked_.png"));
416  $this->tpl->setVariable("TEXT_UNSET", $this->lng->txt("tst_question_mark"));
417  $this->tpl->parseCurrentBlock();
418  }
419  }
420 
421  if ($this->object->getJavaScriptOutput())
422  {
423  $this->tpl->setVariable("JAVASCRIPT_IMAGE", ilUtil::getImagePath("javascript_disable.png"));
424  $this->tpl->setVariable("JAVASCRIPT_IMAGE_ALT", $this->lng->txt("disable_javascript"));
425  $this->tpl->setVariable("JAVASCRIPT_IMAGE_TITLE", $this->lng->txt("disable_javascript"));
426  $this->ctrl->setParameter($this, "tst_javascript", "0");
427  $this->tpl->setVariable("JAVASCRIPT_URL", $this->ctrl->getLinkTarget($this, "gotoQuestion"));
428  }
429  else
430  {
431  $this->tpl->setVariable("JAVASCRIPT_IMAGE", ilUtil::getImagePath("javascript.png"));
432  $this->tpl->setVariable("JAVASCRIPT_IMAGE_ALT", $this->lng->txt("enable_javascript"));
433  $this->tpl->setVariable("JAVASCRIPT_IMAGE_TITLE", $this->lng->txt("enable_javascript"));
434  $this->ctrl->setParameter($this, "tst_javascript", "1");
435  $this->tpl->setVariable("JAVASCRIPT_URL", $this->ctrl->getLinkTarget($this, "gotoQuestion"));
436  }
437 
438  if ($question_gui->object->supportsJavascriptOutput())
439  {
440  $this->tpl->touchBlock("jsswitch");
441  }
442 
443  $this->tpl->addJavaScript(ilUtil::getJSLocation("autosave.js", "Modules/Test"));
444  $this->tpl->setVariable("AUTOSAVE_URL", $this->ctrl->getFormAction($this, "autosave", "", true));
445  }
446 
453  {
454  $template = new ilTemplate("tpl.il_as_tst_password_protection.html", TRUE, TRUE, "Modules/Test");
455  $template->setVariable("FORMACTION", $this->ctrl->getFormAction($this, "checkPassword"));
456  $template->setVariable("PASSWORD_INTRODUCTION", $this->lng->txt("tst_password_introduction"));
457  $template->setVariable("TEXT_PASSWORD", $this->lng->txt("tst_password"));
458  $template->setVariable("SUBMIT", $this->lng->txt("submit"));
459  $this->tpl->setVariable($this->getContentBlockName(), $template->get());
460  }
461 
467  function checkPassword()
468  {
469  if (strcmp($this->object->getPassword(), $_POST["password"]) == 0)
470  {
471  global $ilUser;
472  if ($_SESSION["AccountId"] != ANONYMOUS_USER_ID)
473  {
474  $ilUser->setPref("tst_password_".$this->object->getTestId(), $this->object->getPassword());
475  $ilUser->writePref("tst_password_".$this->object->getTestId(), $this->object->getPassword());
476  }
477  else
478  {
479  $_SESSION['tst_password_'.$this->object->getTestId()] = $this->object->getPassword();
480  }
481  $this->ctrl->redirect($this, "start");
482  }
483  else
484  {
485  ilUtil::sendFailure($this->lng->txt("tst_password_entered_wrong_password"), true);
486  $this->ctrl->redirectByClass("ilobjtestgui", "infoScreen");
487  }
488  }
489 
497  function setAnonymousId()
498  {
499  if ($_SESSION["AccountId"] == ANONYMOUS_USER_ID)
500  {
501  $this->object->setAccessCodeSession($_POST["anonymous_id"]);
502  }
503  $this->ctrl->redirectByClass("ilobjtestgui", "infoScreen");
504  }
505 
514  function start()
515  {
516  if (strcmp($_SESSION["lock"], $_POST["lock"]) != 0)
517  {
518  $_SESSION["lock"] = $_POST["lock"];
519  $this->handleStartCommands();
520  $this->ctrl->redirect($this, "startTest");
521  }
522  else
523  {
524  $this->ctrl->redirectByClass("ilobjtestgui", "redirectToInfoScreen");
525  }
526  }
527 
533  function startTest()
534  {
535  if ($this->object->checkMaximumAllowedUsers() == FALSE)
536  {
538  }
539  if ($_SESSION["AccountId"] == ANONYMOUS_USER_ID)
540  {
541  $this->object->setAccessCodeSession($this->object->createNewAccessCode());
542  }
543  else
544  {
545  $this->object->unsetAccessCodeSession();
546  }
547  if (strlen($this->object->getPassword()))
548  {
549  global $ilUser;
550  global $rbacsystem;
551 
552  $pwd = '';
553  if( $_SESSION["AccountId"] != ANONYMOUS_USER_ID )
554  {
555  $pwd = $ilUser->getPref("tst_password_".$this->object->getTestId());
556  }
557  elseif( isset($_SESSION['tst_password_'.$this->object->getTestId()]) )
558  {
559  $pwd = $_SESSION['tst_password_'.$this->object->getTestId()];
560  }
561 
562  if ((strcmp($pwd, $this->object->getPassword()) != 0) && (!$rbacsystem->checkAccess("write", $this->object->getRefId())))
563  {
564  return $this->showPasswordProtectionPage();
565  }
566  }
567  if ($_SESSION["AccountId"] == ANONYMOUS_USER_ID)
568  {
569  $this->ctrl->redirect($this, "displayCode");
570  }
571  else
572  {
573  $this->ctrl->setParameter($this, "activecommand", "start");
574  $this->ctrl->redirect($this, "redirectQuestion");
575  }
576  }
577 
578  function displayCode()
579  {
580  $this->tpl->addBlockFile($this->getContentBlockName(), "adm_content", "tpl.il_as_tst_anonymous_code_presentation.html", "Modules/Test");
581  $this->tpl->setCurrentBlock("adm_content");
582  $this->tpl->setVariable("TEXT_ANONYMOUS_CODE_CREATED", $this->lng->txt("tst_access_code_created"));
583  $this->tpl->setVariable("TEXT_ANONYMOUS_CODE", $this->object->getAccessCodeSession());
584  $this->tpl->setVariable("FORMACTION", $this->ctrl->getFormAction($this));
585  $this->tpl->setVariable("CONTINUE", $this->lng->txt("continue_work"));
586  $this->tpl->parseCurrentBlock();
587  }
588 
589  function codeConfirmed()
590  {
591  $this->ctrl->setParameter($this, "activecommand", "start");
592  $this->ctrl->redirect($this, "redirectQuestion");
593  }
594 
602  function resume()
603  {
604  if ($this->object->checkMaximumAllowedUsers() == FALSE)
605  {
607  }
608  $this->handleStartCommands();
609  $this->ctrl->setParameter($this, "activecommand", "resume");
610  $this->ctrl->redirect($this, "redirectQuestion");
611  }
612 
616  public function handleStartCommands()
617  {
618  global $ilUser;
619 
620  if ($_POST["chb_javascript"])
621  {
622  $ilUser->writePref("tst_javascript", 1);
623  }
624  else
625  {
626  $ilUser->writePref("tst_javascript", 0);
627  }
628 
629  // hide previous results
630  if ($this->object->getNrOfTries() != 1)
631  {
632  if ($this->object->getUsePreviousAnswers() == 1)
633  {
634  if ($_POST["chb_use_previous_answers"])
635  {
636  $ilUser->writePref("tst_use_previous_answers", 1);
637  }
638  else
639  {
640  $ilUser->writePref("tst_use_previous_answers", 0);
641  }
642  }
643  }
644 /* if ($this->object->getTestType() == TYPE_ONLINE_TEST)
645  {
646  global $ilias;
647  $ilias->auth->setIdle(0, false);
648  }*/
649  }
650 
657  function redirectQuestion()
658  {
659  global $ilUser;
660 
661  // check the test restrictions to access the test in case one
662  // of the test navigation commands was called by an external script
663  // e.g. $ilNavigationHistory
664  $executable = $this->object->isExecutable($ilUser->getId());
665  if (!$executable["executable"])
666  {
667  ilUtil::sendInfo($executable["errormessage"], TRUE);
668  $this->ctrl->redirectByClass("ilobjtestgui", "infoScreen");
669  }
670  switch ($_GET["activecommand"])
671  {
672  case "next":
673  $this->sequence = $this->calculateSequence();
674  if ($this->sequence === FALSE)
675  {
676  if ($this->object->getListOfQuestionsEnd())
677  {
678  $this->outQuestionSummary();
679  }
680  else
681  {
682  $this->ctrl->redirect($this, "finishTest");
683  }
684  }
685  else
686  {
687  $this->object->getTestSession()->setLastSequence($this->sequence);
688  $this->object->getTestSession()->saveToDb();
689  $this->outTestPage();
690  }
691  break;
692  case "previous":
693  $this->sequence = $this->calculateSequence();
694  $this->object->getTestSession()->setLastSequence($this->sequence);
695  $this->object->getTestSession()->saveToDb();
696  if ($this->sequence === FALSE)
697  {
698  $this->ctrl->redirect($this, "outIntroductionPage");
699  }
700  else
701  {
702  $this->outTestPage();
703  }
704  break;
705  case "postpone":
706  $this->sequence = $this->calculateSequence();
707  $nextSequence = $this->object->getTestSequence()->getNextSequence($this->sequence);
708  $this->object->getTestSequence()->postponeSequence($this->sequence);
709  $this->object->getTestSequence()->saveToDb();
710  $this->object->getTestSession()->setLastSequence($nextSequence);
711  $this->object->getTestSession()->saveToDb();
712  $this->sequence = $nextSequence;
713  $this->outTestPage();
714  break;
715  case "setmarked":
716  $this->sequence = $this->calculateSequence();
717  $this->object->getTestSession()->setLastSequence($this->sequence);
718  $this->object->getTestSession()->saveToDb();
719  $q_id = $this->object->getTestSequence()->getQuestionForSequence($_GET["sequence"]);
720  $this->object->setQuestionSetSolved(1, $q_id, $ilUser->getId());
721  $this->outTestPage();
722  break;
723  case "resetmarked":
724  $this->sequence = $this->calculateSequence();
725  $this->object->getTestSession()->setLastSequence($this->sequence);
726  $this->object->getTestSession()->saveToDb();
727  $q_id = $this->object->getTestSequence()->getQuestionForSequence($_GET["sequence"]);
728  $this->object->setQuestionSetSolved(0, $q_id, $ilUser->getId());
729  $this->outTestPage();
730  break;
731  case "directfeedback":
732  $this->sequence = $this->calculateSequence();
733  $this->object->getTestSession()->setLastSequence($this->sequence);
734  $this->object->getTestSession()->saveToDb();
735  $this->outTestPage();
736  break;
737  case "selectImagemapRegion":
738  $this->sequence = $this->calculateSequence();
739  $this->object->getTestSession()->setLastSequence($this->sequence);
740  $this->object->getTestSession()->saveToDb();
741  $this->outTestPage();
742  break;
743  case "summary":
744  $this->ctrl->redirect($this, "outQuestionSummary");
745  break;
746  case "start":
747  $_SESSION['tst_pass_finish'] = 0;
748  $this->object->createTestSession();
749  $active_id = $this->object->getTestSession()->getActiveId();
750  $this->ctrl->setParameter($this, "active_id", $active_id);
751  $shuffle = $this->object->getShuffleQuestions();
752  if ($this->object->isRandomTest())
753  {
754  $this->object->generateRandomQuestions($this->object->getTestSession()->getActiveId());
755  $this->object->loadQuestions();
756  $shuffle = FALSE; // shuffle is already done during the creation of the random questions
757  }
758  require_once 'Modules/TestQuestionPool/classes/class.assQuestion.php';
760  $active_id, $this->object->getTestSession()->getPass()
761  );
762 
763  $this->object->createTestSequence($active_id, 0, $shuffle);
764  $active_time_id = $this->object->startWorkingTime($this->object->getTestSession()->getActiveId(), $this->object->getTestSession()->getPass());
765  $_SESSION["active_time_id"] = $active_time_id;
766  if ($this->object->getListOfQuestionsStart())
767  {
768  $this->ctrl->setParameter($this, "activecommand", "summary");
769  $this->ctrl->redirect($this, "redirectQuestion");
770  }
771  else
772  {
773  $this->ctrl->setParameter($this, "sequence", $this->sequence);
774  $this->ctrl->setParameter($this, "activecommand", "gotoquestion");
775  $this->ctrl->saveParameter($this, "tst_javascript");
776  $this->ctrl->redirect($this, "redirectQuestion");
777  }
778  break;
779  case "resume":
780  $_SESSION['tst_pass_finish'] = 0;
781  $active_id = $this->object->getTestSession()->getActiveId();
782  $this->ctrl->setParameter($this, "active_id", $active_id);
783 
784  if ($this->object->isRandomTest())
785  {
786  if (!$this->object->hasRandomQuestionsForPass($active_id, $this->object->getTestSession()->getPass()))
787  {
788  // create a new set of random questions
789  $this->object->generateRandomQuestions($active_id, $this->object->getTestSession()->getPass());
790  }
791  }
792  $shuffle = $this->object->getShuffleQuestions();
793  if ($this->object->isRandomTest())
794  {
795  $shuffle = FALSE;
796  }
797 
798  require_once 'Modules/TestQuestionPool/classes/class.assQuestion.php';
800  $active_id, $this->object->getTestSession()->getPass()
801  );
802 
803  $this->object->createTestSequence($active_id, $this->object->getTestSession()->getPass(), $shuffle);
804 
805  $this->sequence = $this->object->getTestSession()->getLastSequence();
806  $active_time_id = $this->object->startWorkingTime($active_id, $this->object->getTestSession()->getPass());
807  $_SESSION["active_time_id"] = $active_time_id;
808  if ($this->object->getListOfQuestionsStart())
809  {
810  $this->ctrl->setParameter($this, "activecommand", "summary");
811  $this->ctrl->redirect($this, "redirectQuestion");
812  }
813  else
814  {
815  $this->ctrl->setParameter($this, "sequence", $this->sequence);
816  $this->ctrl->setParameter($this, "activecommand", "gotoquestion");
817  $this->ctrl->saveParameter($this, "tst_javascript");
818  $this->ctrl->redirect($this, "redirectQuestion");
819  }
820  break;
821  case "back":
822  case "gotoquestion":
823  default:
824  $_SESSION['tst_pass_finish'] = 0;
825  if (array_key_exists("tst_javascript", $_GET))
826  {
827  $ilUser->writePref("tst_javascript", $_GET["tst_javascript"]);
828  }
829  $this->sequence = $this->calculateSequence();
830  if (strlen($_GET['gotosequence'])) $this->sequence = $_GET['gotosequence'];
831  $this->object->getTestSession()->setLastSequence($this->sequence);
832  $this->object->getTestSession()->saveToDb();
833  $this->outTestPage();
834  break;
835  }
836  }
837 
843  function calculateSequence()
844  {
845  $sequence = $_GET["sequence"];
846  if (!$sequence) $sequence = $this->object->getTestSequence()->getFirstSequence();
847  if (array_key_exists("save_error", $_GET))
848  {
849  if ($_GET["save_error"] == 1)
850  {
851  return $sequence;
852  }
853  }
854  switch ($_GET["activecommand"])
855  {
856  case "next":
857  $sequence = $this->object->getTestSequence()->getNextSequence($sequence);
858  break;
859  case "previous":
860  $sequence = $this->object->getTestSequence()->getPreviousSequence($sequence);
861  break;
862  }
863  return $sequence;
864  }
865 
867  {
868  $this->tpl->addBlockFile($this->getContentBlockName(), "adm_content", "tpl.il_as_tst_redirect_autosave.html", "Modules/Test");
869  $this->tpl->setVariable("TEXT_REDIRECT", $this->lng->txt("redirectAfterSave"));
870  $this->tpl->setCurrentBlock("HeadContent");
871  $this->tpl->setVariable("CONTENT_BLOCK", "<meta http-equiv=\"refresh\" content=\"5; url=" . $this->ctrl->getLinkTarget($this, "redirectBack") . "\">");
872  $this->tpl->parseCurrentBlock();
873  }
874 
875  function autosave()
876  {
877  global $ilLog;
878  $result = "";
879  if (is_array($_POST) && count($_POST) > 0)
880  {
881  $res = $this->saveQuestionSolution(TRUE);
882  if ($res)
883  {
884  $result = $this->lng->txt("autosave_success");
885  }
886  else
887  {
888  $result = $this->lng->txt("autosave_failed");
889  }
890  }
891  if (!$this->canSaveResult())
892  {
893  // this was the last action in the test, saving is no longer allowed
894  $result = $this->ctrl->getLinkTarget($this, "redirectAfterAutosave", "", true);
895  }
896  echo $result;
897  exit;
898  }
899 
903  public function togglesidelist()
904  {
905  global $ilUser;
906 
907  $show_side_list = $ilUser->getPref('side_list_of_questions');
908  $ilUser->writePref('side_list_of_questions', !$show_side_list);
909  $this->saveQuestionSolution();
910  $this->ctrl->redirect($this, "redirectQuestion");
911  }
912 
920  function next()
921  {
922  $this->saveQuestionSolution();
923  $this->ctrl->setParameter($this, "activecommand", "next");
924  $this->ctrl->redirect($this, "redirectQuestion");
925  }
926 
934  function previous()
935  {
936  $this->saveQuestionSolution();
937  $this->ctrl->setParameter($this, "activecommand", "previous");
938  $this->ctrl->redirect($this, "redirectQuestion");
939  }
940 
948  function postpone()
949  {
950  $this->saveQuestionSolution();
951  $this->ctrl->setParameter($this, "activecommand", "postpone");
952  $this->ctrl->redirect($this, "redirectQuestion");
953  }
954 
962  function summary()
963  {
964  $this->saveQuestionSolution();
965  if ($this->saveResult == FALSE)
966  {
967  $this->ctrl->setParameter($this, "activecommand", "");
968  $this->ctrl->redirect($this, "redirectQuestion");
969  }
970  else
971  {
972  $this->ctrl->setParameter($this, "activecommand", "summary");
973  $this->ctrl->redirect($this, "redirectQuestion");
974  }
975  }
976 
984  function setmarked()
985  {
986  $this->saveQuestionSolution();
987  $this->ctrl->setParameter($this, "activecommand", "setmarked");
988  $this->ctrl->redirect($this, "redirectQuestion");
989  }
990 
998  function resetmarked()
999  {
1000  $this->saveQuestionSolution();
1001  $this->ctrl->setParameter($this, "activecommand", "resetmarked");
1002  $this->ctrl->redirect($this, "redirectQuestion");
1003  }
1004 
1012  function directfeedback()
1013  {
1014  $this->saveQuestionSolution();
1015  $this->ctrl->setParameter($this, "activecommand", "directfeedback");
1016  $this->ctrl->redirect($this, "redirectQuestion");
1017  }
1018 
1027  {
1028  $this->saveQuestionSolution();
1029  $activecommand = "selectImagemapRegion";
1030  if (array_key_exists('cmd', $_POST))
1031  {
1032  $activecommand = key($_POST["cmd"]);
1033  }
1034  if (preg_match("/^gotoquestion_(\\d+)$/", $activecommand, $matches))
1035  {
1036  $activecommand = "gotoquestion";
1037  if (strlen($matches[1]))
1038  {
1039  $this->ctrl->setParameter($this, 'gotosequence', $matches[1]);
1040  }
1041  }
1042  if (strcmp($activecommand, "togglesidelist") == 0)
1043  {
1044  $this->togglesidelist();
1045  }
1046  else
1047  {
1048  $this->ctrl->setParameter($this, "activecommand", $activecommand);
1049  $this->ctrl->redirect($this, "redirectQuestion");
1050  }
1051  }
1052 
1060  function gotoQuestion()
1061  {
1062  if (is_array($_POST) && count($_POST) > 0) $this->saveQuestionSolution();
1063  $this->ctrl->setParameter($this, "sequence", $_GET["sequence"]);
1064  $this->ctrl->setParameter($this, "activecommand", "gotoquestion");
1065  $this->ctrl->saveParameter($this, "tst_javascript");
1066  if (strlen($_GET['qst_selection'])) $_SESSION['qst_selection'] = $_GET['qst_selection'];
1067  $this->ctrl->redirect($this, "redirectQuestion");
1068  }
1069 
1077  function backFromSummary()
1078  {
1079  $this->ctrl->setParameter($this, "activecommand", "back");
1080  $this->ctrl->redirect($this, "redirectQuestion");
1081  }
1082 
1090  function confirmFinish()
1091  {
1092  $this->finishTest(false);
1093  }
1094 
1103  {
1104  global $ilUser;
1105 
1106  $template = new ilTemplate("tpl.il_as_tst_finish_confirmation.html", TRUE, TRUE, "Modules/Test");
1107  $template->setVariable("FINISH_QUESTION", $this->lng->txt("tst_finish_confirmation_question"));
1108  $template->setVariable("BUTTON_CONFIRM", $this->lng->txt("tst_finish_confirm_button"));
1109  if ($this->object->canShowSolutionPrintview($ilUser->getId()))
1110  {
1111  $template->setVariable("BUTTON_CANCEL", $this->lng->txt("tst_finish_confirm_list_of_answers_button"));
1112  }
1113  else
1114  {
1115  $template->setVariable("BUTTON_CANCEL", $this->lng->txt("tst_finish_confirm_cancel_button"));
1116  }
1117  $template->setVariable("FORMACTION", $this->ctrl->getFormAction($this));
1118  $this->tpl->setVariable($this->getContentBlockName(), $template->get());
1119  }
1120 
1128  function finishTest($confirm = true)
1129  {
1130  global $ilUser;
1131  global $ilias;
1132  global $ilAuth;
1133 
1134  unset($_SESSION["tst_next"]);
1135 
1136  $active_id = $this->object->getTestSession()->getActiveId();
1137  $actualpass = $this->object->_getPass($active_id);
1138  if (($actualpass == $this->object->getNrOfTries() - 1) && (!$confirm))
1139  {
1140  $ilAuth->setIdle(ilSession::getIdleValue(), false);
1141  $ilAuth->setExpire(0);
1142  switch ($this->object->getMailNotification())
1143  {
1144  case 1:
1145  $this->object->sendSimpleNotification($active_id);
1146  break;
1147  case 2:
1148  $this->object->sendAdvancedNotification($active_id);
1149  break;
1150  }
1151  }
1152 
1153  if (($confirm) && ($actualpass == $this->object->getNrOfTries() - 1))
1154  {
1155  if ($this->object->canShowSolutionPrintview($ilUser->getId()))
1156  {
1157  $template = new ilTemplate("tpl.il_as_tst_finish_navigation.html", TRUE, TRUE, "Modules/Test");
1158  $template->setVariable("BUTTON_FINISH", $this->lng->txt("btn_next"));
1159  $template->setVariable("BUTTON_CANCEL", $this->lng->txt("btn_previous"));
1160 
1161  $template_top = new ilTemplate("tpl.il_as_tst_list_of_answers_topbuttons.html", TRUE, TRUE, "Modules/Test");
1162  $template_top->setCurrentBlock("button_print");
1163  $template_top->setVariable("BUTTON_PRINT", $this->lng->txt("print"));
1164  $template_top->parseCurrentBlock();
1165 
1166  $this->showListOfAnswers($active_id, NULL, $template_top->get(), $template->get());
1167  return;
1168  }
1169  else
1170  {
1171  // show confirmation page
1172  return $this->confirmFinishTest();
1173  }
1174  }
1175 
1176  if (!$_SESSION['tst_pass_finish'])
1177  {
1178  if (!$_SESSION['tst_pass_finish']) $_SESSION['tst_pass_finish'] = 1;
1179  if ($this->object->getMailNotificationType() == 1)
1180  {
1181  switch ($this->object->getMailNotification())
1182  {
1183  case 1:
1184  $this->object->sendSimpleNotification($active_id);
1185  break;
1186  case 2:
1187  $this->object->sendAdvancedNotification($active_id);
1188  break;
1189  }
1190  }
1191  if( !$this->object->getTestSession()->isSubmitted() )
1192  {
1193  $this->object->setActiveTestSubmitted($ilUser->getId());
1194  }
1195  $this->object->getTestSession()->increaseTestPass();
1196  }
1197  $this->redirectBack();
1198  }
1199 
1200  public function redirectBack()
1201  {
1202  if (!$_GET["skipfinalstatement"])
1203  {
1204  if ($this->object->getShowFinalStatement())
1205  {
1206  $this->ctrl->redirect($this, "showFinalStatement");
1207  }
1208  }
1209  if($_GET['crs_show_result'])
1210  {
1211  $this->ctrl->redirectByClass("ilobjtestgui", "backToCourse");
1212  }
1213 
1214  if (!$this->object->canViewResults())
1215  {
1216  $this->outIntroductionPage();
1217  }
1218  else
1219  {
1220  $this->ctrl->redirectByClass("ilTestEvaluationGUI", "outUserResultsOverview");
1221  }
1222  }
1223 
1224  /*
1225  * Presents the final statement of a test
1226  */
1227  public function showFinalStatement()
1228  {
1229  $template = new ilTemplate("tpl.il_as_tst_final_statement.html", TRUE, TRUE, "Modules/Test");
1230  $this->ctrl->setParameter($this, "crs_show_result", $_GET['crs_show_result']);
1231  $this->ctrl->setParameter($this, "skipfinalstatement", 1);
1232  $template->setVariable("FORMACTION", $this->ctrl->getFormAction($this, "redirectBack"));
1233  $template->setVariable("FINALSTATEMENT", $this->object->getFinalStatement());
1234  $template->setVariable("BUTTON_CONTINUE", $this->lng->txt("btn_next"));
1235  $this->tpl->setVariable($this->getContentBlockName(), $template->get());
1236  }
1237 
1238  private function getKioskHead()
1239  {
1240  global $ilUser;
1241 
1242  $template = new ilTemplate('tpl.il_as_tst_kiosk_head.html', true, true, 'Modules/Test');
1243  if ($this->object->getShowKioskModeTitle())
1244  {
1245  $template->setCurrentBlock("kiosk_show_title");
1246  $template->setVariable("TEST_TITLE", $this->object->getTitle());
1247  $template->parseCurrentBlock();
1248  }
1249  if ($this->object->getShowKioskModeParticipant())
1250  {
1251  $template->setCurrentBlock("kiosk_show_participant");
1252  $template->setVariable("PARTICIPANT_NAME", $this->lng->txt("login_as") . " " . $ilUser->getFullname());
1253  $template->parseCurrentBlock();
1254  }
1255  return $template->get();
1256  }
1257 
1261  function outTestPage()
1262  {
1263  global $rbacsystem, $ilUser;
1264 
1265  $this->tpl->addBlockFile($this->getContentBlockName(), "adm_content", "tpl.il_as_tst_output.html", "Modules/Test");
1266  if (!$rbacsystem->checkAccess("read", $this->object->getRefId()))
1267  {
1268  // only with read access it is possible to run the test
1269  $this->ilias->raiseError($this->lng->txt("cannot_execute_test"),$this->ilias->error_obj->MESSAGE);
1270  }
1271 
1272  if ($this->isMaxProcessingTimeReached())
1273  {
1274  $this->maxProcessingTimeReached();
1275  return;
1276  }
1277 
1278  if ($this->object->endingTimeReached())
1279  {
1280  $this->endingTimeReached();
1281  return;
1282  }
1283 
1284  if ($this->object->getKioskMode())
1285  {
1286  ilUtil::sendInfo();
1287  $head = $this->getKioskHead();
1288  if (strlen($head))
1289  {
1290  $this->tpl->setCurrentBlock("kiosk_options");
1291  $this->tpl->setVariable("KIOSK_HEAD", $head);
1292  $this->tpl->parseCurrentBlock();
1293  }
1294  }
1295 
1296  if (($this->object->getInstantFeedbackSolution() == 1) || ($this->object->getAnswerFeedback() == 1) || ($this->object->getAnswerFeedbackPoints() == 1))
1297  {
1298  $this->tpl->setCurrentBlock("direct_feedback");
1299  $this->tpl->setVariable("TEXT_DIRECT_FEEDBACK", $this->lng->txt("check"));
1300  $this->tpl->parseCurrentBlock();
1301  }
1302 
1303  $postpone = false;
1304  if ($this->object->getSequenceSettings() == TEST_POSTPONE)
1305  {
1306  $postpone = true;
1307  }
1308 
1309  if ($this->object->getEnableProcessingTime())
1310  {
1311  $this->outProcessingTime($this->object->getTestSession()->getActiveId());
1312  }
1313 
1314  $this->tpl->setVariable("FORM_TIMESTAMP", time());
1315  $directfeedback = 0;
1316  if (strcmp($_GET["activecommand"], "directfeedback") == 0) $directfeedback = 1;
1317  $this->outWorkingForm($this->sequence, $this->object->getTestId(), $postpone, $directfeedback, $show_summary);
1318  $this->tpl->setVariable("PAGETITLE", "- " . $this->object->getTitle());
1319  }
1320 
1329  {
1330  global $ilUser;
1331 
1332  // check if user is invited to participate
1333  $user = $this->object->getInvitedUsers($ilUser->getId());
1334  if (!is_array ($user) || count($user)!=1)
1335  {
1336  ilUtil::sendInfo($this->lng->txt("user_not_invited"), true);
1337  $this->ctrl->redirectByClass("ilobjtestgui", "backToRepository");
1338  }
1339 
1340  $user = array_pop($user);
1341  // check if client ip is set and if current remote addr is equal to stored client-ip
1342  if (strcmp($user["clientip"],"")!=0 && strcmp($user["clientip"],$_SERVER["REMOTE_ADDR"])!=0)
1343  {
1344  ilUtil::sendInfo($this->lng->txt("user_wrong_clientip"), true);
1345  $this->ctrl->redirectByClass("ilobjtestgui", "backToRepository");
1346  }
1347  }
1348 
1349 
1353  function isTestAccessible()
1354  {
1355  return !$this->isNrOfTriesReached()
1356  and !$this->isMaxProcessingTimeReached()
1357  and $this->object->startingTimeReached()
1358  and !$this->object->endingTimeReached();
1359  }
1360 
1365  {
1366  return $this->object->hasNrOfTriesRestriction() && $this->object->isNrOfTriesReached($this->object->getTestSession()->getPass());
1367  }
1368 
1376  function passDetails()
1377  {
1378  if (array_key_exists("pass", $_GET) && (strlen($_GET["pass"]) > 0))
1379  {
1380  $this->ctrl->saveParameter($this, "pass");
1381  $this->ctrl->saveParameter($this, "active_id");
1382  $this->outTestResults(false, $_GET["pass"]);
1383  }
1384  else
1385  {
1386  $this->outTestResults(false);
1387  }
1388  }
1389 
1395  function endingTimeReached()
1396  {
1397  ilUtil::sendInfo(sprintf($this->lng->txt("detail_ending_time_reached"), ilFormat::ftimestamp2datetimeDB($this->object->getEndingTime())));
1398  $this->object->getTestSession()->increasePass();
1399  $this->object->getTestSession()->setLastSequence(0);
1400  $this->object->getTestSession()->saveToDb();
1401  if (!$this->object->canViewResults())
1402  {
1403  $this->outIntroductionPage();
1404  }
1405  else
1406  {
1407  $this->ctrl->redirectByClass("ilTestEvaluationGUI", "outUserResultsOverview");
1408  }
1409  }
1410 
1419  {
1420  $this->outIntroductionPage();
1421  }
1422 
1429  {
1430  $this->tpl->addBlockFile($this->getContentBlockName(), "adm_content", "tpl.il_as_tst_submit_answers_confirm.html", "Modules/Test");
1431  $this->tpl->setCurrentBlock("adm_content");
1432  if ($this->object->isTestFinished($this->object->getTestSession()->getActiveId()))
1433  {
1434  $this->tpl->setCurrentBlock("not_submit_allowed");
1435  $this->tpl->setVariable("TEXT_ALREADY_SUBMITTED", $this->lng->txt("tst_already_submitted"));
1436  $this->tpl->setVariable("BTN_OK", $this->lng->txt("tst_show_answer_sheet"));
1437  } else
1438  {
1439  $this->tpl->setCurrentBlock("submit_allowed");
1440  $this->tpl->setVariable("TEXT_CONFIRM_SUBMIT_RESULTS", $this->lng->txt("tst_confirm_submit_answers"));
1441  $this->tpl->setVariable("BTN_OK", $this->lng->txt("tst_submit_results"));
1442  }
1443  $this->tpl->setVariable("BTN_BACK", $this->lng->txt("back"));
1444  $this->tpl->setVariable("FORMACTION", $this->ctrl->getFormAction($this, "finalSubmission"));
1445  $this->tpl->parseCurrentBlock();
1446  }
1447 
1448  function outProcessingTime($active_id)
1449  {
1450  global $ilUser;
1451 
1452  $starting_time = $this->object->getStartingTimeOfUser($active_id);
1453  $processing_time = $this->object->getProcessingTimeInSeconds();
1454  $processing_time_minutes = floor($processing_time / 60);
1455  $processing_time_seconds = $processing_time - $processing_time_minutes * 60;
1456  $str_processing_time = "";
1457  if ($processing_time_minutes > 0)
1458  {
1459  $str_processing_time = $processing_time_minutes . " " . $this->lng->txt("minutes");
1460  }
1461  if ($processing_time_seconds > 0)
1462  {
1463  if (strlen($str_processing_time) > 0) $str_processing_time .= " " . $this->lng->txt("and") . " ";
1464  $str_processing_time .= $processing_time_seconds . " " . $this->lng->txt("seconds");
1465  }
1466  $time_left = $starting_time + $processing_time - mktime();
1467  $time_left_minutes = floor($time_left / 60);
1468  $time_left_seconds = $time_left - $time_left_minutes * 60;
1469  $str_time_left = "";
1470  if ($time_left_minutes > 0)
1471  {
1472  $str_time_left = $time_left_minutes . " " . $this->lng->txt("minutes");
1473  }
1474  if ($time_left < 300)
1475  {
1476  if ($time_left_seconds > 0)
1477  {
1478  if (strlen($str_time_left) > 0) $str_time_left .= " " . $this->lng->txt("and") . " ";
1479  $str_time_left .= $time_left_seconds . " " . $this->lng->txt("seconds");
1480  }
1481  }
1482  $date = getdate($starting_time);
1483  $formattedStartingTime = ilDatePresentation::formatDate(new ilDateTime($date,IL_CAL_FKT_GETDATE));
1484  /*
1485  $formattedStartingTime = ilFormat::formatDate(
1486  $date["year"]."-".
1487  sprintf("%02d", $date["mon"])."-".
1488  sprintf("%02d", $date["mday"])." ".
1489  sprintf("%02d", $date["hours"]).":".
1490  sprintf("%02d", $date["minutes"]).":".
1491  sprintf("%02d", $date["seconds"])
1492  );
1493  */
1494  $datenow = getdate();
1495  $this->tpl->setCurrentBlock("enableprocessingtime");
1496  $this->tpl->setVariable("USER_WORKING_TIME",
1497  sprintf(
1498  $this->lng->txt("tst_time_already_spent"),
1499  $formattedStartingTime,
1500  $str_processing_time
1501  )
1502  );
1503  $this->tpl->setVariable("USER_REMAINING_TIME", sprintf($this->lng->txt("tst_time_already_spent_left"), $str_time_left));
1504  $this->tpl->parseCurrentBlock();
1505  $template = new ilTemplate("tpl.workingtime.js.html", TRUE, TRUE, TRUE);
1506  $template->setVariable("STRING_MINUTE", $this->lng->txt("minute"));
1507  $template->setVariable("STRING_MINUTES", $this->lng->txt("minutes"));
1508  $template->setVariable("STRING_SECOND", $this->lng->txt("second"));
1509  $template->setVariable("STRING_SECONDS", $this->lng->txt("seconds"));
1510  $template->setVariable("STRING_TIMELEFT", $this->lng->txt("tst_time_already_spent_left"));
1511  $template->setVariable("AND", strtolower($this->lng->txt("and")));
1512  $template->setVariable("YEAR", $date["year"]);
1513  $template->setVariable("MONTH", $date["mon"]-1);
1514  $template->setVariable("DAY", $date["mday"]);
1515  $template->setVariable("HOUR", $date["hours"]);
1516  $template->setVariable("MINUTE", $date["minutes"]);
1517  $template->setVariable("SECOND", $date["seconds"]);
1518  if (preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->object->getEndingTime(), $matches))
1519  {
1520  $template->setVariable("ENDYEAR", $matches[1]);
1521  $template->setVariable("ENDMONTH", $matches[2]-1);
1522  $template->setVariable("ENDDAY", $matches[3]);
1523  $template->setVariable("ENDHOUR", $matches[4]);
1524  $template->setVariable("ENDMINUTE", $matches[5]);
1525  $template->setVariable("ENDSECOND", $matches[6]);
1526  }
1527  $template->setVariable("YEARNOW", $datenow["year"]);
1528  $template->setVariable("MONTHNOW", $datenow["mon"]-1);
1529  $template->setVariable("DAYNOW", $datenow["mday"]);
1530  $template->setVariable("HOURNOW", $datenow["hours"]);
1531  $template->setVariable("MINUTENOW", $datenow["minutes"]);
1532  $template->setVariable("SECONDNOW", $datenow["seconds"]);
1533  $template->setVariable("PTIME_M", $processing_time_minutes);
1534  $template->setVariable("PTIME_S", $processing_time_seconds);
1535 
1536  $this->tpl->setCurrentBlock("HeadContent");
1537  $this->tpl->setVariable("CONTENT_BLOCK", $template->get());
1538  $this->tpl->parseCurrentBlock();
1539  }
1540 
1544  public function outQuestionSummary($fullpage = true)
1545  {
1546  if ($fullpage) $this->tpl->addBlockFile($this->getContentBlockName(), "adm_content", "tpl.il_as_tst_question_summary.html", "Modules/Test");
1547  $active_id = $this->object->getTestSession()->getActiveId();
1548  $result_array = & $this->object->getTestSequence()->getSequenceSummary();
1549  $marked_questions = array();
1550  if ($this->object->getKioskMode() && $fullpage)
1551  {
1552  $head = $this->getKioskHead();
1553  if (strlen($head))
1554  {
1555  $this->tpl->setCurrentBlock("kiosk_options");
1556  $this->tpl->setVariable("KIOSK_HEAD", $head);
1557  $this->tpl->parseCurrentBlock();
1558  }
1559  }
1560  if ($this->object->getShowMarker())
1561  {
1562  include_once "./Modules/Test/classes/class.ilObjTest.php";
1563  $marked_questions = ilObjTest::_getSolvedQuestions($active_id);
1564  }
1565  $data = array();
1566  foreach ($result_array as $key => $value)
1567  {
1568  $this->ctrl->setParameter($this, "sequence", $value["sequence"]);
1569  $href = $this->ctrl->getLinkTargetByClass(get_class($this), "gotoQuestion");
1570  $this->tpl->setVariable("VALUE_QUESTION_TITLE", "<a href=\"".$this->ctrl->getLinkTargetByClass(get_class($this), "gotoQuestion")."\">" . $this->object->getQuestionTitle($value["title"]) . "</a>");
1571  $this->ctrl->setParameter($this, "sequence", $_GET["sequence"]);
1572  $description = "";
1573  if ($this->object->getListOfQuestionsDescription())
1574  {
1575  $description = $value["description"];
1576  }
1577  $points = "";
1578  if (!$this->object->getTitleOutput())
1579  {
1580  $points = $value["points"]."&nbsp;".$this->lng->txt("points_short");
1581  }
1582  $marked = false;
1583  if (count($marked_questions))
1584  {
1585  if (array_key_exists($value["qid"], $marked_questions))
1586  {
1587  $obj = $marked_questions[$value["qid"]];
1588  if ($obj["solved"] == 1)
1589  {
1590  $marked = true;
1591  }
1592  }
1593  }
1594  array_push($data, array(
1595  'order' => $value["nr"],
1596  'href' => $href,
1597  'title' => $this->object->getQuestionTitle($value["title"]),
1598  'description' => $description,
1599  'worked_through' => ($value["worked_through"]) ? true : false,
1600  'postponed' => ($value["postponed"]) ? $this->lng->txt("postponed") : '',
1601  'points' => $points,
1602  'marked' => $marked,
1603  'sequence' => $value["sequence"]
1604  ));
1605  }
1606  $this->ctrl->setParameter($this, "sequence", $_GET["sequence"]);
1607  if ($fullpage)
1608  {
1609  include_once "./Modules/Test/classes/tables/class.ilListOfQuestionsTableGUI.php";
1610  $table_gui = new ilListOfQuestionsTableGUI($this, 'backFromSummary', !$this->object->getTitleOutput(), $this->object->getShowMarker());
1611  $table_gui->setData($data);
1612  $this->tpl->setVariable('TABLE_LIST_OF_QUESTIONS', $table_gui->getHTML());
1613  if ($this->object->getEnableProcessingTime()) $this->outProcessingTime($active_id);
1614  }
1615  else
1616  {
1617  $template = new ilTemplate('tpl.il_as_tst_list_of_questions_short.html', true, true, 'Modules/Test');
1618  foreach ($data as $row)
1619  {
1620  if (strlen($row['description']))
1621  {
1622  $template->setCurrentBlock('description');
1623  $template->setVariable("DESCRIPTION", $row['description']);
1624  $template->parseCurrentBlock();
1625  }
1626  $template->setCurrentBlock('item');
1627  $active = ($row['sequence'] == $this->sequence) ? ' active' : '';
1628  $template->setVariable('CLASS', ($row['walked_through']) ? ('answered'.$active) : ('unanswered'.$active));
1629  $template->setVariable('ITEM', ilUtil::prepareFormOutput($row['title']));
1630  $template->setVariable('SEQUENCE', $row['sequence']);
1631  $template->parseCurrentBlock();
1632  }
1633  $template->setVariable('LIST_OF_QUESTIONS', $this->lng->txt('list_of_questions'));
1634  $this->tpl->setVariable('LIST_OF_QUESTIONS', $template->get());
1635  }
1636  }
1637 
1639  {
1640  $this->tpl->addBlockFile($this->getContentBlockName(), "adm_content", "tpl.il_as_tst_max_allowed_users_reached.html", "Modules/Test");
1641  $this->tpl->setCurrentBlock("adm_content");
1642  $this->tpl->setVariable("MAX_ALLOWED_USERS_MESSAGE", sprintf($this->lng->txt("tst_max_allowed_users_message"), $this->object->getAllowedUsersTimeGap()));
1643  $this->tpl->setVariable("MAX_ALLOWED_USERS_HEADING", sprintf($this->lng->txt("tst_max_allowed_users_heading"), $this->object->getAllowedUsersTimeGap()));
1644  $this->tpl->setVariable("BACK_TO_INTRODUCTION", $this->lng->txt("tst_results_back_introduction"));
1645  $this->tpl->setVariable("FORMACTION", $this->ctrl->getFormAction($this));
1646  $this->tpl->parseCurrentBlock();
1647  }
1648 
1650  {
1651  global $ilUser;
1652  if ($this->object->canShowSolutionPrintview($ilUser->getId()))
1653  {
1654  $template = new ilTemplate("tpl.il_as_tst_finish_navigation.html", TRUE, TRUE, "Modules/Test");
1655  $template->setVariable("BUTTON_FINISH", $this->lng->txt("btn_next"));
1656  $template->setVariable("BUTTON_CANCEL", $this->lng->txt("btn_previous"));
1657 
1658  $template_top = new ilTemplate("tpl.il_as_tst_list_of_answers_topbuttons.html", TRUE, TRUE, "Modules/Test");
1659  $template_top->setCurrentBlock("button_print");
1660  $template_top->setVariable("BUTTON_PRINT", $this->lng->txt("print"));
1661  $template_top->parseCurrentBlock();
1662  $active_id = $this->object->getTestSession()->getActiveId();
1663  return $this->showListOfAnswers($active_id, NULL, $template_top->get(), $template->get());
1664  }
1665  else
1666  {
1667  $this->ctrl->redirect($this, 'gotoQuestion');
1668  }
1669  }
1670 
1672  {
1673  $this->confirmFinishTest();
1674  }
1675 
1682  {
1683  $this->tpl->addBlockFile("ADM_CONTENT", "adm_content", "tpl.il_as_tst_correct_solution.html", "Modules/Test");
1684 
1685  include_once("./Services/Style/classes/class.ilObjStyleSheet.php");
1686  $this->tpl->setCurrentBlock("ContentStyle");
1687  $this->tpl->setVariable("LOCATION_CONTENT_STYLESHEET", ilObjStyleSheet::getContentStylePath(0));
1688  $this->tpl->parseCurrentBlock();
1689 
1690  $this->tpl->setCurrentBlock("SyntaxStyle");
1691  $this->tpl->setVariable("LOCATION_SYNTAX_STYLESHEET", ilObjStyleSheet::getSyntaxStylePath());
1692  $this->tpl->parseCurrentBlock();
1693 
1694  $this->tpl->addCss(ilUtil::getStyleSheetLocation("output", "test_print.css", "Modules/Test"), "print");
1695  if ($this->object->getShowSolutionAnswersOnly())
1696  {
1697  $this->tpl->addCss(ilUtil::getStyleSheetLocation("output", "test_print_hide_content.css", "Modules/Test"), "print");
1698  }
1699 
1700  $this->tpl->setCurrentBlock("adm_content");
1701  $solution = $this->getCorrectSolutionOutput($_GET["evaluation"], $_GET["active_id"], $_GET["pass"]);
1702  $this->tpl->setVariable("OUTPUT_SOLUTION", $solution);
1703  $this->tpl->setVariable("TEXT_BACK", $this->lng->txt("back"));
1704  $this->ctrl->saveParameter($this, "pass");
1705  $this->ctrl->saveParameter($this, "active_id");
1706  $this->tpl->setVariable("URL_BACK", $this->ctrl->getLinkTarget($this, "outUserResultsOverview"));
1707  $this->tpl->parseCurrentBlock();
1708  }
1709 
1719  function showListOfAnswers($active_id, $pass = NULL, $top_data = "", $bottom_data = "")
1720  {
1721  global $ilUser;
1722 
1723  $this->tpl->addBlockFile($this->getContentBlockName(), "adm_content", "tpl.il_as_tst_finish_list_of_answers.html", "Modules/Test");
1724 
1725  $result_array =& $this->object->getTestResult($active_id, $pass);
1726 
1727  $counter = 1;
1728  // output of questions with solutions
1729  foreach ($result_array as $question_data)
1730  {
1731  $question = $question_data["qid"];
1732  if (is_numeric($question))
1733  {
1734  $this->tpl->setCurrentBlock("printview_question");
1735  $question_gui = $this->object->createQuestionGUI("", $question);
1736  $template = new ilTemplate("tpl.il_as_qpl_question_printview.html", TRUE, TRUE, "Modules/TestQuestionPool");
1737  $template->setVariable("COUNTER_QUESTION", $counter.". ");
1738  $template->setVariable("QUESTION_TITLE", $question_gui->object->getTitle());
1739 
1740  $show_question_only = ($this->object->getShowSolutionAnswersOnly()) ? TRUE : FALSE;
1741  $result_output = $question_gui->getSolutionOutput($active_id, $pass, FALSE, FALSE, $show_question_only, $this->object->getShowSolutionFeedback());
1742  $template->setVariable("SOLUTION_OUTPUT", $result_output);
1743  $this->tpl->setVariable("QUESTION_OUTPUT", $template->get());
1744  $this->tpl->parseCurrentBlock();
1745  $counter ++;
1746  }
1747  }
1748 
1749  $this->tpl->addCss(ilUtil::getStyleSheetLocation("output", "test_print.css", "Modules/Test"), "print");
1750  if ($this->object->getShowSolutionAnswersOnly())
1751  {
1752  $this->tpl->addCss(ilUtil::getStyleSheetLocation("output", "test_print_hide_content.css", "Modules/Test"), "print");
1753  }
1754  if (strlen($top_data))
1755  {
1756  $this->tpl->setCurrentBlock("top_data");
1757  $this->tpl->setVariable("TOP_DATA", $top_data);
1758  $this->tpl->parseCurrentBlock();
1759  }
1760 
1761  if (strlen($bottom_data))
1762  {
1763  $this->tpl->setCurrentBlock("bottom_data");
1764  $this->tpl->setVariable("FORMACTION", $this->ctrl->getFormAction($this));
1765  $this->tpl->setVariable("BOTTOM_DATA", $bottom_data);
1766  $this->tpl->parseCurrentBlock();
1767  }
1768 
1769  $this->tpl->setCurrentBlock("adm_content");
1770  $this->tpl->setVariable("TXT_ANSWER_SHEET", $this->lng->txt("tst_list_of_answers"));
1771  $user_data = $this->getResultsUserdata($active_id, TRUE);
1772  $signature = $this->getResultsSignature();
1773  $this->tpl->setVariable("USER_DETAILS", $user_data);
1774  $this->tpl->setVariable("SIGNATURE", $signature);
1775  $this->tpl->setVariable("TITLE", $this->object->getTitle());
1776  $this->tpl->setVariable("TXT_TEST_PROLOG", $this->lng->txt("tst_your_answers"));
1777  $invited_user =& $this->object->getInvitedUsers($ilUser->getId());
1778  $pagetitle = $this->object->getTitle() . " - " . $this->lng->txt("clientip") .
1779  ": " . $invited_user[$ilUser->getId()]["clientip"] . " - " .
1780  $this->lng->txt("matriculation") . ": " .
1781  $invited_user[$ilUser->getId()]["matriculation"];
1782  $this->tpl->setVariable("PAGETITLE", $pagetitle);
1783  $this->tpl->parseCurrentBlock();
1784  }
1785 
1792  private function getContentBlockName()
1793  {
1794  if ($this->object->getKioskMode())
1795  {
1796  $this->tpl->setBodyClass("kiosk");
1797  $this->tpl->setAddFooter(FALSE);
1798  return "CONTENT";
1799  }
1800  else
1801  {
1802  return "ADM_CONTENT";
1803  }
1804  }
1805 
1807  {
1808  $this->ctrl->redirectByClass("iltestevaluationgui", "outUserResultsOverview");
1809  }
1810 
1812  {
1813  $this->ctrl->redirectByClass("iltestevaluationgui", "outUserListOfAnswerPasses");
1814  }
1815 
1816 }
1817 ?>