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
4require_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
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 {
597 }
598
599 if ($this->object->getListOfQuestions())
600 {
601 $this->populateSummaryButtons();
602 }
603
604 if ($this->object->getShowCancel())
605 {
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
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
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
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
933 }
934
936 {
937 require_once 'Modules/Course/classes/Objectives/class.ilLOTestQuestionAdapter.php';
938
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}
$_GET["client_id"]
Basic GUI class for assessment questions.
Abstract basic class which is to be extended by the concrete assessment question type classes.
Question page GUI class.
static isObjectiveTest($a_trst_ref_id)
Check if test ref_id is used in an objective course.
static filterQuestions(ilTestSession $a_test_session, ilTestSequence $a_test_sequence)
Called from learning objective test.
static updateObjectiveStatus(ilTestSession $a_test_session, ilTestSequence $a_test_sequence, assQuestion $a_question)
Store result and update objective status.
_getSolvedQuestions($active_id, $question_fi=null)
get solved questions
static allObligationsAnswered($test_id, $active_id, $pass)
checks wether all questions marked as obligatory were answered within the test pass with given testId...
static isQuestionObligatory($question_id)
checks wether the question with given id is marked as obligatory or not
static _getAllReferences($a_id)
get all reference ids of object
Output class for assessment test execution.
nextQuestionCmd()
Go to the next question.
updateContainerObjectivesWithAnsweredQuestion(ilTestSession $testSession, ilTestSequence $testSequence, assQuestion $question)
redirectQuestionCmd()
Called when a user answered a question to perform a redirect after POST.
filterTestSequenceByObjectives(ilTestSession $testSession, ilTestSequence $testSequence)
previousQuestionCmd()
Go to the previous question.
canSaveResult()
Returns TRUE if the answers of the current user could be saved.
saveQuestionSolution($force=FALSE)
saves the user input of a question
isFirstPageInSequence($sequence)
postponeQuestionCmd()
Postpone a question to the end of the test.
outWorkingForm($sequence="", $test_id, $postpone_allowed, $directfeedback=false)
Creates the learners output of a question.
executeCommand()
Execute Command.
isValidSequenceElement($sequenceElement)
isLastQuestionInSequence(assQuestionGUI $question_gui)
Output class for assessment test execution.
fillQuestionRelatedNavigation(assQuestionGUI $questionGUI)
renders the elements for the question related navigation
calculateSequence()
Calculates the sequence to determine the next question.
ensureExistingTestSession(ilTestSession $testSession)
populateScoreBlock($reachedPoints, $maxPoints)
updateWorkingTime()
updates working time and stores state saveresult to see if question has to be stored or not
isMaxProcessingTimeReached()
Checks wheather the maximum processing time is reached or not.
outTestPage($directfeedback)
Outputs the question of the active sequence.
outQuestionSummaryCmd($fullpage=true, $contextFinishTest=false, $obligationsNotAnswered=false, $obligationsFilter=false)
Output of a summary of all test questions for test participants.
static getInstance(ilDB $db, ilObjTest $testOBJ, ilTestRandomQuestionSetConfig $questionSetConfig, ilTestRandomQuestionSetSourcePoolDefinitionList $sourcePoolDefinitionList, ilTestRandomQuestionSetStagingPoolQuestionList $stagingPoolQuestionList)
Test sequence handler.
saveToDb()
Saves the sequence data for a given pass to the database.
getCommand($cmd)
Retrieves the ilCtrl command.
Test session handler.
Signature Plugin Class.
Class ilTestSubmissionReviewGUI.
static getJSLocation($a_js_name, $a_js_location="", $add_version=FALSE)
get full javascript file name (path inclusive) of current user
static redirect($a_script)
http redirect to other script
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
static sendInfo($a_info="", $a_keep=false)
Send Info Message to Screen.
static initConnectionWithAnimation()
Init YUI Connection module.
static initjQuery($a_tpl=null)
Init jQuery.
$_POST['username']
Definition: cron.php:12
< 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']
const OUTPUT_JAVASCRIPT
$cmd
Definition: sahs_server.php:35
global $ilDB
global $ilUser
Definition: imgupload.php:15