ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
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
4require_once './Modules/TestQuestionPool/classes/class.assQuestionGUI.php';
5require_once './Modules/TestQuestionPool/interfaces/interface.ilGuiQuestionScoringAdjustable.php';
6require_once './Modules/TestQuestionPool/interfaces/interface.ilGuiAnswerScoringAdjustable.php';
7require_once './Modules/Test/classes/inc.AssessmentConstants.php';
8
24{
26
35 function __construct($id = -1)
36 {
37 parent::__construct();
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
49 protected function writePostData($always = false)
50 {
51 $hasErrors = (!$always) ? $this->editQuestion(true) : false;
52 if (!$hasErrors)
53 {
54 $form = $this->buildEditForm();
55 $form->setValuesByPost();
56 require_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
59 $this->writeAnswerSpecificPostData($form);
61 return 0;
62 }
63 return 1;
64 }
65
73 protected function getEditAnswersSingleLine($checkonly = false)
74 {
75 if ($checkonly)
76 {
77 // form posting is checked
78 return ($_POST['types'] == 0) ? true : false;
79 }
80
81 $lastChange = $this->object->getLastChange();
82 if (empty($lastChange) && !isset($_POST['types']))
83 {
84 // a new question is edited
85 return $this->object->getMultilineAnswerSetting() ? false : true;
86 }
87 else
88 {
89 // a saved question is edited
90 return $this->object->isSingleline;
91 }
92 }
93
101 public function editQuestion($checkonly = FALSE)
102 {
103 $save = $this->isSaveCommand();
104 $this->getQuestionTemplate();
105
106 $form = $this->buildEditForm();
107
108 $isSingleline = $this->getEditAnswersSingleLine($checkonly);
109 if ($isSingleline)
110 {
111 $form->setMultipart(TRUE);
112 }
113 else
114 {
115 $form->setMultipart(FALSE);
116 }
117
118 $errors = false;
119
120 if ($save)
121 {
122 $form->getItemByPostVar('selection_limit')->setMaxValue(count((array)$_POST['choice']['answer']));
123
124 $form->setValuesByPost();
125 $errors = !$form->checkInput();
126 $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
127 if ($errors) $checkonly = false;
128 }
129
130 if (!$checkonly) $this->tpl->setVariable("QUESTION_DATA", $form->getHTML());
131 return $errors;
132 }
133
135 {
136 parent::addBasicQuestionFormProperties($form);
137 $form->getItemByPostVar('question')->setInitialRteWidth('100');
138 }
139
143 public function uploadchoice()
144 {
145 $this->writePostData(true);
146 $position = key($_POST['cmd']['uploadchoice']);
147 $this->editQuestion();
148 }
149
153 public function removeimagechoice()
154 {
155 $this->writePostData(true);
156 $position = key($_POST['cmd']['removeimagechoice']);
157 $filename = $_POST['choice']['imagename'][$position];
158 $this->object->removeAnswerImage($position);
159 $this->editQuestion();
160 }
161
165 public function addchoice()
166 {
167 $this->writePostData(true);
168 $position = key($_POST['cmd']['addchoice']);
169 $this->object->addAnswer("", 0, 0, $position+1);
170 $this->editQuestion();
171 }
172
176 public function removechoice()
177 {
178 $this->writePostData(true);
179 $position = key($_POST['cmd']['removechoice']);
180 $this->object->deleteAnswer($position);
181 $this->editQuestion();
182 }
183
200 $active_id,
201 $pass = NULL,
202 $graphicalOutput = FALSE,
203 $result_output = FALSE,
204 $show_question_only = TRUE,
205 $show_feedback = FALSE,
206 $show_correct_solution = FALSE,
207 $show_manual_scoring = FALSE,
208 $show_question_text = TRUE
209 )
210 {
211 // shuffle output
212 $keys = $this->getChoiceKeys();
213
214 // get the solution of the user for the active pass or from the last pass if allowed
215 $user_solution = array();
216 if (($active_id > 0) && (!$show_correct_solution))
217 {
218 $solutions =& $this->object->getSolutionValues($active_id, $pass);
219 foreach ($solutions as $idx => $solution_value)
220 {
221 array_push($user_solution, $solution_value["value1"]);
222 }
223 }
224 else
225 {
226 // take the correct solution instead of the user solution
227 foreach ($this->object->answers as $index => $answer)
228 {
229 $points_checked = $answer->getPointsChecked();
230 $points_unchecked = $answer->getPointsUnchecked();
231 if ($points_checked > $points_unchecked)
232 {
233 if ($points_checked > 0)
234 {
235 array_push($user_solution, $index);
236 }
237 }
238 }
239 }
240
241 // generate the question output
242 include_once "./Services/UICore/classes/class.ilTemplate.php";
243 $template = new ilTemplate("tpl.il_as_qpl_mc_mr_output_solution.html", TRUE, TRUE, "Modules/TestQuestionPool");
244 $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html",TRUE, TRUE, "Modules/TestQuestionPool");
245 foreach ($keys as $answer_id)
246 {
247 $answer = $this->object->answers[$answer_id];
248 if (($active_id > 0) && (!$show_correct_solution))
249 {
250 if ($graphicalOutput)
251 {
252 // output of ok/not ok icons for user entered solutions
253 $ok = FALSE;
254 $checked = FALSE;
255 foreach ($user_solution as $mc_solution)
256 {
257 if (strcmp($mc_solution, $answer_id) == 0)
258 {
259 $checked = TRUE;
260 }
261 }
262 if ($checked)
263 {
264 if ($answer->getPointsChecked() > $answer->getPointsUnchecked())
265 {
266 $ok = TRUE;
267 }
268 else
269 {
270 $ok = FALSE;
271 }
272 }
273 else
274 {
275 if ($answer->getPointsChecked() > $answer->getPointsUnchecked())
276 {
277 $ok = FALSE;
278 }
279 else
280 {
281 $ok = TRUE;
282 }
283 }
284 if ($ok)
285 {
286 $template->setCurrentBlock("icon_ok");
287 $template->setVariable("ICON_OK", ilUtil::getImagePath("icon_ok.svg"));
288 $template->setVariable("TEXT_OK", $this->lng->txt("answer_is_right"));
289 $template->parseCurrentBlock();
290 }
291 else
292 {
293 $template->setCurrentBlock("icon_ok");
294 $template->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_not_ok.svg"));
295 $template->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_wrong"));
296 $template->parseCurrentBlock();
297 }
298 }
299 }
300 if (strlen($answer->getImage()))
301 {
302 $template->setCurrentBlock("answer_image");
303 if ($this->object->getThumbSize())
304 {
305 $template->setVariable("ANSWER_IMAGE_URL", $this->object->getImagePathWeb() . $this->object->getThumbPrefix() . $answer->getImage());
306 }
307 else
308 {
309 $template->setVariable("ANSWER_IMAGE_URL", $this->object->getImagePathWeb() . $answer->getImage());
310 }
311 $alt = $answer->getImage();
312 if (strlen($answer->getAnswertext()))
313 {
314 $alt = $answer->getAnswertext();
315 }
316 $alt = preg_replace("/<[^>]*?>/", "", $alt);
317 $template->setVariable("ANSWER_IMAGE_ALT", ilUtil::prepareFormOutput($alt));
318 $template->setVariable("ANSWER_IMAGE_TITLE", ilUtil::prepareFormOutput($alt));
319 $template->parseCurrentBlock();
320 }
321
322 if ($show_feedback)
323 {
324
325 if ($this->object->getSpecificFeedbackSetting() == 2)
326 {
327 foreach ($user_solution as $mc_solution)
328 {
329 if (strcmp($mc_solution, $answer_id) == 0)
330 {
331 $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
332 $this->object->getId(), $answer_id
333 );
334 if (strlen($fb))
335 {
336 $template->setCurrentBlock("feedback");
337 $template->setVariable("FEEDBACK", $this->object->prepareTextareaOutput( $fb, true ));
338 $template->parseCurrentBlock();
339 }
340 }
341 }
342 }
343
344 if ($this->object->getSpecificFeedbackSetting() == 1)
345 {
346 $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
347 $this->object->getId(), $answer_id
348 );
349 if (strlen($fb))
350 {
351 $template->setCurrentBlock("feedback");
352 $template->setVariable("FEEDBACK", $this->object->prepareTextareaOutput( $fb, true ));
353 $template->parseCurrentBlock();
354 }
355 }
356
357 if ($this->object->getSpecificFeedbackSetting() == 3)
358 {
359 $answer = $this->object->getAnswer($answer_id);
360
361 if ($answer->getPoints() > 0)
362 {
363 $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
364 $this->object->getId(), $answer_id
365 );
366 if (strlen($fb))
367 {
368 $template->setCurrentBlock("feedback");
369 $template->setVariable("FEEDBACK", $this->object->prepareTextareaOutput( $fb, true ));
370 $template->parseCurrentBlock();
371 }
372 }
373
374 }
375 }
376 $template->setCurrentBlock("answer_row");
377 $template->setVariable("ANSWER_TEXT", $this->object->prepareTextareaOutput($answer->getAnswertext(), TRUE));
378 $checked = FALSE;
379 if ($result_output)
380 {
381 $pointschecked = $this->object->answers[$answer_id]->getPointsChecked();
382 $pointsunchecked = $this->object->answers[$answer_id]->getPointsUnchecked();
383 $resulttextchecked = ($pointschecked == 1) || ($pointschecked == -1) ? "%s " . $this->lng->txt("point") : "%s " . $this->lng->txt("points");
384 $resulttextunchecked = ($pointsunchecked == 1) || ($pointsunchecked == -1) ? "%s " . $this->lng->txt("point") : "%s " . $this->lng->txt("points");
385 $template->setVariable("RESULT_OUTPUT", sprintf("(" . $this->lng->txt("checkbox_checked") . " = $resulttextchecked, " . $this->lng->txt("checkbox_unchecked") . " = $resulttextunchecked)", $pointschecked, $pointsunchecked));
386 }
387 foreach ($user_solution as $mc_solution)
388 {
389 if (strcmp($mc_solution, $answer_id) == 0)
390 {
392 {
393 $template->setVariable("SOLUTION_IMAGE", ilUtil::getHtmlPath(ilUtil::getImagePath("checkbox_checked.png")));
394 $template->setVariable("SOLUTION_ALT", $this->lng->txt("checked"));
395 }
396 else
397 {
398 $template->setVariable('QID', $this->object->getId());
399 $template->setVariable('SUFFIX', $show_correct_solution ? 'bestsolution' : 'usersolution');
400 $template->setVariable('SOLUTION_VALUE', $answer_id);
401 $template->setVariable('SOLUTION_CHECKED', 'checked');
402 }
403 $checked = TRUE;
404 }
405 }
406 if (!$checked)
407 {
409 {
410 $template->setVariable("SOLUTION_IMAGE", ilUtil::getHtmlPath(ilUtil::getImagePath("checkbox_unchecked.png")));
411 $template->setVariable("SOLUTION_ALT", $this->lng->txt("unchecked"));
412 }
413 else
414 {
415 $template->setVariable('QID', $this->object->getId());
416 $template->setVariable('SUFFIX', $show_correct_solution ? 'bestsolution' : 'usersolution');
417 $template->setVariable('SOLUTION_VALUE', $answer_id);
418 }
419 }
420 $template->parseCurrentBlock();
421 }
422 $questiontext = $this->object->getQuestion();
423 if ($show_question_text==true)
424 {
425 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
426 }
427 $questionoutput = $template->get();
428 $feedback = ($show_feedback && !$this->isTestPresentationContext()) ? $this->getAnswerFeedbackOutput($active_id, $pass) : "";
429
430 if (strlen($feedback))
431 {
432 $cssClass = ( $this->hasCorrectSolution($active_id, $pass) ?
434 );
435
436 $solutiontemplate->setVariable("ILC_FB_CSS_CLASS", $cssClass);
437 $solutiontemplate->setVariable("FEEDBACK", $this->object->prepareTextareaOutput( $feedback , true ));
438 }
439 $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
440
441 $solutionoutput = $solutiontemplate->get();
442 if (!$show_question_only)
443 {
444 // get page object output
445 $solutionoutput = $this->getILIASPage($solutionoutput);
446 }
447 return $solutionoutput;
448 }
449
450 function getPreview($show_question_only = FALSE, $showInlineFeedback = false)
451 {
452 $user_solution = is_object($this->getPreviewSession()) ? (array)$this->getPreviewSession()->getParticipantsSolution() : array();
453 // shuffle output
454 $keys = $this->getChoiceKeys();
455
456 // generate the question output
457 include_once "./Services/UICore/classes/class.ilTemplate.php";
458 $template = new ilTemplate("tpl.il_as_qpl_mc_mr_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
459 foreach ($keys as $answer_id)
460 {
461 $answer = $this->object->answers[$answer_id];
462 if (strlen($answer->getImage()))
463 {
464 if ($this->object->getThumbSize())
465 {
466 $template->setCurrentBlock("preview");
467 $template->setVariable("URL_PREVIEW", $this->object->getImagePathWeb() . $answer->getImage());
468 $template->setVariable("TEXT_PREVIEW", $this->lng->txt('preview'));
469 $template->setVariable("IMG_PREVIEW", ilUtil::getImagePath('enlarge.svg'));
470 $template->setVariable("ANSWER_IMAGE_URL", $this->object->getImagePathWeb() . $this->object->getThumbPrefix() . $answer->getImage());
471 list($width, $height, $type, $attr) = getimagesize($this->object->getImagePath() . $answer->getImage());
472 $alt = $answer->getImage();
473 if (strlen($answer->getAnswertext()))
474 {
475 $alt = $answer->getAnswertext();
476 }
477 $alt = preg_replace("/<[^>]*?>/", "", $alt);
478 $template->setVariable("ANSWER_IMAGE_ALT", ilUtil::prepareFormOutput($alt));
479 $template->setVariable("ANSWER_IMAGE_TITLE", ilUtil::prepareFormOutput($alt));
480 $template->parseCurrentBlock();
481 }
482 else
483 {
484 $template->setCurrentBlock("answer_image");
485 $template->setVariable("ANSWER_IMAGE_URL", $this->object->getImagePathWeb() . $answer->getImage());
486 list($width, $height, $type, $attr) = getimagesize($this->object->getImagePath() . $answer->getImage());
487 $alt = $answer->getImage();
488 if (strlen($answer->getAnswertext()))
489 {
490 $alt = $answer->getAnswertext();
491 }
492 $alt = preg_replace("/<[^>]*?>/", "", $alt);
493 $template->setVariable("ATTR", $attr);
494 $template->setVariable("ANSWER_IMAGE_ALT", ilUtil::prepareFormOutput($alt));
495 $template->setVariable("ANSWER_IMAGE_TITLE", ilUtil::prepareFormOutput($alt));
496 $template->parseCurrentBlock();
497 }
498 }
499
500 if( $showInlineFeedback )
501 {
502 $this->populateSpecificFeedbackInline($user_solution, $answer_id, $template);
503 }
504
505 $template->setCurrentBlock("answer_row");
506 $template->setVariable("QID", $this->object->getId());
507 $template->setVariable("ANSWER_ID", $answer_id);
508 $template->setVariable("ANSWER_TEXT", $this->object->prepareTextareaOutput($answer->getAnswertext(), TRUE));
509 foreach ($user_solution as $mc_solution)
510 {
511 if (strcmp($mc_solution, $answer_id) == 0)
512 {
513 $template->setVariable("CHECKED_ANSWER", " checked=\"checked\"");
514 }
515 }
516 $template->parseCurrentBlock();
517 }
518 if($this->object->getSelectionLimit())
519 {
520 $template->setVariable('SELECTION_LIMIT_HINT', sprintf(
521 $this->lng->txt('ass_mc_sel_lim_hint'),
522 $this->object->getSelectionLimit(),
523 $this->object->getAnswerCount()
524 ));
525
526 $template->setVariable('SELECTION_LIMIT_VALUE', $this->object->getSelectionLimit());
527 }
528 else
529 {
530 $template->setVariable('SELECTION_LIMIT_VALUE', 'null');
531 }
532 $template->setVariable("QUESTION_ID", $this->object->getId());
533 $questiontext = $this->object->getQuestion();
534 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
535 $questionoutput = $template->get();
536 if (!$show_question_only)
537 {
538 // get page object output
539 $questionoutput = $this->getILIASPage($questionoutput);
540 }
541 return $questionoutput;
542 }
543
554 $active_id,
555 // hey: prevPassSolutions - will be always available from now on
556 $pass,
557 // hey.
558 $is_postponed = FALSE,
559 $use_post_solutions = FALSE,
560 $show_feedback = FALSE
561 )
562 {
563 // shuffle output
564 $keys = $this->getChoiceKeys();
565
566 // get the solution of the user for the active pass or from the last pass if allowed
567 $user_solution = array();
568 if ($active_id)
569 {
570 // hey: prevPassSolutions - obsolete due to central check
571 #$solutions = NULL;
572 #include_once "./Modules/Test/classes/class.ilObjTest.php";
573 #if (!ilObjTest::_getUsePreviousAnswers($active_id, true))
574 #{
575 # if (is_null($pass)) $pass = ilObjTest::_getPass($active_id);
576 #}
577 $solutions = $this->object->getTestOutputSolutions($active_id, $pass);
578 // hey.
579 foreach ($solutions as $idx => $solution_value)
580 {
581// fau: testNav - don't add the dummy entry for 'none of the above' to the user options
582 if ( $solution_value["value1"] != 'mc_none_above')
583 {
584 array_push($user_solution, $solution_value["value1"]);
585 }
586// fau.
587 }
588 }
589 // generate the question output
590 include_once "./Services/UICore/classes/class.ilTemplate.php";
591 $template = new ilTemplate("tpl.il_as_qpl_mc_mr_output.html", TRUE, TRUE, "Modules/TestQuestionPool");
592 foreach ($keys as $answer_id)
593 {
594 $answer = $this->object->answers[$answer_id];
595 if (strlen($answer->getImage()))
596 {
597 if ($this->object->getThumbSize())
598 {
599 $template->setCurrentBlock("preview");
600 $template->setVariable("URL_PREVIEW", $this->object->getImagePathWeb() . $answer->getImage());
601 $template->setVariable("TEXT_PREVIEW", $this->lng->txt('preview'));
602 $template->setVariable("IMG_PREVIEW", ilUtil::getImagePath('enlarge.svg'));
603 $template->setVariable("ANSWER_IMAGE_URL", $this->object->getImagePathWeb() . $this->object->getThumbPrefix() . $answer->getImage());
604 list($width, $height, $type, $attr) = getimagesize($this->object->getImagePath() . $answer->getImage());
605 $alt = $answer->getImage();
606 if (strlen($answer->getAnswertext()))
607 {
608 $alt = $answer->getAnswertext();
609 }
610 $alt = preg_replace("/<[^>]*?>/", "", $alt);
611 $template->setVariable("ANSWER_IMAGE_ALT", ilUtil::prepareFormOutput($alt));
612 $template->setVariable("ANSWER_IMAGE_TITLE", ilUtil::prepareFormOutput($alt));
613 $template->parseCurrentBlock();
614 }
615 else
616 {
617 $template->setCurrentBlock("answer_image");
618 $template->setVariable("ANSWER_IMAGE_URL", $this->object->getImagePathWeb() . $answer->getImage());
619 list($width, $height, $type, $attr) = getimagesize($this->object->getImagePath() . $answer->getImage());
620 $alt = $answer->getImage();
621 if (strlen($answer->getAnswertext()))
622 {
623 $alt = $answer->getAnswertext();
624 }
625 $alt = preg_replace("/<[^>]*?>/", "", $alt);
626 $template->setVariable("ATTR", $attr);
627 $template->setVariable("ANSWER_IMAGE_ALT", ilUtil::prepareFormOutput($alt));
628 $template->setVariable("ANSWER_IMAGE_TITLE", ilUtil::prepareFormOutput($alt));
629 $template->parseCurrentBlock();
630 }
631 }
632
633 if( $show_feedback )
634 {
635 $this->populateSpecificFeedbackInline($user_solution, $answer_id, $template);
636 }
637
638 $template->setCurrentBlock("answer_row");
639 $template->setVariable("QID", $this->object->getId());
640 $template->setVariable("ANSWER_ID", $answer_id);
641 $template->setVariable("ANSWER_TEXT", $this->object->prepareTextareaOutput($answer->getAnswertext(), TRUE));
642 foreach ($user_solution as $mc_solution)
643 {
644 if (strcmp($mc_solution, $answer_id) == 0)
645 {
646 $template->setVariable("CHECKED_ANSWER", " checked=\"checked\"");
647 }
648 }
649 $template->parseCurrentBlock();
650 }
651
652// fau: testNav - add 'none of the above', if needed by the deprecated test setting to score empty answers
653 if ($this->withNoneAbove)
654 {
655 $this->tpl->addJavaScript('Modules/TestQuestionPool/js/ilAssMultipleChoice.js');
656 $template->setCurrentBlock('none_above');
657 $template->setVariable('LABEL_NONE_ABOVE', $this->lng->txt('tst_mc_label_none_above'));
658 if ($this->isAnswered && empty($user_solution))
659 {
660 $template->setVariable('CHECKED_NONE_ABOVE', " checked=\"checked\"");
661 }
662 $template->parseCurrentBlock();
663 }
664// fau.
665
666 $questiontext = $this->object->getQuestion();
667 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, TRUE));
668 $template->setVariable("QUESTION_ID", $this->object->getId());
669 if($this->object->getSelectionLimit())
670 {
671 $template->setVariable('SELECTION_LIMIT_HINT', sprintf(
672 $this->lng->txt('ass_mc_sel_lim_hint'),
673 $this->object->getSelectionLimit(),
674 $this->object->getAnswerCount()
675 ));
676
677 $template->setVariable('SELECTION_LIMIT_VALUE', $this->object->getSelectionLimit());
678 }
679 else
680 {
681 $template->setVariable('SELECTION_LIMIT_VALUE', 'null');
682 }
683 $questionoutput = $template->get();
684 $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput);
685 return $pageoutput;
686 }
687
689 {
690 $tpl->addJavaScript('Modules/TestQuestionPool/js/ilAssMultipleChoice.js');
691 }
692
698 public function setQuestionTabs()
699 {
700 global $rbacsystem, $ilTabs;
701
702 $ilTabs->clearTargets();
703
704 $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $_GET["q_id"]);
705 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
706 $q_type = $this->object->getQuestionType();
707
708 if (strlen($q_type))
709 {
710 $classname = $q_type . "GUI";
711 $this->ctrl->setParameterByClass(strtolower($classname), "sel_question_types", $q_type);
712 $this->ctrl->setParameterByClass(strtolower($classname), "q_id", $_GET["q_id"]);
713 }
714
715 if ($_GET["q_id"])
716 {
717 if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
718 {
719 // edit page
720 $ilTabs->addTarget("edit_page",
721 $this->ctrl->getLinkTargetByClass("ilAssQuestionPageGUI", "edit"),
722 array("edit", "insert", "exec_pg"),
723 "", "", $force_active);
724 }
725
726 $this->addTab_QuestionPreview($ilTabs);
727 }
728 $force_active = false;
729 if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
730 {
731 $url = "";
732 if ($classname) $url = $this->ctrl->getLinkTargetByClass($classname, "editQuestion");
733 $force_active = false;
734 // edit question properties
735 $ilTabs->addTarget("edit_question",
736 $url,
737 array("editQuestion", "save", "saveEdit", "addchoice", "removechoice", "removeimagechoice", "uploadchoice", "originalSyncForm"),
738 $classname, "", $force_active);
739 }
740
741 // add tab for question feedback within common class assQuestionGUI
742 $this->addTab_QuestionFeedback($ilTabs);
743
744 // add tab for question hint within common class assQuestionGUI
745 $this->addTab_QuestionHints($ilTabs);
746
747 // add tab for question's suggested solution within common class assQuestionGUI
748 $this->addTab_SuggestedSolution($ilTabs, $classname);
749
750 // Assessment of questions sub menu entry
751 if ($_GET["q_id"])
752 {
753 $ilTabs->addTarget("statistics",
754 $this->ctrl->getLinkTargetByClass($classname, "assessment"),
755 array("assessment"),
756 $classname, "");
757 }
758
759 $this->addBackTab($ilTabs);
760 }
761
767 function getChoiceKeys()
768 {
769 $choiceKeys = array_keys($this->object->answers);
770
771 if( $this->object->getShuffle() )
772 {
773 $choiceKeys = $this->object->getShuffler()->shuffle($choiceKeys);
774 }
775
776 return $choiceKeys;
777 }
778
779 function getSpecificFeedbackOutput($active_id, $pass)
780 {
781 // No return value, this question type supports inline specific feedback.
782 $output = "";
783 return $this->object->prepareTextareaOutput($output, TRUE);
784 }
785
787 {
788 $this->object->setShuffle( $_POST["shuffle"] );
789
790 $selectionLimit = (int)$form->getItemByPostVar('selection_limit')->getValue();
791 $this->object->setSelectionLimit($selectionLimit > 0 ? $selectionLimit : null);
792
793 $this->object->setMultilineAnswerSetting( $_POST["types"] );
794 if (is_array( $_POST['choice']['imagename'] ) && $_POST["types"] == 1)
795 {
796 $this->object->isSingleline = true;
797 ilUtil::sendInfo( $this->lng->txt( 'info_answer_type_change' ), true );
798 }
799 else
800 {
801 $this->object->isSingleline = ($_POST["types"] == 0) ? true : false;
802 }
803 $this->object->setThumbSize( (strlen( $_POST["thumb_size"] )) ? $_POST["thumb_size"] : "" );
804 }
805
807 {
808 // Delete all existing answers and create new answers from the form data
809 $this->object->flushAnswers();
810 if ($this->object->isSingleline)
811 {
812 foreach ($_POST['choice']['answer'] as $index => $answertext)
813 {
814 $answertext = ilUtil::secureString($answertext);
815
816 $picturefile = $_POST['choice']['imagename'][$index];
817 $file_org_name = $_FILES['choice']['name']['image'][$index];
818 $file_temp_name = $_FILES['choice']['tmp_name']['image'][$index];
819
820 if (strlen( $file_temp_name ))
821 {
822 // check suffix
823 $suffix = strtolower( array_pop( explode( ".", $file_org_name ) ) );
824 if (in_array( $suffix, array( "jpg", "jpeg", "png", "gif" ) ))
825 {
826 // upload image
827 $filename = $this->object->buildHashedImageFilename( $file_org_name );
828 if ($this->object->setImageFile( $filename, $file_temp_name ) == 0)
829 {
830 $picturefile = $filename;
831 }
832 }
833 }
834 $this->object->addAnswer( $answertext,
835 $_POST['choice']['points'][$index],
836 $_POST['choice']['points_unchecked'][$index],
837 $index,
838 $picturefile
839 );
840 }
841 }
842 else
843 {
844 foreach ($_POST['choice']['answer'] as $index => $answer)
845 {
846 $answertext = $answer;
847 $this->object->addAnswer( $answertext,
848 $_POST['choice']['points'][$index],
849 $_POST['choice']['points_unchecked'][$index],
850 $index
851 );
852 }
853 }
854 }
855
857 {
858 // shuffle
859 $shuffle = new ilCheckboxInputGUI($this->lng->txt( "shuffle_answers" ), "shuffle");
860 $shuffle->setValue( 1 );
861 $shuffle->setChecked( $this->object->getShuffle() );
862 $shuffle->setRequired( FALSE );
863 $form->addItem( $shuffle );
864
865 require_once 'Services/Form/classes/class.ilNumberInputGUI.php';
866 $selLim = new ilNumberInputGUI($this->lng->txt('ass_mc_sel_lim_setting'), 'selection_limit');
867 $selLim->setInfo($this->lng->txt('ass_mc_sel_lim_setting_desc'));
868 $selLim->setSize(2);
869 $selLim->setRequired(false);
870 $selLim->allowDecimals(false);
871 $selLim->setMinvalueShouldBeGreater(false);
872 $selLim->setMaxvalueShouldBeLess(false);
873 $selLim->setMinValue(1);
874 $selLim->setMaxValue($this->object->getAnswerCount());
875 $selLim->setValue($this->object->getSelectionLimit());
876 $form->addItem($selLim);
877
878 if ($this->object->getId())
879 {
880 $hidden = new ilHiddenInputGUI("", "ID");
881 $hidden->setValue( $this->object->getId() );
882 $form->addItem( $hidden );
883 }
884
885 $isSingleline = $this->getEditAnswersSingleLine();
886
887 if (!$this->object->getSelfAssessmentEditingMode())
888 {
889 // Answer types
890 $types = new ilSelectInputGUI($this->lng->txt( "answer_types" ), "types");
891 $types->setRequired( false );
892 $types->setValue( ($isSingleline) ? 0 : 1 );
893 $types->setOptions( array(
894 0 => $this->lng->txt( 'answers_singleline' ),
895 1 => $this->lng->txt( 'answers_multiline' ),
896 )
897 );
898 $form->addItem( $types );
899 }
900
901 if ($isSingleline)
902 {
903 // thumb size
904 $thumb_size = new ilNumberInputGUI($this->lng->txt( "thumb_size" ), "thumb_size");
905 $thumb_size->setSuffix($this->lng->txt("thumb_size_unit_pixel"));
906 $thumb_size->setMinValue( 20 );
907 $thumb_size->setDecimals( 0 );
908 $thumb_size->setSize( 6 );
909 $thumb_size->setInfo( $this->lng->txt( 'thumb_size_info' ) );
910 $thumb_size->setValue( $this->object->getThumbSize() );
911 $thumb_size->setRequired( false );
912 $form->addItem( $thumb_size );
913 return $isSingleline;
914 }
915 return $isSingleline;
916 }
917
919 {
920 // Choices
921 include_once "./Modules/TestQuestionPool/classes/class.ilMultipleChoiceWizardInputGUI.php";
922 $choices = new ilMultipleChoiceWizardInputGUI($this->lng->txt( "answers" ), "choice");
923 $choices->setRequired( true );
924 $choices->setQuestionObject( $this->object );
925 $isSingleline = $this->getEditAnswersSingleLine();
926 $choices->setSingleline( $isSingleline );
927 $choices->setAllowMove( false );
928 if ($this->object->getSelfAssessmentEditingMode())
929 {
930 $choices->setSize( 40 );
931 }
932 $choices->setMaxLength( 800 );
933 if ($this->object->getAnswerCount() == 0)
934 $this->object->addAnswer( "", 0, 0, 0 );
935 $choices->setValues( $this->object->getAnswers() );
936 $form->addItem( $choices );
937 }
938
949 {
950 return array();
951 }
952
963 {
964 return array();
965 }
966
975 public function getAggregatedAnswersView($relevant_answers)
976 {
977 return $this->renderAggregateView(
978 $this->aggregateAnswers( $relevant_answers, $this->object->getAnswers() ) )->get();
979 }
980
981 public function aggregateAnswers($relevant_answers_chosen, $answers_defined_on_question)
982 {
983 $aggregate = array();
984 foreach ($answers_defined_on_question as $answer)
985 {
986 $aggregated_info_for_answer = array();
987 $aggregated_info_for_answer['answertext'] = $answer->getAnswerText();
988 $aggregated_info_for_answer['count_checked'] = 0;
989
990 foreach ($relevant_answers_chosen as $relevant_answer)
991 {
992 if ($relevant_answer['value1'] == $answer->getOrder())
993 {
994 $aggregated_info_for_answer['count_checked']++;
995 }
996 }
997 $aggregated_info_for_answer['count_unchecked'] =
998 ceil(count($relevant_answers_chosen) / count($answers_defined_on_question))
999 - $aggregated_info_for_answer['count_checked'];
1000
1001 $aggregate[] = $aggregated_info_for_answer;
1002 }
1003 return $aggregate;
1004 }
1005
1011 public function renderAggregateView($aggregate)
1012 {
1013 $tpl = new ilTemplate('tpl.il_as_aggregated_answers_table.html', true, true, "Modules/TestQuestionPool");
1014
1015 $tpl->setCurrentBlock('headercell');
1016 $tpl->setVariable('HEADER', $this->lng->txt('tst_answer_aggr_answer_header'));
1017 $tpl->parseCurrentBlock();
1018
1019 $tpl->setCurrentBlock('headercell');
1020 $tpl->setVariable('HEADER', $this->lng->txt('tst_answer_aggr_frequency_header'));
1021 $tpl->parseCurrentBlock();
1022
1023 foreach ($aggregate as $line_data)
1024 {
1025 $tpl->setCurrentBlock( 'aggregaterow' );
1026 $tpl->setVariable( 'OPTION', $line_data['answertext'] );
1027 $tpl->setVariable( 'COUNT', $line_data['count_checked'] );
1028 $tpl->parseCurrentBlock();
1029 }
1030 return $tpl;
1031 }
1032
1039 private function populateSpecificFeedbackInline($user_solution, $answer_id, $template)
1040 {
1041 if($this->object->getSpecificFeedbackSetting() == 2)
1042 {
1043 foreach($user_solution as $mc_solution)
1044 {
1045 if(strcmp($mc_solution, $answer_id) == 0)
1046 {
1047 $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation($this->object->getId(), $answer_id);
1048 if(strlen($fb))
1049 {
1050 $template->setCurrentBlock("feedback");
1051 $template->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($fb, true));
1052 $template->parseCurrentBlock();
1053 }
1054 }
1055 }
1056 }
1057
1058 if($this->object->getSpecificFeedbackSetting() == 1)
1059 {
1060 $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation($this->object->getId(), $answer_id);
1061 if(strlen($fb))
1062 {
1063 $template->setCurrentBlock("feedback");
1064 $template->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($fb, true));
1065 $template->parseCurrentBlock();
1066 }
1067 }
1068
1069 if($this->object->getSpecificFeedbackSetting() == 3)
1070 {
1071 $answer = $this->object->getAnswer($answer_id);
1072
1073 if($answer->getPoints() > 0)
1074 {
1075 $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation($this->object->getId(), $answer_id);
1076 if(strlen($fb))
1077 {
1078 $template->setCurrentBlock("feedback");
1079 $template->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($fb, true));
1080 $template->parseCurrentBlock();
1081 }
1082 }
1083 }
1084 }
1085
1086 // fau: testNav - new functions setWithNoneAbove() and setIsAnswered()
1087
1092 public function setWithNoneAbove($a_with_none_above)
1093 {
1094 $this->withNoneAbove = (bool) $a_with_none_above;
1095 }
1096
1101 public function setIsAnswered($a_is_answered)
1102 {
1103 $this->isAnswered = (bool) $a_is_answered;
1104 }
1105 // fau.
1106
1110 protected function buildEditForm()
1111 {
1112 include_once("./Services/Form/classes/class.ilPropertyFormGUI.php");
1113 $form = new ilPropertyFormGUI();
1114 $form->setFormAction($this->ctrl->getFormAction($this));
1115 $form->setTitle($this->outQuestionType());
1116 $form->setTableWidth("100%");
1117 $form->setId("assmultiplechoice");
1118
1119 // title, author, description, question, working time (assessment mode)
1120 $this->addBasicQuestionFormProperties($form);
1122 $this->populateAnswerSpecificFormPart($form);
1123 $this->populateTaxonomyFormSection($form);
1124 $this->addQuestionFormCommandButtons($form);
1125 return $form;
1126 }
1127}
sprintf('%.4f', $callTime)
$_GET["client_id"]
$_POST["username"]
An exception for terminatinating execution or to throw for unit testing.
Multiple choice question GUI representation.
setIsAnswered($a_is_answered)
Show the question as answered in a test run.
getAggregatedAnswersView($relevant_answers)
Returns an html string containing a question specific representation of the answers so far given in t...
getAfterParticipationSuppressionAnswerPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
addBasicQuestionFormProperties($form)
Add basic question form properties: assessment: title, author, description, question,...
getChoiceKeys()
Create the key index numbers for the array of choices.
getAfterParticipationSuppressionQuestionPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
aggregateAnswers($relevant_answers_chosen, $answers_defined_on_question)
populateSpecificFeedbackInline($user_solution, $answer_id, $template)
editQuestion($checkonly=FALSE)
Creates an output of the edit form for the question.
writeAnswerSpecificPostData(ilPropertyFormGUI $form)
Extracts the answer specific values from $_POST and applies them to the data object.
populateQuestionSpecificFormPart(\ilPropertyFormGUI $form)
getEditAnswersSingleLine($checkonly=false)
Get the single/multiline editing of answers.
populateJavascriptFilesRequiredForWorkForm(ilTemplate $tpl)
__construct($id=-1)
assMultipleChoiceGUI constructor
getSpecificFeedbackOutput($active_id, $pass)
Returns the answer specific feedback for the question.
getPreview($show_question_only=FALSE, $showInlineFeedback=false)
populateAnswerSpecificFormPart(\ilPropertyFormGUI $form)
getTestOutput( $active_id, $pass, $is_postponed=FALSE, $use_post_solutions=FALSE, $show_feedback=FALSE)
setQuestionTabs()
Sets the ILIAS tabs for this question type.
setWithNoneAbove($a_with_none_above)
Enable the 'None above' addition in a test run.
writeQuestionSpecificPostData(ilPropertyFormGUI $form)
Extracts the question specific values from $_POST and applies them to the data object.
writePostData($always=false)
{Evaluates a posted edit form and writes the form data in the question object.integer A positive valu...
getSolutionOutput( $active_id, $pass=NULL, $graphicalOutput=FALSE, $result_output=FALSE, $show_question_only=TRUE, $show_feedback=FALSE, $show_correct_solution=FALSE, $show_manual_scoring=FALSE, $show_question_text=TRUE)
Get the question solution output.
Class for multiple choice tests.
Basic GUI class for assessment questions.
populateTaxonomyFormSection(ilPropertyFormGUI $form)
addTab_QuestionHints(ilTabsGUI $tabs)
adds the hints tab to ilTabsGUI
addQuestionFormCommandButtons($form)
Add the command buttons of a question properties form.
getILIASPage($html="")
Returns the ILIAS Page around a question.
getQuestionTemplate()
get question template
addTab_SuggestedSolution(ilTabsGUI $tabs, $classname)
outQuestionPage($a_temp_var, $a_postponed=false, $active_id="", $html="")
output question page
addBackTab(ilTabsGUI $ilTabs)
hasCorrectSolution($activeId, $passIndex)
addTab_QuestionFeedback(ilTabsGUI $tabs)
adds the feedback tab to ilTabsGUI
addTab_QuestionPreview(ilTabsGUI $tabsGUI)
getAnswerFeedbackOutput($active_id, $pass)
Returns the answer generic feedback depending on the results of the question.
This class represents a checkbox property in a property form.
This class represents a hidden form property in a property form.
This class represents a multiple choice wizard property in a property form.
This class represents a number property in a property form.
This class represents a property form user interface.
addItem($a_item)
Add Item (Property, SectionHeader).
getItemByPostVar($a_post_var)
Get Item by POST variable.
This class represents a selection list property in a property form.
special template class to simplify handling of ITX/PEAR
static secureString($a_str, $a_strip_html=true, $a_allow="")
Remove unsecure tags.
static getHtmlPath($relative_path)
get url of path
static sendInfo($a_info="", $a_keep=false)
Send Info Message to Screen.
static getImagePath($img, $module_path="", $mode="output", $offline=false)
get image path (for images located in a template directory)
static prepareFormOutput($a_str, $a_strip=false)
prepares string output for html forms @access public
if(!is_dir( $entity_dir)) exit("Fatal Error ([A-Za-z0-9]+)\s+" &#(? foreach( $entity_files as $file) $output
Interface ilGuiAnswerScoringAdjustable.
Interface ilGuiQuestionScoringAdjustable.
$url
Definition: shib_logout.php:72
$errors