ILIAS  Release_4_4_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.assMultipleChoiceGUI.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/TestQuestionPool/classes/class.assQuestionGUI.php';
5 require_once './Modules/TestQuestionPool/interfaces/interface.ilGuiQuestionScoringAdjustable.php';
6 require_once './Modules/TestQuestionPool/interfaces/interface.ilGuiAnswerScoringAdjustable.php';
7 require_once './Modules/Test/classes/inc.AssessmentConstants.php';
8 
24 {
26 
35  function __construct($id = -1)
36  {
38  include_once "./Modules/TestQuestionPool/classes/class.assMultipleChoice.php";
39  $this->object = new assMultipleChoice();
40  if ($id >= 0)
41  {
42  $this->object->loadFromDb($id);
43  }
44  }
45 
53  public function writePostData($always = false)
54  {
55  $hasErrors = (!$always) ? $this->editQuestion(true) : false;
56  if (!$hasErrors)
57  {
61  $this->saveTaxonomyAssignments();
62  return 0;
63  }
64  return 1;
65  }
66 
74  public function editQuestion($checkonly = FALSE)
75  {
76  $save = $this->isSaveCommand();
77  $this->getQuestionTemplate();
78 
79  include_once("./Services/Form/classes/class.ilPropertyFormGUI.php");
80  $form = new ilPropertyFormGUI();
81  $form->setFormAction($this->ctrl->getFormAction($this));
82  $form->setTitle($this->outQuestionType());
83  $isSingleline = ($this->object->lastChange == 0 && !array_key_exists('types', $_POST)) ? (($this->object->getMultilineAnswerSetting()) ? false : true) : $this->object->isSingleline;
84  if ($checkonly) $isSingleline = ($_POST['types'] == 0) ? true : false;
85  if ($isSingleline)
86  {
87  $form->setMultipart(TRUE);
88  }
89  else
90  {
91  $form->setMultipart(FALSE);
92  }
93  $form->setTableWidth("100%");
94  $form->setId("assmultiplechoice");
95 
96  // title, author, description, question, working time (assessment mode)
97  $this->addBasicQuestionFormProperties( $form );
98  $this->populateQuestionSpecificFormPart( $form );
99  $this->populateAnswerSpecificFormPart( $form );
100  $this->populateTaxonomyFormSection($form);
101  $this->addQuestionFormCommandButtons($form);
102 
103  $errors = false;
104 
105  if ($save)
106  {
107  $form->setValuesByPost();
108  $errors = !$form->checkInput();
109  $form->setValuesByPost(); // again, because checkInput now performs the whole stripSlashes handling and we need this if we don't want to have duplication of backslashes
110  if ($errors) $checkonly = false;
111  }
112 
113  if (!$checkonly) $this->tpl->setVariable("QUESTION_DATA", $form->getHTML());
114  return $errors;
115  }
116 
120  public function uploadchoice()
121  {
122  $this->writePostData(true);
123  $position = key($_POST['cmd']['uploadchoice']);
124  $this->editQuestion();
125  }
126 
130  public function removeimagechoice()
131  {
132  $this->writePostData(true);
133  $position = key($_POST['cmd']['removeimagechoice']);
134  $filename = $_POST['choice']['imagename'][$position];
135  $this->object->removeAnswerImage($position);
136  $this->editQuestion();
137  }
138 
142  public function addchoice()
143  {
144  $this->writePostData(true);
145  $position = key($_POST['cmd']['addchoice']);
146  $this->object->addAnswer("", 0, 0, $position+1);
147  $this->editQuestion();
148  }
149 
153  public function removechoice()
154  {
155  $this->writePostData(true);
156  $position = key($_POST['cmd']['removechoice']);
157  $this->object->deleteAnswer($position);
158  $this->editQuestion();
159  }
160 
170  $formaction,
171  $active_id,
172  $pass = NULL,
173  $is_question_postponed = FALSE,
174  $user_post_solutions = FALSE,
175  $show_specific_inline_feedback = FALSE
176  )
177  {
178  $test_output = $this->getTestOutput(
179  $active_id,
180  $pass,
181  $is_question_postponed,
182  $user_post_solutions,
183  $show_specific_inline_feedback
184  );
185 
186  $this->tpl->setVariable("QUESTION_OUTPUT", $test_output);
187  $this->tpl->setVariable("FORMACTION", $formaction);
188  }
189 
206  $active_id,
207  $pass = NULL,
208  $graphicalOutput = FALSE,
209  $result_output = FALSE,
210  $show_question_only = TRUE,
211  $show_feedback = FALSE,
212  $show_correct_solution = FALSE,
213  $show_manual_scoring = FALSE,
214  $show_question_text = TRUE
215  )
216  {
217  // shuffle output
218  $keys = $this->getChoiceKeys();
219 
220  // get the solution of the user for the active pass or from the last pass if allowed
221  $user_solution = array();
222  if (($active_id > 0) && (!$show_correct_solution))
223  {
224  $solutions =& $this->object->getSolutionValues($active_id, $pass);
225  foreach ($solutions as $idx => $solution_value)
226  {
227  array_push($user_solution, $solution_value["value1"]);
228  }
229  }
230  else
231  {
232  // take the correct solution instead of the user solution
233  foreach ($this->object->answers as $index => $answer)
234  {
235  $points_checked = $answer->getPointsChecked();
236  $points_unchecked = $answer->getPointsUnchecked();
237  if ($points_checked > $points_unchecked)
238  {
239  if ($points_checked > 0)
240  {
241  array_push($user_solution, $index);
242  }
243  }
244  }
245  }
246 
247  // generate the question output
248  include_once "./Services/UICore/classes/class.ilTemplate.php";
249  $template = new ilTemplate("tpl.il_as_qpl_mc_mr_output_solution.html", TRUE, TRUE, "Modules/TestQuestionPool");
250  $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html",TRUE, TRUE, "Modules/TestQuestionPool");
251  foreach ($keys as $answer_id)
252  {
253  $answer = $this->object->answers[$answer_id];
254  if (($active_id > 0) && (!$show_correct_solution))
255  {
256  if ($graphicalOutput)
257  {
258  // output of ok/not ok icons for user entered solutions
259  $ok = FALSE;
260  $checked = FALSE;
261  foreach ($user_solution as $mc_solution)
262  {
263  if (strcmp($mc_solution, $answer_id) == 0)
264  {
265  $checked = TRUE;
266  }
267  }
268  if ($checked)
269  {
270  if ($answer->getPointsChecked() > $answer->getPointsUnchecked())
271  {
272  $ok = TRUE;
273  }
274  else
275  {
276  $ok = FALSE;
277  }
278  }
279  else
280  {
281  if ($answer->getPointsChecked() > $answer->getPointsUnchecked())
282  {
283  $ok = FALSE;
284  }
285  else
286  {
287  $ok = TRUE;
288  }
289  }
290  if ($ok)
291  {
292  $template->setCurrentBlock("icon_ok");
293  $template->setVariable("ICON_OK", ilUtil::getImagePath("icon_ok.png"));
294  $template->setVariable("TEXT_OK", $this->lng->txt("answer_is_right"));
295  $template->parseCurrentBlock();
296  }
297  else
298  {
299  $template->setCurrentBlock("icon_ok");
300  $template->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_not_ok.png"));
301  $template->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_wrong"));
302  $template->parseCurrentBlock();
303  }
304  }
305  }
306  if (strlen($answer->getImage()))
307  {
308  $template->setCurrentBlock("answer_image");
309  if ($this->object->getThumbSize())
310  {
311  $template->setVariable("ANSWER_IMAGE_URL", $this->object->getImagePathWeb() . $this->object->getThumbPrefix() . $answer->getImage());
312  }
313  else
314  {
315  $template->setVariable("ANSWER_IMAGE_URL", $this->object->getImagePathWeb() . $answer->getImage());
316  }
317  $alt = $answer->getImage();
318  if (strlen($answer->getAnswertext()))
319  {
320  $alt = $answer->getAnswertext();
321  }
322  $alt = preg_replace("/<[^>]*?>/", "", $alt);
323  $template->setVariable("ANSWER_IMAGE_ALT", ilUtil::prepareFormOutput($alt));
324  $template->setVariable("ANSWER_IMAGE_TITLE", ilUtil::prepareFormOutput($alt));
325  $template->parseCurrentBlock();
326  }
327 
328  if ($show_feedback)
329  {
330 
331  if ($this->object->getSpecificFeedbackSetting() == 2)
332  {
333  foreach ($user_solution as $mc_solution)
334  {
335  if (strcmp($mc_solution, $answer_id) == 0)
336  {
337  $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
338  $this->object->getId(), $answer_id
339  );
340  if (strlen($fb))
341  {
342  $template->setCurrentBlock("feedback");
343  $template->setVariable("FEEDBACK", $this->object->prepareTextareaOutput( $fb, true ));
344  $template->parseCurrentBlock();
345  }
346  }
347  }
348  }
349 
350  if ($this->object->getSpecificFeedbackSetting() == 1)
351  {
352  $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
353  $this->object->getId(), $answer_id
354  );
355  if (strlen($fb))
356  {
357  $template->setCurrentBlock("feedback");
358  $template->setVariable("FEEDBACK", $this->object->prepareTextareaOutput( $fb, true ));
359  $template->parseCurrentBlock();
360  }
361  }
362 
363  if ($this->object->getSpecificFeedbackSetting() == 3)
364  {
365  $answer = $this->object->getAnswer($answer_id);
366 
367  if ($answer->getPoints() > 0)
368  {
369  $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
370  $this->object->getId(), $answer_id
371  );
372  if (strlen($fb))
373  {
374  $template->setCurrentBlock("feedback");
375  $template->setVariable("FEEDBACK", $this->object->prepareTextareaOutput( $fb, true ));
376  $template->parseCurrentBlock();
377  }
378  }
379 
380  }
381  }
382  $template->setCurrentBlock("answer_row");
383  $template->setVariable("ANSWER_TEXT", $this->object->prepareTextareaOutput($answer->getAnswertext(), TRUE));
384  $checked = FALSE;
385  if ($result_output)
386  {
387  $pointschecked = $this->object->answers[$answer_id]->getPointsChecked();
388  $pointsunchecked = $this->object->answers[$answer_id]->getPointsUnchecked();
389  $resulttextchecked = ($pointschecked == 1) || ($pointschecked == -1) ? "%s " . $this->lng->txt("point") : "%s " . $this->lng->txt("points");
390  $resulttextunchecked = ($pointsunchecked == 1) || ($pointsunchecked == -1) ? "%s " . $this->lng->txt("point") : "%s " . $this->lng->txt("points");
391  $template->setVariable("RESULT_OUTPUT", sprintf("(" . $this->lng->txt("checkbox_checked") . " = $resulttextchecked, " . $this->lng->txt("checkbox_unchecked") . " = $resulttextunchecked)", $pointschecked, $pointsunchecked));
392  }
393  foreach ($user_solution as $mc_solution)
394  {
395  if (strcmp($mc_solution, $answer_id) == 0)
396  {
397  $template->setVariable("SOLUTION_IMAGE", ilUtil::getHtmlPath(ilUtil::getImagePath("checkbox_checked.png")));
398  $template->setVariable("SOLUTION_ALT", $this->lng->txt("checked"));
399  $checked = TRUE;
400  }
401  }
402  if (!$checked)
403  {
404  $template->setVariable("SOLUTION_IMAGE", ilUtil::getHtmlPath(ilUtil::getImagePath("checkbox_unchecked.png")));
405  $template->setVariable("SOLUTION_ALT", $this->lng->txt("unchecked"));
406  }
407  $template->parseCurrentBlock();
408  }
409  $questiontext = $this->object->getQuestion();
410  if ($show_question_text==true)
411  {
412  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
413  }
414  $questionoutput = $template->get();
415  $feedback = ($show_feedback) ? $this->getAnswerFeedbackOutput($active_id, $pass) : "";
416 
417  if (strlen($feedback)) $solutiontemplate->setVariable("FEEDBACK", $this->object->prepareTextareaOutput( $feedback , true ));
418  $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
419 
420  $solutionoutput = $solutiontemplate->get();
421  if (!$show_question_only)
422  {
423  // get page object output
424  $solutionoutput = '<div class="ilc_question_Standard">'.$solutionoutput."</div>";
425  }
426  return $solutionoutput;
427  }
428 
429  function getPreview($show_question_only = FALSE)
430  {
431  // shuffle output
432  $keys = $this->getChoiceKeys();
433 
434  // generate the question output
435  include_once "./Services/UICore/classes/class.ilTemplate.php";
436  $template = new ilTemplate("tpl.il_as_qpl_mc_mr_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
437  foreach ($keys as $answer_id)
438  {
439  $answer = $this->object->answers[$answer_id];
440  if (strlen($answer->getImage()))
441  {
442  if ($this->object->getThumbSize())
443  {
444  $template->setCurrentBlock("preview");
445  $template->setVariable("URL_PREVIEW", $this->object->getImagePathWeb() . $answer->getImage());
446  $template->setVariable("TEXT_PREVIEW", $this->lng->txt('preview'));
447  $template->setVariable("IMG_PREVIEW", ilUtil::getImagePath('enlarge.png'));
448  $template->setVariable("ANSWER_IMAGE_URL", $this->object->getImagePathWeb() . $this->object->getThumbPrefix() . $answer->getImage());
449  list($width, $height, $type, $attr) = getimagesize($this->object->getImagePath() . $answer->getImage());
450  $alt = $answer->getImage();
451  if (strlen($answer->getAnswertext()))
452  {
453  $alt = $answer->getAnswertext();
454  }
455  $alt = preg_replace("/<[^>]*?>/", "", $alt);
456  $template->setVariable("ANSWER_IMAGE_ALT", ilUtil::prepareFormOutput($alt));
457  $template->setVariable("ANSWER_IMAGE_TITLE", ilUtil::prepareFormOutput($alt));
458  $template->parseCurrentBlock();
459  }
460  else
461  {
462  $template->setCurrentBlock("answer_image");
463  $template->setVariable("ANSWER_IMAGE_URL", $this->object->getImagePathWeb() . $answer->getImage());
464  list($width, $height, $type, $attr) = getimagesize($this->object->getImagePath() . $answer->getImage());
465  $alt = $answer->getImage();
466  if (strlen($answer->getAnswertext()))
467  {
468  $alt = $answer->getAnswertext();
469  }
470  $alt = preg_replace("/<[^>]*?>/", "", $alt);
471  $template->setVariable("ATTR", $attr);
472  $template->setVariable("ANSWER_IMAGE_ALT", ilUtil::prepareFormOutput($alt));
473  $template->setVariable("ANSWER_IMAGE_TITLE", ilUtil::prepareFormOutput($alt));
474  $template->parseCurrentBlock();
475  }
476  }
477  $template->setCurrentBlock("answer_row");
478  $template->setVariable("ANSWER_ID", $answer_id);
479  $template->setVariable("ANSWER_TEXT", $this->object->prepareTextareaOutput($answer->getAnswertext(), TRUE));
480  $template->parseCurrentBlock();
481  }
482  $questiontext = $this->object->getQuestion();
483  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
484  $questionoutput = $template->get();
485  if (!$show_question_only)
486  {
487  // get page object output
488  $questionoutput = $this->getILIASPage($questionoutput);
489  }
490  return $questionoutput;
491  }
492 
502  function getTestOutput(
503  $active_id,
504  $pass = NULL,
505  $is_postponed = FALSE,
506  $use_post_solutions = FALSE,
507  $show_feedback = FALSE
508  )
509  {
510  // shuffle output
511  $keys = $this->getChoiceKeys();
512 
513  // get the solution of the user for the active pass or from the last pass if allowed
514  $user_solution = array();
515  if ($active_id)
516  {
517  $solutions = NULL;
518  include_once "./Modules/Test/classes/class.ilObjTest.php";
519  if (!ilObjTest::_getUsePreviousAnswers($active_id, true))
520  {
521  if (is_null($pass)) $pass = ilObjTest::_getPass($active_id);
522  }
523  $solutions =& $this->object->getSolutionValues($active_id, $pass);
524  foreach ($solutions as $idx => $solution_value)
525  {
526  array_push($user_solution, $solution_value["value1"]);
527  }
528  }
529  // generate the question output
530  include_once "./Services/UICore/classes/class.ilTemplate.php";
531  $template = new ilTemplate("tpl.il_as_qpl_mc_mr_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
532  foreach ($keys as $answer_id)
533  {
534  $answer = $this->object->answers[$answer_id];
535  if (strlen($answer->getImage()))
536  {
537  if ($this->object->getThumbSize())
538  {
539  $template->setCurrentBlock("preview");
540  $template->setVariable("URL_PREVIEW", $this->object->getImagePathWeb() . $answer->getImage());
541  $template->setVariable("TEXT_PREVIEW", $this->lng->txt('preview'));
542  $template->setVariable("IMG_PREVIEW", ilUtil::getImagePath('enlarge.png'));
543  $template->setVariable("ANSWER_IMAGE_URL", $this->object->getImagePathWeb() . $this->object->getThumbPrefix() . $answer->getImage());
544  list($width, $height, $type, $attr) = getimagesize($this->object->getImagePath() . $answer->getImage());
545  $alt = $answer->getImage();
546  if (strlen($answer->getAnswertext()))
547  {
548  $alt = $answer->getAnswertext();
549  }
550  $alt = preg_replace("/<[^>]*?>/", "", $alt);
551  $template->setVariable("ANSWER_IMAGE_ALT", ilUtil::prepareFormOutput($alt));
552  $template->setVariable("ANSWER_IMAGE_TITLE", ilUtil::prepareFormOutput($alt));
553  $template->parseCurrentBlock();
554  }
555  else
556  {
557  $template->setCurrentBlock("answer_image");
558  $template->setVariable("ANSWER_IMAGE_URL", $this->object->getImagePathWeb() . $answer->getImage());
559  list($width, $height, $type, $attr) = getimagesize($this->object->getImagePath() . $answer->getImage());
560  $alt = $answer->getImage();
561  if (strlen($answer->getAnswertext()))
562  {
563  $alt = $answer->getAnswertext();
564  }
565  $alt = preg_replace("/<[^>]*?>/", "", $alt);
566  $template->setVariable("ATTR", $attr);
567  $template->setVariable("ANSWER_IMAGE_ALT", ilUtil::prepareFormOutput($alt));
568  $template->setVariable("ANSWER_IMAGE_TITLE", ilUtil::prepareFormOutput($alt));
569  $template->parseCurrentBlock();
570  }
571  }
572  if ($show_feedback && $this->object->getSpecificFeedbackSetting() == 2)
573  {
574  foreach ($user_solution as $mc_solution)
575  {
576  if (strcmp($mc_solution, $answer_id) == 0)
577  {
578  $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
579  $this->object->getId(), $answer_id
580  );
581  if (strlen($fb))
582  {
583  $template->setCurrentBlock("feedback");
584  $template->setVariable("FEEDBACK", $this->object->prepareTextareaOutput( $fb, true ));
585  $template->parseCurrentBlock();
586  }
587  }
588  }
589  }
590 
591  if ($show_feedback && $this->object->getSpecificFeedbackSetting() == 1)
592  {
593  $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
594  $this->object->getId(), $answer_id
595  );
596  if (strlen($fb))
597  {
598  $template->setCurrentBlock("feedback");
599  $template->setVariable("FEEDBACK", $this->object->prepareTextareaOutput( $fb, true ));
600  $template->parseCurrentBlock();
601  }
602  }
603 
604  if ($show_feedback && $this->object->getSpecificFeedbackSetting() == 3)
605  {
606  $answer = $this->object->getAnswer($answer_id);
607 
608  if ($answer->getPoints() > 0)
609  {
610  $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
611  $this->object->getId(), $answer_id
612  );
613  if (strlen($fb))
614  {
615  $template->setCurrentBlock("feedback");
616  $template->setVariable("FEEDBACK", $this->object->prepareTextareaOutput( $fb, true ));
617  $template->parseCurrentBlock();
618  }
619  }
620 
621  }
622 
623 
624  $template->setCurrentBlock("answer_row");
625  $template->setVariable("ANSWER_ID", $answer_id);
626  $template->setVariable("ANSWER_TEXT", $this->object->prepareTextareaOutput($answer->getAnswertext(), TRUE));
627  foreach ($user_solution as $mc_solution)
628  {
629  if (strcmp($mc_solution, $answer_id) == 0)
630  {
631  $template->setVariable("CHECKED_ANSWER", " checked=\"checked\"");
632  }
633  }
634  $template->parseCurrentBlock();
635  }
636  $questiontext = $this->object->getQuestion();
637  $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
638  $questionoutput = $template->get();
639  $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput);
640  return $pageoutput;
641  }
642 
648  public function setQuestionTabs()
649  {
650  global $rbacsystem, $ilTabs;
651 
652  $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $_GET["q_id"]);
653  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
654  $q_type = $this->object->getQuestionType();
655 
656  if (strlen($q_type))
657  {
658  $classname = $q_type . "GUI";
659  $this->ctrl->setParameterByClass(strtolower($classname), "sel_question_types", $q_type);
660  $this->ctrl->setParameterByClass(strtolower($classname), "q_id", $_GET["q_id"]);
661  }
662 
663  if ($_GET["q_id"])
664  {
665  if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
666  {
667  // edit page
668  $ilTabs->addTarget("edit_page",
669  $this->ctrl->getLinkTargetByClass("ilAssQuestionPageGUI", "edit"),
670  array("edit", "insert", "exec_pg"),
671  "", "", $force_active);
672  }
673 
674  // edit page
675  $ilTabs->addTarget("preview",
676  $this->ctrl->getLinkTargetByClass("ilAssQuestionPageGUI", "preview"),
677  array("preview"),
678  "ilAssQuestionPageGUI", "", $force_active);
679  }
680  $force_active = false;
681  if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
682  {
683  $url = "";
684  if ($classname) $url = $this->ctrl->getLinkTargetByClass($classname, "editQuestion");
685  $force_active = false;
686  // edit question properties
687  $ilTabs->addTarget("edit_question",
688  $url,
689  array("editQuestion", "save", "saveEdit", "addchoice", "removechoice", "removeimagechoice", "uploadchoice", "originalSyncForm"),
690  $classname, "", $force_active);
691  }
692 
693  // add tab for question feedback within common class assQuestionGUI
694  $this->addTab_QuestionFeedback($ilTabs);
695 
696  // add tab for question hint within common class assQuestionGUI
697  $this->addTab_QuestionHints($ilTabs);
698 
699  if ($_GET["q_id"])
700  {
701  $ilTabs->addTarget("solution_hint",
702  $this->ctrl->getLinkTargetByClass($classname, "suggestedsolution"),
703  array("suggestedsolution", "saveSuggestedSolution", "outSolutionExplorer", "cancel",
704  "addSuggestedSolution","cancelExplorer", "linkChilds", "removeSuggestedSolution"
705  ),
706  $classname,
707  ""
708  );
709  }
710 
711  // Assessment of questions sub menu entry
712  if ($_GET["q_id"])
713  {
714  $ilTabs->addTarget("statistics",
715  $this->ctrl->getLinkTargetByClass($classname, "assessment"),
716  array("assessment"),
717  $classname, "");
718  }
719 
720  if (($_GET["calling_test"] > 0) || ($_GET["test_ref_id"] > 0))
721  {
722  $ref_id = $_GET["calling_test"];
723  if (strlen($ref_id) == 0) $ref_id = $_GET["test_ref_id"];
724 
725  global $___test_express_mode;
726 
727  if (!$_GET['test_express_mode'] && !$___test_express_mode) {
728  $ilTabs->setBackTarget($this->lng->txt("backtocallingtest"), "ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=$ref_id");
729  }
730  else {
732  $ilTabs->setBackTarget($this->lng->txt("backtocallingtest"), $link);
733  }
734  }
735  else
736  {
737  $ilTabs->setBackTarget($this->lng->txt("qpl"), $this->ctrl->getLinkTargetByClass("ilobjquestionpoolgui", "questions"));
738  }
739  }
740 
746  function getChoiceKeys()
747  {
748  if (strcmp($_GET["activecommand"], "directfeedback") == 0)
749  {
750  if (is_array($_SESSION["choicekeys"])) $this->choiceKeys = $_SESSION["choicekeys"];
751  }
752  if (!is_array($this->choiceKeys))
753  {
754  $this->choiceKeys = array_keys($this->object->answers);
755  if ($this->object->getShuffle())
756  {
757  $this->choiceKeys = $this->object->pcArrayShuffle($this->choiceKeys);
758  }
759  }
760  $_SESSION["choicekeys"] = $this->choiceKeys;
761  return $this->choiceKeys;
762  }
763 
764  function getSpecificFeedbackOutput($active_id, $pass)
765  {
766  // No return value, this question type supports inline specific feedback.
767  $output = "";
768  return $this->object->prepareTextareaOutput($output, TRUE);
769  }
770 
771  public function writeQuestionSpecificPostData($always = false)
772  {
773  $this->object->setShuffle( $_POST["shuffle"] );
774 
775  $this->object->setSpecificFeedbackSetting( $_POST['feedback_setting'] );
776 
777  $this->object->setMultilineAnswerSetting( $_POST["types"] );
778  if (is_array( $_POST['choice']['imagename'] ) && $_POST["types"] == 1)
779  {
780  $this->object->isSingleline = true;
781  ilUtil::sendInfo( $this->lng->txt( 'info_answer_type_change' ), true );
782  }
783  else
784  {
785  $this->object->isSingleline = ($_POST["types"] == 0) ? true : false;
786  }
787  $this->object->setThumbSize( (strlen( $_POST["thumb_size"] )) ? $_POST["thumb_size"] : "" );
788  }
789 
790  public function writeAnswerSpecificPostData($always = false)
791  {
792  // Delete all existing answers and create new answers from the form data
793  $this->object->flushAnswers();
794  if ($this->object->isSingleline)
795  {
796  foreach ($_POST['choice']['answer'] as $index => $answertext)
797  {
798  $picturefile = $_POST['choice']['imagename'][$index];
799  $file_org_name = $_FILES['choice']['name']['image'][$index];
800  $file_temp_name = $_FILES['choice']['tmp_name']['image'][$index];
801 
802  if (strlen( $file_temp_name ))
803  {
804  // check suffix
805  $suffix = strtolower( array_pop( explode( ".", $file_org_name ) ) );
806  if (in_array( $suffix, array( "jpg", "jpeg", "png", "gif" ) ))
807  {
808  // upload image
809  $filename = $this->object->createNewImageFileName( $file_org_name );
810  if ($this->object->setImageFile( $filename, $file_temp_name ) == 0)
811  {
812  $picturefile = $filename;
813  }
814  }
815  }
816  $this->object->addAnswer( $answertext,
817  $_POST['choice']['points'][$index],
818  $_POST['choice']['points_unchecked'][$index],
819  $index,
820  $picturefile
821  );
822  }
823  }
824  else
825  {
826  foreach ($_POST['choice']['answer'] as $index => $answer)
827  {
828  $answertext = $answer;
829  $this->object->addAnswer( $answertext,
830  $_POST['choice']['points'][$index],
831  $_POST['choice']['points_unchecked'][$index],
832  $index
833  );
834  }
835  }
836  }
837 
839  {
840  // shuffle
841  $shuffle = new ilCheckboxInputGUI($this->lng->txt( "shuffle_answers" ), "shuffle");
842  $shuffle->setValue( 1 );
843  $shuffle->setChecked( $this->object->getShuffle() );
844  $shuffle->setRequired( FALSE );
845  $form->addItem( $shuffle );
846 
847  if ($this->object->getId())
848  {
849  $hidden = new ilHiddenInputGUI("", "ID");
850  $hidden->setValue( $this->object->getId() );
851  $form->addItem( $hidden );
852  }
853 
854  if (!$this->object->getSelfAssessmentEditingMode())
855  {
856  $isSingleline = ($this->object->lastChange == 0 && !array_key_exists( 'types',
857  $_POST
858  )) ? (($this->object->getMultilineAnswerSetting()) ? false : true) : $this->object->isSingleline;
859  // Answer types
860  $types = new ilSelectInputGUI($this->lng->txt( "answer_types" ), "types");
861  $types->setRequired( false );
862  $types->setValue( ($isSingleline) ? 0 : 1 );
863  $types->setOptions( array(
864  0 => $this->lng->txt( 'answers_singleline' ),
865  1 => $this->lng->txt( 'answers_multiline' ),
866  )
867  );
868  $form->addItem( $types );
869  }
870 
871  if ($isSingleline)
872  {
873  // thumb size
874  $thumb_size = new ilNumberInputGUI($this->lng->txt( "thumb_size" ), "thumb_size");
875  $thumb_size->setSuffix($this->lng->txt("thumb_size_unit_pixel"));
876  $thumb_size->setMinValue( 20 );
877  $thumb_size->setDecimals( 0 );
878  $thumb_size->setSize( 6 );
879  $thumb_size->setInfo( $this->lng->txt( 'thumb_size_info' ) );
880  $thumb_size->setValue( $this->object->getThumbSize() );
881  $thumb_size->setRequired( false );
882  $form->addItem( $thumb_size );
883  return $isSingleline;
884  }
885  return $isSingleline;
886  }
887 
889  {
890  // Choices
891  include_once "./Modules/TestQuestionPool/classes/class.ilMultipleChoiceWizardInputGUI.php";
892  $choices = new ilMultipleChoiceWizardInputGUI($this->lng->txt( "answers" ), "choice");
893  $choices->setRequired( true );
894  $choices->setQuestionObject( $this->object );
895  $isSingleline = ($this->object->lastChange == 0 && !array_key_exists( 'types',
896  $_POST
897  )) ? (($this->object->getMultilineAnswerSetting()) ? false : true) : $this->object->isSingleline;
898  $choices->setSingleline( $isSingleline );
899  $choices->setAllowMove( false );
900  if ($this->object->getSelfAssessmentEditingMode())
901  {
902  $choices->setSize( 40 );
903  $choices->setMaxLength( 800 );
904  }
905  if ($this->object->getAnswerCount() == 0)
906  $this->object->addAnswer( "", 0, 0, 0 );
907  $choices->setValues( $this->object->getAnswers() );
908  $form->addItem( $choices );
909  }
910 
921  {
922  return array();
923  }
924 
935  {
936  return array('shuffle','types','thumb_size');
937  }
938 
939  public function reworkFormForCorrectionMode(ilPropertyFormGUI $form)
940  {
942  $multiplechoice_wizardinputgui = $form->getItemByPostVar('choice');
943  $multiplechoice_wizardinputgui->setDisableUpload(true);
944  $multiplechoice_wizardinputgui->setDisableActions(true);
945  $multiplechoice_wizardinputgui->setDisableText(true);
946  return $form;
947  }
948 
957  public function getAggregatedAnswersView($relevant_answers)
958  {
959  $actives = array();
960  foreach($relevant_answers as $answer)
961  {
962  $actives[$answer['active_fi']] = max($answer['pass'], $actives[$answer['pass']]);
963  }
964  $usercount = count($actives);
965  $passcount = 0;
966  foreach($actives as $active)
967  {
968  $passcount += $active;
969  }
970  $passcount = $passcount + $usercount; // Add pass 0
971 
972  $tpl = new ilTemplate('tpl.il_as_aggregated_answers_header.html', true, true, "Modules/TestQuestionPool");
973  $tpl->setVariable('HEADERTEXT', $this->lng->txt('overview'));
974  $tpl->setVariable('NUMBER_OF_USERS_INFO', $this->lng->txt('number_of_users'));
975  $tpl->setVariable('NUMBER_OF_USERS', $usercount);
976  $tpl->setVariable('NUMBER_OF_PASSES_INFO', $this->lng->txt('number_of_passes'));
977  $tpl->setVariable('NUMBER_OF_PASSES', $passcount);
978 
979  $header = $tpl->get();
980  $overview = $this->renderAggregateView(
981  $this->aggregateAnswers( $relevant_answers, $this->object->getAnswers() )
982  )->get();
983 
984  $variants = $this->renderVariantsView(
985  $this->aggregateAnswerVariants($relevant_answers, $this->object->getAnswers()),
986  $this->object->getAnswers()
987  )->get();
988 
989  return $header . $overview . $variants ;
990  }
991 
992  public function aggregateAnswers($relevant_answers_chosen, $answers_defined_on_question)
993  {
994  $aggregate = array();
995  foreach ($answers_defined_on_question as $answer)
996  {
997  $aggregated_info_for_answer = array();
998  $aggregated_info_for_answer['answertext'] = $answer->getAnswerText();
999  $aggregated_info_for_answer['count_checked'] = 0;
1000 
1001  foreach ($relevant_answers_chosen as $relevant_answer)
1002  {
1003  if ($relevant_answer['value1'] == $answer->getOrder())
1004  {
1005  $aggregated_info_for_answer['count_checked']++;
1006  }
1007  }
1008  $aggregated_info_for_answer['count_unchecked'] =
1009  ceil(count($relevant_answers_chosen) / count($answers_defined_on_question))
1010  - $aggregated_info_for_answer['count_checked'];
1011 
1012  $aggregate[] = $aggregated_info_for_answer;
1013  }
1014  return $aggregate;
1015  }
1016 
1017  public function aggregateAnswerVariants($relevant_answers_chosen)
1018  {
1019  $variants = array();
1020  $passdata = array();
1021  foreach ($relevant_answers_chosen as $relevant_answer)
1022  {
1023  $pass_ident = $relevant_answer['active_fi'].$relevant_answer['pass'];
1024  $answer = $passdata[$pass_ident];
1025  if (strlen($answer))
1026  {
1027  $answer_elements = explode(',', $answer);
1028  } else {
1029  $answer_elements = array();
1030  }
1031  $answer_elements[] = $relevant_answer['value1'];
1032  $passdata[$pass_ident] = implode(',',$answer_elements);
1033  }
1034  foreach($passdata as $passident => $behaviour)
1035  {
1036  $variants[$behaviour]++;
1037  }
1038  arsort($variants);
1039  return $variants;
1040  }
1041 
1047  public function renderAggregateView($aggregate)
1048  {
1049  $tpl = new ilTemplate('tpl.il_as_aggregated_answers_table.html', true, true, "Modules/TestQuestionPool");
1050  $tpl->setVariable( 'OPTION_HEADER', $this->lng->txt('option') );
1051  $tpl->setVariable( 'COUNT_HEADER', $this->lng->txt('count') );
1052  $tpl->setVariable( 'AGGREGATION_HEADER', $this->lng->txt('aggregated_answers_header') );
1053  foreach ($aggregate as $line_data)
1054  {
1055  $tpl->setCurrentBlock( 'aggregaterow' );
1056  $tpl->setVariable( 'OPTION', $line_data['answertext'] );
1057  $tpl->setVariable( 'COUNT', $line_data['count_checked'] );
1058  $tpl->parseCurrentBlock();
1059  }
1060  return $tpl;
1061  }
1062 
1063  public function renderVariantsView($aggregate, $answers)
1064  {
1065  $tpl = new ilTemplate( 'tpl.il_as_aggregated_answers_table.html', true, true, "Modules/TestQuestionPool" );
1066  $tpl->setVariable( 'OPTION_HEADER', $this->lng->txt( 'answer_variant' ) );
1067  $tpl->setVariable( 'COUNT_HEADER', $this->lng->txt( 'count' ) );
1068  $tpl->setVariable( 'AGGREGATION_HEADER', $this->lng->txt( 'aggregated_answers_variants' ) );
1069  foreach ($aggregate as $options => $count)
1070  {
1071  $tpl->setCurrentBlock( 'aggregaterow' );
1072  $optionstext = array();
1073  foreach (explode( ',', $options ) as $option)
1074  {
1075  $answer = $answers[$option];
1076  $optionstext[] = $answer->getAnswerText();
1077  }
1078  $tpl->setVariable( 'OPTION', implode( ',&nbsp;', $optionstext ) );
1079  $tpl->setVariable( 'COUNT', $count );
1080  $tpl->parseCurrentBlock();
1081  }
1082 
1083  return $tpl;
1084  }
1085 }