ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
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 public 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 $this->object->loadFromDb($id);
42 }
43 }
44
48 protected function writePostData($always = false)
49 {
50 $hasErrors = (!$always) ? $this->editQuestion(true) : false;
51 if (!$hasErrors) {
52 $form = $this->buildEditForm();
53 $form->setValuesByPost();
54 require_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
59 return 0;
60 }
61 return 1;
62 }
63
71 protected function getEditAnswersSingleLine($checkonly = false)
72 {
73 if ($checkonly) {
74 // form posting is checked
75 return ($_POST['types'] == 0) ? true : false;
76 }
77
78 $lastChange = $this->object->getLastChange();
79 if (empty($lastChange) && !isset($_POST['types'])) {
80 // a new question is edited
81 return $this->object->getMultilineAnswerSetting() ? false : true;
82 } else {
83 // a saved question is edited
84 return $this->object->isSingleline;
85 }
86 }
87
95 public function editQuestion($checkonly = false)
96 {
97 $save = $this->isSaveCommand();
98 $this->getQuestionTemplate();
99
100 $form = $this->buildEditForm();
101
102 $isSingleline = $this->getEditAnswersSingleLine($checkonly);
103 if ($isSingleline) {
104 $form->setMultipart(true);
105 } else {
106 $form->setMultipart(false);
107 }
108
109 $errors = false;
110
111 if ($save) {
112 $form->getItemByPostVar('selection_limit')->setMaxValue(count((array) $_POST['choice']['answer']));
113
114 $form->setValuesByPost();
115 $errors = !$form->checkInput();
116 $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
117 if ($errors) {
118 $checkonly = false;
119 }
120 }
121
122 if (!$checkonly) {
123 $this->tpl->setVariable("QUESTION_DATA", $form->getHTML());
124 }
125 return $errors;
126 }
127
129 {
130 parent::addBasicQuestionFormProperties($form);
131 $form->getItemByPostVar('question')->setInitialRteWidth('100');
132 }
133
137 public function uploadchoice()
138 {
139 $this->writePostData(true);
140 $position = key($_POST['cmd']['uploadchoice']);
141 $this->editQuestion();
142 }
143
147 public function removeimagechoice()
148 {
149 $this->writePostData(true);
150 $position = key($_POST['cmd']['removeimagechoice']);
151 $filename = $_POST['choice']['imagename'][$position];
152 $this->object->removeAnswerImage($position);
153 $this->editQuestion();
154 }
155
159 public function addchoice()
160 {
161 $this->writePostData(true);
162 $position = key($_POST['cmd']['addchoice']);
163 $this->object->addAnswer("", 0, 0, $position+1);
164 $this->editQuestion();
165 }
166
170 public function removechoice()
171 {
172 $this->writePostData(true);
173 $position = key($_POST['cmd']['removechoice']);
174 $this->object->deleteAnswer($position);
175 $this->editQuestion();
176 }
177
193 public function getSolutionOutput(
194 $active_id,
195 $pass = null,
196 $graphicalOutput = false,
197 $result_output = false,
198 $show_question_only = true,
199 $show_feedback = false,
200 $show_correct_solution = false,
201 $show_manual_scoring = false,
202 $show_question_text = true
203 ) {
204 // shuffle output
205 $keys = $this->getChoiceKeys();
206
207 // get the solution of the user for the active pass or from the last pass if allowed
208 $user_solution = array();
209 if (($active_id > 0) && (!$show_correct_solution)) {
210 $solutions =&$this->object->getSolutionValues($active_id, $pass);
211 foreach ($solutions as $idx => $solution_value) {
212 array_push($user_solution, $solution_value["value1"]);
213 }
214 } else {
215 // take the correct solution instead of the user solution
216 foreach ($this->object->answers as $index => $answer) {
217 $points_checked = $answer->getPointsChecked();
218 $points_unchecked = $answer->getPointsUnchecked();
219 if ($points_checked > $points_unchecked) {
220 if ($points_checked > 0) {
221 array_push($user_solution, $index);
222 }
223 }
224 }
225 }
226
227 // generate the question output
228 include_once "./Services/UICore/classes/class.ilTemplate.php";
229 $template = new ilTemplate("tpl.il_as_qpl_mc_mr_output_solution.html", true, true, "Modules/TestQuestionPool");
230 $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html", true, true, "Modules/TestQuestionPool");
231 foreach ($keys as $answer_id) {
232 $answer = $this->object->answers[$answer_id];
233 if (($active_id > 0) && (!$show_correct_solution)) {
234 if ($graphicalOutput) {
235 // output of ok/not ok icons for user entered solutions
236 $ok = false;
237 $checked = false;
238 foreach ($user_solution as $mc_solution) {
239 if (strcmp($mc_solution, $answer_id) == 0) {
240 $checked = true;
241 }
242 }
243 if ($checked) {
244 if ($answer->getPointsChecked() > $answer->getPointsUnchecked()) {
245 $ok = true;
246 } else {
247 $ok = false;
248 }
249 } else {
250 if ($answer->getPointsChecked() > $answer->getPointsUnchecked()) {
251 $ok = false;
252 } else {
253 $ok = true;
254 }
255 }
256 if ($ok) {
257 $template->setCurrentBlock("icon_ok");
258 $template->setVariable("ICON_OK", ilUtil::getImagePath("icon_ok.svg"));
259 $template->setVariable("TEXT_OK", $this->lng->txt("answer_is_right"));
260 $template->parseCurrentBlock();
261 } else {
262 $template->setCurrentBlock("icon_ok");
263 $template->setVariable("ICON_NOT_OK", ilUtil::getImagePath("icon_not_ok.svg"));
264 $template->setVariable("TEXT_NOT_OK", $this->lng->txt("answer_is_wrong"));
265 $template->parseCurrentBlock();
266 }
267 }
268 }
269 if (strlen($answer->getImage())) {
270 $template->setCurrentBlock("answer_image");
271 if ($this->object->getThumbSize()) {
272 $template->setVariable("ANSWER_IMAGE_URL", $this->object->getImagePathWeb() . $this->object->getThumbPrefix() . $answer->getImage());
273 } else {
274 $template->setVariable("ANSWER_IMAGE_URL", $this->object->getImagePathWeb() . $answer->getImage());
275 }
276 $alt = $answer->getImage();
277 if (strlen($answer->getAnswertext())) {
278 $alt = $answer->getAnswertext();
279 }
280 $alt = preg_replace("/<[^>]*?>/", "", $alt);
281 $template->setVariable("ANSWER_IMAGE_ALT", ilUtil::prepareFormOutput($alt));
282 $template->setVariable("ANSWER_IMAGE_TITLE", ilUtil::prepareFormOutput($alt));
283 $template->parseCurrentBlock();
284 }
285
286 if ($show_feedback) {
287 if ($this->object->getSpecificFeedbackSetting() == 2) {
288 foreach ($user_solution as $mc_solution) {
289 if (strcmp($mc_solution, $answer_id) == 0) {
290 $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
291 $this->object->getId(),
292 $answer_id
293 );
294 if (strlen($fb)) {
295 $template->setCurrentBlock("feedback");
296 $template->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($fb, true));
297 $template->parseCurrentBlock();
298 }
299 }
300 }
301 }
302
303 if ($this->object->getSpecificFeedbackSetting() == 1) {
304 $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
305 $this->object->getId(),
306 $answer_id
307 );
308 if (strlen($fb)) {
309 $template->setCurrentBlock("feedback");
310 $template->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($fb, true));
311 $template->parseCurrentBlock();
312 }
313 }
314
315 if ($this->object->getSpecificFeedbackSetting() == 3) {
316 $answer = $this->object->getAnswer($answer_id);
317
318 if ($answer->getPoints() > 0) {
319 $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
320 $this->object->getId(),
321 $answer_id
322 );
323 if (strlen($fb)) {
324 $template->setCurrentBlock("feedback");
325 $template->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($fb, true));
326 $template->parseCurrentBlock();
327 }
328 }
329 }
330 }
331 $template->setCurrentBlock("answer_row");
332 $template->setVariable("ANSWER_TEXT", $this->object->prepareTextareaOutput($answer->getAnswertext(), true));
333 $checked = false;
334 if ($result_output) {
335 $pointschecked = $this->object->answers[$answer_id]->getPointsChecked();
336 $pointsunchecked = $this->object->answers[$answer_id]->getPointsUnchecked();
337 $resulttextchecked = ($pointschecked == 1) || ($pointschecked == -1) ? "%s " . $this->lng->txt("point") : "%s " . $this->lng->txt("points");
338 $resulttextunchecked = ($pointsunchecked == 1) || ($pointsunchecked == -1) ? "%s " . $this->lng->txt("point") : "%s " . $this->lng->txt("points");
339 $template->setVariable("RESULT_OUTPUT", sprintf("(" . $this->lng->txt("checkbox_checked") . " = $resulttextchecked, " . $this->lng->txt("checkbox_unchecked") . " = $resulttextunchecked)", $pointschecked, $pointsunchecked));
340 }
341 foreach ($user_solution as $mc_solution) {
342 if (strcmp($mc_solution, $answer_id) == 0) {
344 $template->setVariable("SOLUTION_IMAGE", ilUtil::getHtmlPath(ilUtil::getImagePath("checkbox_checked.png")));
345 $template->setVariable("SOLUTION_ALT", $this->lng->txt("checked"));
346 } else {
347 $template->setVariable('QID', $this->object->getId());
348 $template->setVariable('SUFFIX', $show_correct_solution ? 'bestsolution' : 'usersolution');
349 $template->setVariable('SOLUTION_VALUE', $answer_id);
350 $template->setVariable('SOLUTION_CHECKED', 'checked');
351 }
352 $checked = true;
353 }
354 }
355 if (!$checked) {
357 $template->setVariable("SOLUTION_IMAGE", ilUtil::getHtmlPath(ilUtil::getImagePath("checkbox_unchecked.png")));
358 $template->setVariable("SOLUTION_ALT", $this->lng->txt("unchecked"));
359 } else {
360 $template->setVariable('QID', $this->object->getId());
361 $template->setVariable('SUFFIX', $show_correct_solution ? 'bestsolution' : 'usersolution');
362 $template->setVariable('SOLUTION_VALUE', $answer_id);
363 }
364 }
365 $template->parseCurrentBlock();
366 }
367 $questiontext = $this->object->getQuestion();
368 if ($show_question_text==true) {
369 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, true));
370 }
371 $questionoutput = $template->get();
372 $feedback = ($show_feedback && !$this->isTestPresentationContext()) ? $this->getAnswerFeedbackOutput($active_id, $pass) : "";
373
374 if (strlen($feedback)) {
375 $cssClass = (
376 $this->hasCorrectSolution($active_id, $pass) ?
378 );
379
380 $solutiontemplate->setVariable("ILC_FB_CSS_CLASS", $cssClass);
381 $solutiontemplate->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($feedback, true));
382 }
383 $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
384
385 $solutionoutput = $solutiontemplate->get();
386 if (!$show_question_only) {
387 // get page object output
388 $solutionoutput = $this->getILIASPage($solutionoutput);
389 }
390 return $solutionoutput;
391 }
392
393 public function getPreview($show_question_only = false, $showInlineFeedback = false)
394 {
395 $user_solution = is_object($this->getPreviewSession()) ? (array) $this->getPreviewSession()->getParticipantsSolution() : array();
396 // shuffle output
397 $keys = $this->getChoiceKeys();
398
399 // generate the question output
400 include_once "./Services/UICore/classes/class.ilTemplate.php";
401 $template = new ilTemplate("tpl.il_as_qpl_mc_mr_output.html", true, true, "Modules/TestQuestionPool");
402 foreach ($keys as $answer_id) {
403 $answer = $this->object->answers[$answer_id];
404 if (strlen($answer->getImage())) {
405 if ($this->object->getThumbSize()) {
406 $template->setCurrentBlock("preview");
407 $template->setVariable("URL_PREVIEW", $this->object->getImagePathWeb() . $answer->getImage());
408 $template->setVariable("TEXT_PREVIEW", $this->lng->txt('preview'));
409 $template->setVariable("IMG_PREVIEW", ilUtil::getImagePath('enlarge.svg'));
410 $template->setVariable("ANSWER_IMAGE_URL", $this->object->getImagePathWeb() . $this->object->getThumbPrefix() . $answer->getImage());
411 list($width, $height, $type, $attr) = getimagesize($this->object->getImagePath() . $answer->getImage());
412 $alt = $answer->getImage();
413 if (strlen($answer->getAnswertext())) {
414 $alt = $answer->getAnswertext();
415 }
416 $alt = preg_replace("/<[^>]*?>/", "", $alt);
417 $template->setVariable("ANSWER_IMAGE_ALT", ilUtil::prepareFormOutput($alt));
418 $template->setVariable("ANSWER_IMAGE_TITLE", ilUtil::prepareFormOutput($alt));
419 $template->parseCurrentBlock();
420 } else {
421 $template->setCurrentBlock("answer_image");
422 $template->setVariable("ANSWER_IMAGE_URL", $this->object->getImagePathWeb() . $answer->getImage());
423 list($width, $height, $type, $attr) = getimagesize($this->object->getImagePath() . $answer->getImage());
424 $alt = $answer->getImage();
425 if (strlen($answer->getAnswertext())) {
426 $alt = $answer->getAnswertext();
427 }
428 $alt = preg_replace("/<[^>]*?>/", "", $alt);
429 $template->setVariable("ATTR", $attr);
430 $template->setVariable("ANSWER_IMAGE_ALT", ilUtil::prepareFormOutput($alt));
431 $template->setVariable("ANSWER_IMAGE_TITLE", ilUtil::prepareFormOutput($alt));
432 $template->parseCurrentBlock();
433 }
434 }
435
436 if ($showInlineFeedback) {
437 $this->populateSpecificFeedbackInline($user_solution, $answer_id, $template);
438 }
439
440 $template->setCurrentBlock("answer_row");
441 $template->setVariable("QID", $this->object->getId());
442 $template->setVariable("ANSWER_ID", $answer_id);
443 $template->setVariable("ANSWER_TEXT", $this->object->prepareTextareaOutput($answer->getAnswertext(), true));
444 foreach ($user_solution as $mc_solution) {
445 if (strcmp($mc_solution, $answer_id) == 0) {
446 $template->setVariable("CHECKED_ANSWER", " checked=\"checked\"");
447 }
448 }
449 $template->parseCurrentBlock();
450 }
451 if ($this->object->getSelectionLimit()) {
452 $template->setVariable('SELECTION_LIMIT_HINT', sprintf(
453 $this->lng->txt('ass_mc_sel_lim_hint'),
454 $this->object->getSelectionLimit(),
455 $this->object->getAnswerCount()
456 ));
457
458 $template->setVariable('SELECTION_LIMIT_VALUE', $this->object->getSelectionLimit());
459 } else {
460 $template->setVariable('SELECTION_LIMIT_VALUE', 'null');
461 }
462 $template->setVariable("QUESTION_ID", $this->object->getId());
463 $questiontext = $this->object->getQuestion();
464 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, true));
465 $questionoutput = $template->get();
466 if (!$show_question_only) {
467 // get page object output
468 $questionoutput = $this->getILIASPage($questionoutput);
469 }
470 return $questionoutput;
471 }
472
482 public function getTestOutput(
483 $active_id,
484 // hey: prevPassSolutions - will be always available from now on
485 $pass,
486 // hey.
487 $is_postponed = false,
488 $use_post_solutions = false,
489 $show_feedback = false
490 ) {
491 // shuffle output
492 $keys = $this->getChoiceKeys();
493
494 // get the solution of the user for the active pass or from the last pass if allowed
495 $user_solution = array();
496 if ($active_id) {
497 // hey: prevPassSolutions - obsolete due to central check
498 #$solutions = NULL;
499 #include_once "./Modules/Test/classes/class.ilObjTest.php";
500 #if (!ilObjTest::_getUsePreviousAnswers($active_id, true))
501 #{
502 # if (is_null($pass)) $pass = ilObjTest::_getPass($active_id);
503 #}
504 $solutions = $this->object->getTestOutputSolutions($active_id, $pass);
505 // hey.
506 foreach ($solutions as $idx => $solution_value) {
507 // fau: testNav - don't add the dummy entry for 'none of the above' to the user options
508 if ($solution_value["value1"] == 'mc_none_above') {
510 continue;
511 }
512
513 $user_solution[] = $solution_value["value1"];
514 // fau.
515 }
516
517 if (empty($user_solution) && $this->object->getTestPresentationConfig()->isWorkedThrough()) {
519 }
520 }
521 // generate the question output
522 $this->tpl->addJavaScript('Modules/TestQuestionPool/js/ilAssMultipleChoice.js');
523 include_once "./Services/UICore/classes/class.ilTemplate.php";
524 $template = new ilTemplate("tpl.il_as_qpl_mc_mr_output.html", true, true, "Modules/TestQuestionPool");
525 foreach ($keys as $answer_id) {
526 $answer = $this->object->answers[$answer_id];
527 if (strlen($answer->getImage())) {
528 if ($this->object->getThumbSize()) {
529 $template->setCurrentBlock("preview");
530 $template->setVariable("URL_PREVIEW", $this->object->getImagePathWeb() . $answer->getImage());
531 $template->setVariable("TEXT_PREVIEW", $this->lng->txt('preview'));
532 $template->setVariable("IMG_PREVIEW", ilUtil::getImagePath('enlarge.svg'));
533 $template->setVariable("ANSWER_IMAGE_URL", $this->object->getImagePathWeb() . $this->object->getThumbPrefix() . $answer->getImage());
534 list($width, $height, $type, $attr) = getimagesize($this->object->getImagePath() . $answer->getImage());
535 $alt = $answer->getImage();
536 if (strlen($answer->getAnswertext())) {
537 $alt = $answer->getAnswertext();
538 }
539 $alt = preg_replace("/<[^>]*?>/", "", $alt);
540 $template->setVariable("ANSWER_IMAGE_ALT", ilUtil::prepareFormOutput($alt));
541 $template->setVariable("ANSWER_IMAGE_TITLE", ilUtil::prepareFormOutput($alt));
542 $template->parseCurrentBlock();
543 } else {
544 $template->setCurrentBlock("answer_image");
545 $template->setVariable("ANSWER_IMAGE_URL", $this->object->getImagePathWeb() . $answer->getImage());
546 list($width, $height, $type, $attr) = getimagesize($this->object->getImagePath() . $answer->getImage());
547 $alt = $answer->getImage();
548 if (strlen($answer->getAnswertext())) {
549 $alt = $answer->getAnswertext();
550 }
551 $alt = preg_replace("/<[^>]*?>/", "", $alt);
552 $template->setVariable("ATTR", $attr);
553 $template->setVariable("ANSWER_IMAGE_ALT", ilUtil::prepareFormOutput($alt));
554 $template->setVariable("ANSWER_IMAGE_TITLE", ilUtil::prepareFormOutput($alt));
555 $template->parseCurrentBlock();
556 }
557 }
558
559 if ($show_feedback) {
560 $this->populateSpecificFeedbackInline($user_solution, $answer_id, $template);
561 }
562
563 $template->setCurrentBlock("answer_row");
564 $template->setVariable("QID", $this->object->getId());
565 $template->setVariable("ANSWER_ID", $answer_id);
566 $template->setVariable("ANSWER_TEXT", $this->object->prepareTextareaOutput($answer->getAnswertext(), true));
567 foreach ($user_solution as $mc_solution) {
568 if (strcmp($mc_solution, $answer_id) == 0) {
569 $template->setVariable("CHECKED_ANSWER", " checked=\"checked\"");
570 }
571 }
572 $template->parseCurrentBlock();
573 }
574
575 $questiontext = $this->object->getQuestion();
576 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, true));
577 $template->setVariable("QUESTION_ID", $this->object->getId());
578 if ($this->object->getSelectionLimit()) {
579 $template->setVariable('SELECTION_LIMIT_HINT', sprintf(
580 $this->lng->txt('ass_mc_sel_lim_hint'),
581 $this->object->getSelectionLimit(),
582 $this->object->getAnswerCount()
583 ));
584
585 $template->setVariable('SELECTION_LIMIT_VALUE', $this->object->getSelectionLimit());
586 } else {
587 $template->setVariable('SELECTION_LIMIT_VALUE', 'null');
588 }
589 $questionoutput = $template->get();
590 $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput);
591 return $pageoutput;
592 }
593
595
597 {
599 }
600
602 {
603 $this->useEmptySolutionInputChecked = $useEmptySolutionInputChecked;
604 }
605
607 {
608 // hey: prevPassSolutions - use abstracted template to share with other purposes of this kind
609 $this->tpl->addJavaScript('Modules/TestQuestionPool/js/ilAssMultipleChoice.js');
610
611 $tpl = new ilTemplate('tpl.tst_question_additional_behaviour_checkbox.html', true, true, 'Modules/TestQuestionPool');
612
613 // HEY: affects next if (!) /// noneAboveChecked repaired but disabled because the checked input ..
614 if (false) { // .. makes the qstEditController initialize the "edit" instead of the "answered" state
615 if ($this->isUseEmptySolutionInputChecked()) {
616 $tpl->setCurrentBlock('checked');
617 $tpl->touchBlock('checked');
618 $tpl->parseCurrentBlock();
619 }
620 }
621
622 $tpl->setCurrentBlock('checkbox');
623 $tpl->setVariable('TXT_FORCE_FORM_DIFF_LABEL', $this->object->getTestPresentationConfig()->getUseUnchangedAnswerLabel());
624 $tpl->parseCurrentBlock();
625 // hey.
626 return $tpl->get();
627 }
628
630 {
631 $tpl->addJavaScript('Modules/TestQuestionPool/js/ilAssMultipleChoice.js');
632 }
633
639 public function setQuestionTabs()
640 {
641 global $rbacsystem, $ilTabs;
642
643 $ilTabs->clearTargets();
644
645 $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $_GET["q_id"]);
646 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
647 $q_type = $this->object->getQuestionType();
648
649 if (strlen($q_type)) {
650 $classname = $q_type . "GUI";
651 $this->ctrl->setParameterByClass(strtolower($classname), "sel_question_types", $q_type);
652 $this->ctrl->setParameterByClass(strtolower($classname), "q_id", $_GET["q_id"]);
653 }
654
655 if ($_GET["q_id"]) {
656 if ($rbacsystem->checkAccess('write', $_GET["ref_id"])) {
657 // edit page
658 $ilTabs->addTarget(
659 "edit_page",
660 $this->ctrl->getLinkTargetByClass("ilAssQuestionPageGUI", "edit"),
661 array("edit", "insert", "exec_pg"),
662 "",
663 "",
664 $force_active
665 );
666 }
667
668 $this->addTab_QuestionPreview($ilTabs);
669 }
670 $force_active = false;
671 if ($rbacsystem->checkAccess('write', $_GET["ref_id"])) {
672 $url = "";
673 if ($classname) {
674 $url = $this->ctrl->getLinkTargetByClass($classname, "editQuestion");
675 }
676 $force_active = false;
677 // edit question properties
678 $ilTabs->addTarget(
679 "edit_question",
680 $url,
681 array("editQuestion", "save", "saveEdit", "addchoice", "removechoice", "removeimagechoice", "uploadchoice", "originalSyncForm"),
682 $classname,
683 "",
684 $force_active
685 );
686 }
687
688 // add tab for question feedback within common class assQuestionGUI
689 $this->addTab_QuestionFeedback($ilTabs);
690
691 // add tab for question hint within common class assQuestionGUI
692 $this->addTab_QuestionHints($ilTabs);
693
694 // add tab for question's suggested solution within common class assQuestionGUI
695 $this->addTab_SuggestedSolution($ilTabs, $classname);
696
697 // Assessment of questions sub menu entry
698 if ($_GET["q_id"]) {
699 $ilTabs->addTarget(
700 "statistics",
701 $this->ctrl->getLinkTargetByClass($classname, "assessment"),
702 array("assessment"),
703 $classname,
704 ""
705 );
706 }
707
708 $this->addBackTab($ilTabs);
709 }
710
716 public function getChoiceKeys()
717 {
718 $choiceKeys = array_keys($this->object->answers);
719
720 if ($this->object->getShuffle()) {
721 $choiceKeys = $this->object->getShuffler()->shuffle($choiceKeys);
722 }
723
724 return $choiceKeys;
725 }
726
727 public function getSpecificFeedbackOutput($active_id, $pass)
728 {
729 // No return value, this question type supports inline specific feedback.
730 $output = "";
731 return $this->object->prepareTextareaOutput($output, true);
732 }
733
735 {
736 $this->object->setShuffle($_POST["shuffle"]);
737
738 $selectionLimit = (int) $form->getItemByPostVar('selection_limit')->getValue();
739 $this->object->setSelectionLimit($selectionLimit > 0 ? $selectionLimit : null);
740
741 $this->object->setMultilineAnswerSetting($_POST["types"]);
742 if (is_array($_POST['choice']['imagename']) && $_POST["types"] == 1) {
743 $this->object->isSingleline = true;
744 ilUtil::sendInfo($this->lng->txt('info_answer_type_change'), true);
745 } else {
746 $this->object->isSingleline = ($_POST["types"] == 0) ? true : false;
747 }
748 $this->object->setThumbSize((strlen($_POST["thumb_size"])) ? $_POST["thumb_size"] : "");
749 }
750
752 {
753 // Delete all existing answers and create new answers from the form data
754 $this->object->flushAnswers();
755 if ($this->object->isSingleline) {
756 foreach ($_POST['choice']['answer'] as $index => $answertext) {
757 $answertext = ilUtil::secureString($answertext);
758
759 $picturefile = $_POST['choice']['imagename'][$index];
760 $file_org_name = $_FILES['choice']['name']['image'][$index];
761 $file_temp_name = $_FILES['choice']['tmp_name']['image'][$index];
762
763 if (strlen($file_temp_name)) {
764 // check suffix
765 $suffix = strtolower(array_pop(explode(".", $file_org_name)));
766 if (in_array($suffix, array( "jpg", "jpeg", "png", "gif" ))) {
767 // upload image
768 $filename = $this->object->buildHashedImageFilename($file_org_name);
769 if ($this->object->setImageFile($filename, $file_temp_name) == 0) {
770 $picturefile = $filename;
771 }
772 }
773 }
774 $this->object->addAnswer(
775 $answertext,
776 $_POST['choice']['points'][$index],
777 $_POST['choice']['points_unchecked'][$index],
778 $index,
779 $picturefile
780 );
781 }
782 } else {
783 foreach ($_POST['choice']['answer'] as $index => $answer) {
784 $answertext = $answer;
785 $this->object->addAnswer(
786 $answertext,
787 $_POST['choice']['points'][$index],
788 $_POST['choice']['points_unchecked'][$index],
789 $index
790 );
791 }
792 }
793 }
794
796 {
797 // shuffle
798 $shuffle = new ilCheckboxInputGUI($this->lng->txt("shuffle_answers"), "shuffle");
799 $shuffle->setValue(1);
800 $shuffle->setChecked($this->object->getShuffle());
801 $shuffle->setRequired(false);
802 $form->addItem($shuffle);
803
804 require_once 'Services/Form/classes/class.ilNumberInputGUI.php';
805 $selLim = new ilNumberInputGUI($this->lng->txt('ass_mc_sel_lim_setting'), 'selection_limit');
806 $selLim->setInfo($this->lng->txt('ass_mc_sel_lim_setting_desc'));
807 $selLim->setSize(2);
808 $selLim->setRequired(false);
809 $selLim->allowDecimals(false);
810 $selLim->setMinvalueShouldBeGreater(false);
811 $selLim->setMaxvalueShouldBeLess(false);
812 $selLim->setMinValue(1);
813 $selLim->setMaxValue($this->object->getAnswerCount());
814 $selLim->setValue($this->object->getSelectionLimit());
815 $form->addItem($selLim);
816
817 if ($this->object->getId()) {
818 $hidden = new ilHiddenInputGUI("", "ID");
819 $hidden->setValue($this->object->getId());
820 $form->addItem($hidden);
821 }
822
823 $isSingleline = $this->getEditAnswersSingleLine();
824
825 if (!$this->object->getSelfAssessmentEditingMode()) {
826 // Answer types
827 $types = new ilSelectInputGUI($this->lng->txt("answer_types"), "types");
828 $types->setRequired(false);
829 $types->setValue(($isSingleline) ? 0 : 1);
830 $types->setOptions(
831 array(
832 0 => $this->lng->txt('answers_singleline'),
833 1 => $this->lng->txt('answers_multiline'),
834 )
835 );
836 $form->addItem($types);
837 }
838
839 if ($isSingleline) {
840 // thumb size
841 $thumb_size = new ilNumberInputGUI($this->lng->txt("thumb_size"), "thumb_size");
842 $thumb_size->setSuffix($this->lng->txt("thumb_size_unit_pixel"));
843 $thumb_size->setMinValue(20);
844 $thumb_size->setDecimals(0);
845 $thumb_size->setSize(6);
846 $thumb_size->setInfo($this->lng->txt('thumb_size_info'));
847 $thumb_size->setValue($this->object->getThumbSize());
848 $thumb_size->setRequired(false);
849 $form->addItem($thumb_size);
850 return $isSingleline;
851 }
852 return $isSingleline;
853 }
854
856 {
857 // Choices
858 include_once "./Modules/TestQuestionPool/classes/class.ilMultipleChoiceWizardInputGUI.php";
859 $choices = new ilMultipleChoiceWizardInputGUI($this->lng->txt("answers"), "choice");
860 $choices->setRequired(true);
861 $choices->setQuestionObject($this->object);
862 $isSingleline = $this->getEditAnswersSingleLine();
863 $choices->setSingleline($isSingleline);
864 $choices->setAllowMove(false);
865 if ($this->object->getSelfAssessmentEditingMode()) {
866 $choices->setSize(40);
867 }
868 $choices->setMaxLength(800);
869 if ($this->object->getAnswerCount() == 0) {
870 $this->object->addAnswer("", 0, 0, 0);
871 }
872 $choices->setValues($this->object->getAnswers());
873 $form->addItem($choices);
874 }
875
886 {
887 return array();
888 }
889
900 {
901 return array();
902 }
903
912 public function getAggregatedAnswersView($relevant_answers)
913 {
914 return $this->renderAggregateView(
915 $this->aggregateAnswers($relevant_answers, $this->object->getAnswers())
916 )->get();
917 }
918
919 public function aggregateAnswers($relevant_answers_chosen, $answers_defined_on_question)
920 {
921 $aggregate = array();
922 foreach ($answers_defined_on_question as $answer) {
923 $aggregated_info_for_answer = array();
924 $aggregated_info_for_answer['answertext'] = $answer->getAnswerText();
925 $aggregated_info_for_answer['count_checked'] = 0;
926
927 foreach ($relevant_answers_chosen as $relevant_answer) {
928 if ($relevant_answer['value1'] == $answer->getOrder()) {
929 $aggregated_info_for_answer['count_checked']++;
930 }
931 }
932 $aggregated_info_for_answer['count_unchecked'] =
933 ceil(count($relevant_answers_chosen) / count($answers_defined_on_question))
934 - $aggregated_info_for_answer['count_checked'];
935
936 $aggregate[] = $aggregated_info_for_answer;
937 }
938 return $aggregate;
939 }
940
946 public function renderAggregateView($aggregate)
947 {
948 $tpl = new ilTemplate('tpl.il_as_aggregated_answers_table.html', true, true, "Modules/TestQuestionPool");
949
950 $tpl->setCurrentBlock('headercell');
951 $tpl->setVariable('HEADER', $this->lng->txt('tst_answer_aggr_answer_header'));
952 $tpl->parseCurrentBlock();
953
954 $tpl->setCurrentBlock('headercell');
955 $tpl->setVariable('HEADER', $this->lng->txt('tst_answer_aggr_frequency_header'));
956 $tpl->parseCurrentBlock();
957
958 foreach ($aggregate as $line_data) {
959 $tpl->setCurrentBlock('aggregaterow');
960 $tpl->setVariable('OPTION', $line_data['answertext']);
961 $tpl->setVariable('COUNT', $line_data['count_checked']);
962 $tpl->parseCurrentBlock();
963 }
964 return $tpl;
965 }
966
973 private function populateSpecificFeedbackInline($user_solution, $answer_id, $template)
974 {
975 if ($this->object->getSpecificFeedbackSetting() == 2) {
976 foreach ($user_solution as $mc_solution) {
977 if (strcmp($mc_solution, $answer_id) == 0) {
978 $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation($this->object->getId(), $answer_id);
979 if (strlen($fb)) {
980 $template->setCurrentBlock("feedback");
981 $template->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($fb, true));
982 $template->parseCurrentBlock();
983 }
984 }
985 }
986 }
987
988 if ($this->object->getSpecificFeedbackSetting() == 1) {
989 $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation($this->object->getId(), $answer_id);
990 if (strlen($fb)) {
991 $template->setCurrentBlock("feedback");
992 $template->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($fb, true));
993 $template->parseCurrentBlock();
994 }
995 }
996
997 if ($this->object->getSpecificFeedbackSetting() == 3) {
998 $answer = $this->object->getAnswer($answer_id);
999
1000 if ($answer->getPoints() > 0) {
1001 $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation($this->object->getId(), $answer_id);
1002 if (strlen($fb)) {
1003 $template->setCurrentBlock("feedback");
1004 $template->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($fb, true));
1005 $template->parseCurrentBlock();
1006 }
1007 }
1008 }
1009 }
1010
1011 // fau: testNav - new functions setWithNoneAbove() and setIsAnswered()
1012 // moved functionality to ilTestQuestionPresentationConfig
1013 // fau.
1014
1018 protected function buildEditForm()
1019 {
1020 include_once("./Services/Form/classes/class.ilPropertyFormGUI.php");
1021 $form = new ilPropertyFormGUI();
1022 $form->setFormAction($this->ctrl->getFormAction($this));
1023 $form->setTitle($this->outQuestionType());
1024 $form->setTableWidth("100%");
1025 $form->setId("assmultiplechoice");
1026
1027 // title, author, description, question, working time (assessment mode)
1033 return $form;
1034 }
1035}
sprintf('%.4f', $callTime)
$_GET["client_id"]
$_POST["username"]
An exception for terminatinating execution or to throw for unit testing.
Multiple choice question GUI representation.
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...
setUseEmptySolutionInputChecked($useEmptySolutionInputChecked)
addBasicQuestionFormProperties($form)
Add basic question form properties: assessment: title, author, description, question,...
getTestOutput( $active_id, $pass, $is_postponed=false, $use_post_solutions=false, $show_feedback=false)
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)
writeAnswerSpecificPostData(ilPropertyFormGUI $form)
Extracts the answer specific values from $_POST and applies them to the data object.
getPreview($show_question_only=false, $showInlineFeedback=false)
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.
populateAnswerSpecificFormPart(\ilPropertyFormGUI $form)
editQuestion($checkonly=false)
Creates an output of the edit form for the question.
setQuestionTabs()
Sets the ILIAS tabs for this question type.
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.
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...
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.
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
$template
if(!array_key_exists('StateId', $_REQUEST)) $id
if(!is_dir( $entity_dir)) exit("Fatal Error ([A-Za-z0-9]+)\s+" &#(? foreach( $entity_files as $file) $output
Interface ilGuiAnswerScoringAdjustable.
Interface ilGuiQuestionScoringAdjustable.
$index
Definition: metadata.php:60
$errors
Definition: index.php:6
$keys
$type
$url
if(isset($_POST['submit'])) $form