ILIAS  release_8 Revision v8.24
class.assSingleChoiceGUI.php
Go to the documentation of this file.
1<?php
2
19require_once './Modules/Test/classes/inc.AssessmentConstants.php';
20
36{
44 public function __construct($id = -1)
45 {
47 include_once "./Modules/TestQuestionPool/classes/class.assSingleChoice.php";
48 $this->object = new assSingleChoice();
49 if ($id >= 0) {
50 $this->object->loadFromDb($id);
51 }
52 }
53
57 public function hasInlineFeedback(): bool
58 {
59 return $this->object->feedbackOBJ->isSpecificAnswerFeedbackAvailable($this->object->getId());
60 }
61
65 protected function writePostData(bool $always = false): int
66 {
67 $hasErrors = (!$always) ? $this->editQuestion(true) : false;
68 if (!$hasErrors) {
69 require_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
74 return 0;
75 }
76 return 1;
77 }
78
86 protected function getEditAnswersSingleLine($checkonly = false): bool
87 {
88 if ($this->object->getSelfAssessmentEditingMode()) {
89 return $this->object->isSingleline();
90 }
91
92 if ($checkonly) {
93 $types = $_POST['types'] ?? '0';
94 return $types === '0' ? true : false;
95 }
96
97 $lastChange = $this->object->getLastChange();
98 if (empty($lastChange) && !isset($_POST['types'])) {
99 // a new question is edited
100 return $this->object->getMultilineAnswerSetting() ? false : true;
101 } else {
102 // a saved question is edited
103 return $this->object->isSingleline();
104 }
105 }
106
111 public function editQuestion($checkonly = false): bool
112 {
113 $save = $this->isSaveCommand();
114 $this->getQuestionTemplate();
115
116 include_once("./Services/Form/classes/class.ilPropertyFormGUI.php");
117 $form = new ilPropertyFormGUI();
118 $this->editForm = $form;
119
120 $form->setFormAction($this->ctrl->getFormAction($this));
121 $form->setTitle($this->outQuestionType());
122 $is_singleline = $this->getEditAnswersSingleLine($checkonly);
123 if ($is_singleline) {
124 $form->setMultipart(true);
125 } else {
126 $form->setMultipart(false);
127 }
128 $form->setTableWidth("100%");
129 $form->setId("asssinglechoice");
130
131 $this->addBasicQuestionFormProperties($form);
132 $this->populateQuestionSpecificFormPart($form, $is_singleline);
133 $this->populateAnswerSpecificFormPart($form, $is_singleline);
134
135
136 $this->populateTaxonomyFormSection($form);
137
138 $this->addQuestionFormCommandButtons($form);
139
140 $errors = false;
141
142 if ($save) {
143 foreach ($this->request->getParsedBody() as $key => $value) {
144 $item = $form->getItemByPostVar($key);
145 if ($item !== null) {
146 switch (get_class($item)) {
147 case 'ilDurationInputGUI':
148 $item->setHours($value['hh']);
149 $item->setMinutes($value['mm']);
150 $item->setSeconds($value['ss']);
151 break;
152 default:
153 $item->setValue($value);
154 }
155 }
156 }
157
158 $errors = !$form->checkInput();
159 foreach ($this->request->getParsedBody() as $key => $value) {
160 $item = $form->getItemByPostVar($key);
161 if ($item !== null) {
162 switch (get_class($item)) {
163 case 'ilDurationInputGUI':
164 $item->setHours($value['hh']);
165 $item->setMinutes($value['mm']);
166 $item->setSeconds($value['ss']);
167 break;
168 default:
169 $item->setValue($value);
170 }
171 }
172 } // again, because checkInput now performs the whole stripSlashes handling and we need this if we don't want to have duplication of backslashes
173
174 if ($errors) {
175 $checkonly = false;
176 }
177 }
178
179 if (!$checkonly) {
180 $this->tpl->setVariable("QUESTION_DATA", $form->getHTML());
181 }
182 return $errors;
183 }
184
188 public function uploadchoice(): void
189 {
190 $this->writePostData(true);
191 $position = key($_POST['cmd']['uploadchoice']);
192 $this->editQuestion();
193 }
194
198 public function removeimagechoice(): void
199 {
200 $this->writePostData(true);
201 $position = key($_POST['cmd']['removeimagechoice']);
202 $filename = $_POST['choice']['imagename'][$position];
203 $this->object->removeAnswerImage($position);
204 $this->editQuestion();
205 }
206
210 public function addchoice(): void
211 {
212 $this->writePostData(true);
213 $position = key($_POST['cmd']['addchoice']);
214 $this->object->addAnswer("", 0, $position + 1);
215 $this->editQuestion();
216 }
217
221 public function removechoice(): void
222 {
223 $this->writePostData(true);
224 $position = key($_POST['cmd']['removechoice']);
225 $this->object->deleteAnswer($position);
226 $this->editQuestion();
227 }
228
241 public function getSolutionOutput(
242 $active_id,
243 $pass = null,
244 $graphicalOutput = false,
245 $result_output = false,
246 $show_question_only = true,
247 $show_feedback = false,
248 $show_correct_solution = false,
249 $show_manual_scoring = false,
250 $show_question_text = true
251 ): string {
252 // shuffle output
253 $keys = $this->getChoiceKeys();
254
255 // get the solution of the user for the active pass or from the last pass if allowed
256 $user_solution = "";
257 if (($active_id > 0) && (!$show_correct_solution)) {
258 $solutions = $this->object->getSolutionValues($active_id, $pass);
259 foreach ($solutions as $idx => $solution_value) {
260 $user_solution = $solution_value["value1"];
261 }
262 } else {
263 $found_index = -1;
264 $max_points = 0;
265 foreach ($this->object->answers as $index => $answer) {
266 if ($answer->getPoints() > $max_points) {
267 $max_points = $answer->getPoints();
268 $found_index = $index;
269 }
270 }
271 $user_solution = $found_index;
272 }
273 // generate the question output
274 include_once "./Services/UICore/classes/class.ilTemplate.php";
275 $template = new ilTemplate("tpl.il_as_qpl_mc_sr_output_solution.html", true, true, "Modules/TestQuestionPool");
276 $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html", true, true, "Modules/TestQuestionPool");
277 foreach ($keys as $answer_id) {
278 $answer = $this->object->answers[$answer_id];
279 if (($active_id > 0) && (!$show_correct_solution)) {
280 if ($graphicalOutput) {
281 $correctness_icon = $this->generateCorrectnessIconsForCorrectness(self::CORRECTNESS_NOT_OK);
282
283 if (strcmp($user_solution, $answer_id) == 0) {
284 if ($answer->getPoints() == $this->object->getMaximumPoints()) {
285 $correctness_icon = $this->generateCorrectnessIconsForCorrectness(self::CORRECTNESS_OK);
286 } elseif ($answer->getPoints() > 0) {
287 $correctness_icon = $this->generateCorrectnessIconsForCorrectness(self::CORRECTNESS_MOSTLY_OK);
288 }
289 }
290 $template->setCurrentBlock("icon_ok");
291 $template->setVariable("ICON_OK", $correctness_icon);
292 $template->parseCurrentBlock();
293 }
294 }
295 if (strlen($answer->getImage())) {
296 $template->setCurrentBlock("answer_image");
297 if ($this->object->getThumbSize()) {
298 $template->setVariable("ANSWER_IMAGE_URL", $this->object->getImagePathWeb() . $this->object->getThumbPrefix() . $answer->getImage());
299 } else {
300 $template->setVariable("ANSWER_IMAGE_URL", $this->object->getImagePathWeb() . $answer->getImage());
301 }
302 $alt = $answer->getImage();
303 if (strlen($answer->getAnswertext())) {
304 $alt = $answer->getAnswertext();
305 }
306 $alt = preg_replace("/<[^>]*?>/", "", $alt);
307 $template->setVariable("ANSWER_IMAGE_ALT", ilLegacyFormElementsUtil::prepareFormOutput($alt));
308 $template->setVariable("ANSWER_IMAGE_TITLE", ilLegacyFormElementsUtil::prepareFormOutput($alt));
309 $template->parseCurrentBlock();
310 }
311 if ($show_feedback) {
312 $this->populateInlineFeedback($template, $answer_id, $user_solution);
313 }
314 $template->setCurrentBlock("answer_row");
315 $template->setVariable("ANSWER_TEXT", $this->object->prepareTextareaOutput($answer->getAnswertext(), true));
316
318 if (strcmp($user_solution, $answer_id) == 0) {
319 $template->setVariable("SOLUTION_IMAGE", ilUtil::getHtmlPath(ilUtil::getImagePath("radiobutton_checked.png")));
320 $template->setVariable("SOLUTION_ALT", $this->lng->txt("checked"));
321 } else {
322 $template->setVariable("SOLUTION_IMAGE", ilUtil::getHtmlPath(ilUtil::getImagePath("radiobutton_unchecked.png")));
323 $template->setVariable("SOLUTION_ALT", $this->lng->txt("unchecked"));
324 }
325 } else {
326 $template->setVariable('QID', $this->object->getId());
327 $template->setVariable('SUFFIX', $show_correct_solution ? 'bestsolution' : 'usersolution');
328 $template->setVariable('SOLUTION_VALUE', $answer_id);
329 if (strcmp($user_solution, $answer_id) == 0) {
330 $template->setVariable('SOLUTION_CHECKED', 'checked');
331 }
332 }
333
334 if ($result_output) {
335 $points = $this->object->answers[$answer_id]->getPoints();
336 $resulttext = ($points == 1) ? "(%s " . $this->lng->txt("point") . ")" : "(%s " . $this->lng->txt("points") . ")";
337 $template->setVariable("RESULT_OUTPUT", sprintf($resulttext, $points));
338 }
339 $template->parseCurrentBlock();
340 }
341 $questiontext = $this->object->getQuestionForHTMLOutput();
342 if ($show_feedback && $this->hasInlineFeedback()) {
343 $questiontext .= $this->buildFocusAnchorHtml();
344 }
345 if ($show_question_text == true) {
346 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, true));
347 }
348 $questionoutput = $template->get();
349 $feedback = ($show_feedback && !$this->isTestPresentationContext()) ? $this->getGenericFeedbackOutput((int) $active_id, $pass) : "";
350 if (strlen($feedback)) {
351 $cssClass = (
352 $this->hasCorrectSolution($active_id, $pass) ?
354 );
355
356 $solutiontemplate->setVariable("ILC_FB_CSS_CLASS", $cssClass);
357 $solutiontemplate->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($feedback, true));
358 }
359 $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
360
361 $solutionoutput = $solutiontemplate->get();
362
363 if (!$show_question_only) {
364 // get page object output
365 $solutionoutput = $this->getILIASPage($solutionoutput);
366 }
367 return $solutionoutput;
368 }
369
370 public function getPreview($show_question_only = false, $showInlineFeedback = false): string
371 {
372 $keys = $this->getChoiceKeys();
373
374 // generate the question output
375 include_once "./Services/UICore/classes/class.ilTemplate.php";
376 $template = new ilTemplate("tpl.il_as_qpl_mc_sr_output.html", true, true, "Modules/TestQuestionPool");
377 foreach ($keys as $answer_id) {
378 $answer = $this->object->answers[$answer_id];
379 if (strlen($answer->getImage())) {
380 if ($this->object->getThumbSize()) {
381 $template->setCurrentBlock("preview");
382 $template->setVariable("URL_PREVIEW", $this->object->getImagePathWeb() . $answer->getImage());
383 $template->setVariable("TEXT_PREVIEW", $this->lng->txt('preview'));
384 $template->setVariable("IMG_PREVIEW", ilUtil::getImagePath('enlarge.svg'));
385 $template->setVariable("ANSWER_IMAGE_URL", $this->object->getImagePathWeb() . $this->object->getThumbPrefix() . $answer->getImage());
386 list($width, $height, $type, $attr) = getimagesize($this->object->getImagePath() . $answer->getImage());
387 $alt = $answer->getImage();
388 if (strlen($answer->getAnswertext())) {
389 $alt = $answer->getAnswertext();
390 }
391 $alt = preg_replace("/<[^>]*?>/", "", $alt);
392 $template->setVariable("ANSWER_IMAGE_ALT", ilLegacyFormElementsUtil::prepareFormOutput($alt));
393 $template->setVariable("ANSWER_IMAGE_TITLE", ilLegacyFormElementsUtil::prepareFormOutput($alt));
394 $template->parseCurrentBlock();
395 } else {
396 $template->setCurrentBlock("answer_image");
397 $template->setVariable("ANSWER_IMAGE_URL", $this->object->getImagePathWeb() . $answer->getImage());
398 list($width, $height, $type, $attr) = getimagesize($this->object->getImagePath() . $answer->getImage());
399 $alt = $answer->getImage();
400 if (strlen($answer->getAnswertext())) {
401 $alt = $answer->getAnswertext();
402 }
403 $alt = preg_replace("/<[^>]*?>/", "", $alt);
404 $template->setVariable("ATTR", $attr);
405 $template->setVariable("ANSWER_IMAGE_ALT", ilLegacyFormElementsUtil::prepareFormOutput($alt));
406 $template->setVariable("ANSWER_IMAGE_TITLE", ilLegacyFormElementsUtil::prepareFormOutput($alt));
407 $template->parseCurrentBlock();
408 }
409 }
410 if ($showInlineFeedback && is_object($this->getPreviewSession())) {
411 $this->populateInlineFeedback($template, $answer_id, $this->getPreviewSession()->getParticipantsSolution());
412 }
413 $template->setCurrentBlock("answer_row");
414 $template->setVariable("QID", $this->object->getId() . 'ID');
415 $template->setVariable("ANSWER_ID", $answer_id);
416 $template->setVariable("ANSWER_TEXT", $this->object->prepareTextareaOutput($answer->getAnswertext(), true));
417
418 if (is_object($this->getPreviewSession())) {
419 $user_solution = $this->getPreviewSession()->getParticipantsSolution();
420 if (strcmp($user_solution, $answer_id) == 0) {
421 $template->setVariable("CHECKED_ANSWER", " checked=\"checked\"");
422 }
423 }
424
425 $template->parseCurrentBlock();
426 }
427 $questiontext = $this->object->getQuestionForHTMLOutput();
428 if ($showInlineFeedback && $this->hasInlineFeedback()) {
429 $questiontext .= $this->buildFocusAnchorHtml();
430 }
431 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, true));
432 $questionoutput = $template->get();
433 if (!$show_question_only) {
434 // get page object output
435 $questionoutput = $this->getILIASPage($questionoutput);
436 }
437 return $questionoutput;
438 }
439
440 // hey: prevPassSolutions - pass will be always available from now on
441 public function getTestOutput($active_id, $pass, $is_postponed = false, $use_post_solutions = false, $show_feedback = false): string
442 // hey.
443 {
444 $keys = $this->getChoiceKeys();
445
446 // get the solution of the user for the active pass or from the last pass if allowed
447 $user_solution = "";
448 if ($active_id) {
449 $solutions = $this->object->getTestOutputSolutions($active_id, $pass);
450 foreach ($solutions as $idx => $solution_value) {
451 $user_solution = $solution_value["value1"];
452 }
453 }
454
455 // generate the question output
456 include_once "./Services/UICore/classes/class.ilTemplate.php";
457 $template = new ilTemplate("tpl.il_as_qpl_mc_sr_output.html", true, true, "Modules/TestQuestionPool");
458 foreach ($keys as $answer_id) {
459 $answer = $this->object->answers[$answer_id];
460 if (strlen($answer->getImage())) {
461 if ($this->object->getThumbSize()) {
462 $template->setCurrentBlock("preview");
463 $template->setVariable("URL_PREVIEW", $this->object->getImagePathWeb() . $answer->getImage());
464 $template->setVariable("TEXT_PREVIEW", $this->lng->txt('preview'));
465 $template->setVariable("IMG_PREVIEW", ilUtil::getImagePath('enlarge.svg'));
466 $template->setVariable("ANSWER_IMAGE_URL", $this->object->getImagePathWeb() . $this->object->getThumbPrefix() . $answer->getImage());
467 list($width, $height, $type, $attr) = getimagesize($this->object->getImagePath() . $answer->getImage());
468 $alt = $answer->getImage();
469 if (strlen($answer->getAnswertext())) {
470 $alt = $answer->getAnswertext();
471 }
472 $alt = preg_replace("/<[^>]*?>/", "", $alt);
473 $template->setVariable("ANSWER_IMAGE_ALT", ilLegacyFormElementsUtil::prepareFormOutput($alt));
474 $template->setVariable("ANSWER_IMAGE_TITLE", ilLegacyFormElementsUtil::prepareFormOutput($alt));
475 $template->parseCurrentBlock();
476 } else {
477 $template->setCurrentBlock("answer_image");
478 $template->setVariable("ANSWER_IMAGE_URL", $this->object->getImagePathWeb() . $answer->getImage());
479 list($width, $height, $type, $attr) = getimagesize($this->object->getImagePath() . $answer->getImage());
480 $alt = $answer->getImage();
481 if (strlen($answer->getAnswertext())) {
482 $alt = $answer->getAnswertext();
483 }
484 $alt = preg_replace("/<[^>]*?>/", "", $alt);
485 $template->setVariable("ATTR", $attr);
486 $template->setVariable("ANSWER_IMAGE_ALT", ilLegacyFormElementsUtil::prepareFormOutput($alt));
487 $template->setVariable("ANSWER_IMAGE_TITLE", ilLegacyFormElementsUtil::prepareFormOutput($alt));
488 $template->parseCurrentBlock();
489 }
490 }
491 if ($show_feedback) {
492 $feedbackOutputRequired = false;
493
494 switch ($this->object->getSpecificFeedbackSetting()) {
495 case 1:
496 $feedbackOutputRequired = true;
497 break;
498
499 case 2:
500 if (strcmp($user_solution, $answer_id) == 0) {
501 $feedbackOutputRequired = true;
502 }
503 break;
504
505 case 3:
506 if ($this->object->getAnswer($answer_id)->getPoints() > 0) {
507 $feedbackOutputRequired = true;
508 }
509 break;
510 }
511
512 if ($feedbackOutputRequired) {
513 $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
514 $this->object->getId(),
515 0,
516 $answer_id
517 );
518 if (strlen($fb)) {
519 $template->setCurrentBlock("feedback");
520 $template->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($fb, true));
521 $template->parseCurrentBlock();
522 }
523 }
524 }
525 $template->setCurrentBlock("answer_row");
526 $template->setVariable("ANSWER_ID", $answer_id);
527 $template->setVariable("ANSWER_TEXT", $this->object->prepareTextareaOutput($answer->getAnswertext(), true));
528 if (strcmp($user_solution, $answer_id) == 0) {
529 $template->setVariable("CHECKED_ANSWER", " checked=\"checked\"");
530 }
531 $template->parseCurrentBlock();
532 }
533 $template->setVariable("QUESTIONTEXT", $this->object->getQuestionForHTMLOutput());
534 $questionoutput = $template->get();
535 $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput, $show_feedback);
536 return $pageoutput;
537 }
538
539 /*
540 * Create the key index numbers for the array of choices
541 *
542 * @return array
543 */
544 public function getChoiceKeys()
545 {
546 $choiceKeys = array_keys($this->object->answers);
547
548 if ($this->object->getShuffle()) {
549 $choiceKeys = $this->object->getShuffler()->transform($choiceKeys);
550 }
551
552 return $choiceKeys;
553 }
554
555 public function getSpecificFeedbackOutput(array $userSolution): string
556 {
557 // No return value, this question type supports inline specific feedback.
558 $output = "";
559 return $this->object->prepareTextareaOutput($output, true);
560 }
561
563 {
564 $types = $_POST["types"] ?? '0';
565
566 $this->object->setShuffle($_POST["shuffle"] ?? '0');
567 $this->object->setMultilineAnswerSetting($types);
568
569 if (isset($_POST['choice']) && isset($_POST['choice']['imagename']) && is_array($_POST['choice']['imagename']) && $types === '1') {
570 $this->object->setIsSingleline(true);
571 $this->tpl->setOnScreenMessage('info', $this->lng->txt('info_answer_type_change'), true);
572 } else {
573 $this->object->setIsSingleline($types === '0' ? true : false);
574 }
575 if (isset($_POST["thumb_size"])) {
576 $this->object->setThumbSize((int) $_POST["thumb_size"]);
577 }
578 }
579
580 public function populateQuestionSpecificFormPart(\ilPropertyFormGUI $form, bool $is_singleline = false): ilPropertyFormGUI
581 {
582 // shuffle
583 $shuffle = new ilCheckboxInputGUI($this->lng->txt("shuffle_answers"), "shuffle");
584 $shuffle->setValue(1);
585 $shuffle->setChecked($this->object->getShuffle());
586 $shuffle->setRequired(false);
587 $form->addItem($shuffle);
588
589 if ($this->object->getId()) {
590 $hidden = new ilHiddenInputGUI("", "ID");
591 $hidden->setValue($this->object->getId());
592 $form->addItem($hidden);
593 }
594
595 if (!$this->object->getSelfAssessmentEditingMode()) {
596 // Answer types
597 $types = new ilSelectInputGUI($this->lng->txt("answer_types"), "types");
598 $types->setRequired(false);
599 $types->setValue(($is_singleline) ? 0 : 1);
600 $types->setOptions(
601 array(
602 0 => $this->lng->txt('answers_singleline'),
603 1 => $this->lng->txt('answers_multiline'),
604 )
605 );
606 $form->addItem($types);
607 }
608
609 if ($is_singleline) {
610 // thumb size
611 $thumb_size = new ilNumberInputGUI($this->lng->txt("thumb_size"), "thumb_size");
612 $thumb_size->setSuffix($this->lng->txt("thumb_size_unit_pixel"));
613 $thumb_size->setMinValue($this->object->getMinimumThumbSize());
614 $thumb_size->setMaxValue($this->object->getMaximumThumbSize());
615 $thumb_size->setDecimals(0);
616 $thumb_size->setSize(6);
617 $thumb_size->setInfo($this->lng->txt('thumb_size_info'));
618 $thumb_size->setValue($this->object->getThumbSize());
619 $thumb_size->setRequired(true);
620 } else {
621 $thumb_size = new ilHiddenInputGUI('thumb_size');
622 $thumb_size->setValue($this->object->getThumbSize());
623 }
624 $form->addItem($thumb_size);
625
626 return $form;
627 }
628
639 {
640 return array();
641 }
642
644 {
645 // Delete all existing answers and create new answers from the form data
646 $this->object->flushAnswers();
647 $choice = $this->cleanupAnswerText($_POST['choice'], $this->object->isSingleline() === false);
648 if ($this->object->isSingleline()) {
649 foreach ($choice['answer'] as $index => $answertext) {
650 $answertext = htmlentities($answertext);
651 $picturefile = $choice['imagename'][$index] ?? '';
652 $file_org_name = $_FILES['choice']['name']['image'][$index] ?? '';
653 $file_temp_name = $_FILES['choice']['tmp_name']['image'][$index] ?? '';
654
655 if ($file_temp_name !== '') {
656 // check suffix
657 $file_name_parts = explode(".", $file_org_name);
658 $suffix = strtolower(array_pop($file_name_parts));
659 if (in_array($suffix, array("jpg", "jpeg", "png", "gif"))) {
660 // upload image
661 $filename = $this->object->buildHashedImageFilename($file_org_name);
662 if ($this->object->setImageFile($filename, $file_temp_name) == 0) {
663 $picturefile = $filename;
664 }
665 }
666 }
667 $points = (float) str_replace(',', '.', $choice['points'][$index]);
668 $this->object->addAnswer(
669 $answertext,
670 $points,
671 $index,
672 $picturefile,
673 $choice['answer_id'][$index]
674 );
675 }
676 } else {
677 foreach ($choice['answer'] as $index => $answer) {
678 $answertext = $answer;
679 $this->object->addAnswer(
680 $answertext,
681 $choice['points'][$index],
682 $index,
683 '',
684 $choice['answer_id'][$index]
685 );
686 }
687 }
688 }
689
690 public function populateAnswerSpecificFormPart(\ilPropertyFormGUI $form, bool $is_singleline = false): ilPropertyFormGUI
691 {
692 $choices = new ilSingleChoiceWizardInputGUI($this->lng->txt("answers"), "choice");
693 $choices->setRequired(true);
694 $choices->setQuestionObject($this->object);
695 $choices->setSingleline($is_singleline);
696 $choices->setAllowMove(false);
697 if ($this->object->getSelfAssessmentEditingMode()) {
698 $choices->setSize(40);
699 }
700 if ($this->object->getAnswerCount() == 0) {
701 $this->object->addAnswer("", 0, 0);
702 }
703 $choices->setValues(array_map(
704 function (ASS_AnswerBinaryStateImage $value) {
705 $value->setAnswerText(html_entity_decode($value->getAnswerText()));
706 return $value;
707 },
708 $this->object->getAnswers()
709 ));
710 $form->addItem($choices);
711 return $form;
712 }
713
724 {
725 return array();
726 }
727
734 public function getAggregatedAnswersView(array $relevant_answers): string
735 {
736 return $this->renderAggregateView(
737 $this->aggregateAnswers($relevant_answers, $this->object->getAnswers())
738 )->get();
739 }
740
741 public function aggregateAnswers($relevant_answers_chosen, $answers_defined_on_question): array
742 {
743 $aggregate = array();
744 foreach ($answers_defined_on_question as $answer) {
745 $aggregated_info_for_answer = array();
746 $aggregated_info_for_answer['answertext'] = $answer->getAnswerText();
747 $aggregated_info_for_answer['count_checked'] = 0;
748
749 foreach ($relevant_answers_chosen as $relevant_answer) {
750 if ($relevant_answer['value1'] == $answer->getOrder()) {
751 $aggregated_info_for_answer['count_checked']++;
752 }
753 }
754 $aggregated_info_for_answer['count_unchecked'] =
755 ceil(count($relevant_answers_chosen) / count($answers_defined_on_question))
756 - $aggregated_info_for_answer['count_checked'];
757
758 $aggregate[] = $aggregated_info_for_answer;
759 }
760 return $aggregate;
761 }
762
768 public function renderAggregateView($aggregate): ilTemplate
769 {
770 $tpl = new ilTemplate('tpl.il_as_aggregated_answers_table.html', true, true, "Modules/TestQuestionPool");
771
772 $tpl->setCurrentBlock('headercell');
773 $tpl->setVariable('HEADER', $this->lng->txt('tst_answer_aggr_answer_header'));
774 $tpl->parseCurrentBlock();
775
776 $tpl->setCurrentBlock('headercell');
777 $tpl->setVariable('HEADER', $this->lng->txt('tst_answer_aggr_frequency_header'));
778 $tpl->parseCurrentBlock();
779
780 foreach ($aggregate as $line_data) {
781 $tpl->setCurrentBlock('aggregaterow');
782 $tpl->setVariable('OPTION', $line_data['answertext']);
783 $tpl->setVariable('COUNT', $line_data['count_checked']);
784 $tpl->parseCurrentBlock();
785 }
786 return $tpl;
787 }
788
789 private function populateInlineFeedback($template, $answer_id, $user_solution): void
790 {
791 $feedbackOutputRequired = false;
792
793 switch ($this->object->getSpecificFeedbackSetting()) {
794 case 1:
795 $feedbackOutputRequired = true;
796 break;
797
798 case 2:
799 if (strcmp($user_solution, $answer_id) == 0) {
800 $feedbackOutputRequired = true;
801 }
802 break;
803
804 case 3:
805 if ($this->object->getAnswer($answer_id)->getPoints() > 0) {
806 $feedbackOutputRequired = true;
807 }
808 break;
809 }
810
811 if ($feedbackOutputRequired) {
812 $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation($this->object->getId(), 0, $answer_id);
813 if (strlen($fb)) {
814 $template->setCurrentBlock("feedback");
815 $template->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($fb, true));
816 $template->parseCurrentBlock();
817 }
818 }
819 }
820
821 public function getAnswersFrequency($relevantAnswers, $questionIndex): array
822 {
823 $agg = $this->aggregateAnswers($relevantAnswers, $this->object->getAnswers());
824
825 $answers = array();
826
827 foreach ($agg as $ans) {
828 $answers[] = array(
829 'answer' => $ans['answertext'],
830 'frequency' => $ans['count_checked']
831 );
832 }
833
834 return $answers;
835 }
836
838 {
839 require_once 'Modules/TestQuestionPool/classes/forms/class.ilAssSingleChoiceCorrectionsInputGUI.php';
840 $choices = new ilAssSingleChoiceCorrectionsInputGUI($this->lng->txt("answers"), "choice");
841 $choices->setRequired(true);
842 $choices->setQuestionObject($this->object);
843 $choices->setValues($this->object->getAnswers());
844 $form->addItem($choices);
845 }
846
851 {
852 $input = $form->getItemByPostVar('choice');
853 $values = $input->getValues();
854
855 foreach ($this->object->getAnswers() as $index => $answer) {
856 /* @var ASS_AnswerMultipleResponseImage $answer */
857 $points = (float) str_replace(',', '.', $values[$index]->getPoints());
858 $answer->setPoints($points);
859 }
860 }
861}
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
$filename
Definition: buildRTE.php:78
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
return true
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
populateTaxonomyFormSection(ilPropertyFormGUI $form)
getILIASPage(string $html="")
Returns the ILIAS Page around a question.
addBasicQuestionFormProperties(ilPropertyFormGUI $form)
getGenericFeedbackOutput(int $active_id, ?int $pass)
addQuestionFormCommandButtons(ilPropertyFormGUI $form)
hasCorrectSolution($activeId, $passIndex)
generateCorrectnessIconsForCorrectness(int $correctness)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
removeimagechoice()
Remove an image.
writeAnswerSpecificPostData(ilPropertyFormGUI $form)
Extracts the answer specific values from $_POST and applies them to the data object.
populateAnswerSpecificFormPart(\ilPropertyFormGUI $form, bool $is_singleline=false)
populateCorrectionsFormProperties(ilPropertyFormGUI $form)
getEditAnswersSingleLine($checkonly=false)
Get the single/multiline editing of answers.
populateInlineFeedback($template, $answer_id, $user_solution)
writePostData(bool $always=false)
{Evaluates a posted edit form and writes the form data in the question object.integer A positive valu...
getAfterParticipationSuppressionAnswerPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
populateQuestionSpecificFormPart(\ilPropertyFormGUI $form, bool $is_singleline=false)
writeQuestionSpecificPostData(ilPropertyFormGUI $form)
Extracts the question specific values from $_POST and applies them to the data object.
addchoice()
Add a new answer.
removechoice()
Remove an answer.
getAfterParticipationSuppressionQuestionPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
__construct($id=-1)
assSingleChoiceGUI constructor
getPreview($show_question_only=false, $showInlineFeedback=false)
getSpecificFeedbackOutput(array $userSolution)
Returns the answer specific feedback for the question.
aggregateAnswers($relevant_answers_chosen, $answers_defined_on_question)
editQuestion($checkonly=false)
Creates an output of the edit form for the question.
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.
getTestOutput($active_id, $pass, $is_postponed=false, $use_post_solutions=false, $show_feedback=false)
saveCorrectionsFormProperties(ilPropertyFormGUI $form)
getAggregatedAnswersView(array $relevant_answers)
Returns an html string containing a question specific representation of the answers so far given in t...
getAnswersFrequency($relevantAnswers, $questionIndex)
uploadchoice()
Upload an image.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This class represents a checkbox property in a property form.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static prepareFormOutput($a_str, bool $a_strip=false)
This class represents a number property in a property form.
This class represents a property form user interface.
getItemByPostVar(string $a_post_var)
This class represents a selection list property in a property form.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
special template class to simplify handling of ITX/PEAR
static getHtmlPath(string $relative_path)
get url of path
static getImagePath(string $img, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
$errors
Definition: imgupload.php:65
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
if($DIC->http() ->request() ->getMethod()=="GET" &&isset($DIC->http() ->request() ->getQueryParams()['tex'])) $tpl
Definition: latex.php:41
$index
Definition: metadata.php:145
$keys
Definition: metadata.php:204
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
string $key
Consumer key/client ID value.
Definition: System.php:193
$type