ILIAS  release_8 Revision v8.24
class.assKprimChoiceGUI.php
Go to the documentation of this file.
1<?php
2
19require_once 'Modules/TestQuestionPool/classes/class.assQuestionGUI.php';
20require_once 'Modules/TestQuestionPool/interfaces/interface.ilGuiQuestionScoringAdjustable.php';
21require_once 'Modules/TestQuestionPool/interfaces/interface.ilGuiAnswerScoringAdjustable.php';
22
32{
36 public function __construct($qId = -1)
37 {
39
40 require_once 'Modules/TestQuestionPool/classes/class.assKprimChoice.php';
41 $this->object = new assKprimChoice();
42
43 if ($qId > 0) {
44 $this->object->loadFromDb($qId);
45 }
46 }
47
51 public function hasInlineFeedback(): bool
52 {
53 return $this->object->feedbackOBJ->isSpecificAnswerFeedbackAvailable($this->object->getId());
54 }
55
56 protected function getAdditionalEditQuestionCommands(): array
57 {
58 return array('uploadImage', 'removeImage');
59 }
60
61 protected function editQuestion(ilPropertyFormGUI $form = null): void
62 {
63 if ($form === null) {
64 $form = $this->buildEditForm();
65 }
66
67 $this->getQuestionTemplate();
68
69 $this->tpl->setVariable("QUESTION_DATA", $this->ctrl->getHTML($form));
70 }
71
72 protected function uploadImage(): void
73 {
74 $result = $this->writePostData(true);
75
76 if ($result == 0) {
77 $this->object->saveToDb();
78 $this->editQuestion();
79 }
80 }
81
82 public function removeImage(): void
83 {
84 $position = key($_POST['cmd']['removeImage']);
85 $this->object->removeAnswerImage($position);
86
87 $this->object->saveToDb();
88 $this->editQuestion();
89 }
90
91 public function downkprim_answers(): void
92 {
93 if (isset($_POST['cmd'][__FUNCTION__]) && count($_POST['cmd'][__FUNCTION__])) {
94 $this->object->moveAnswerDown(key($_POST['cmd'][__FUNCTION__]));
95 $this->object->saveToDb();
96 }
97
98 $this->editQuestion();
99 }
100
101 public function upkprim_answers(): void
102 {
103 if (isset($_POST['cmd'][__FUNCTION__]) && count($_POST['cmd'][__FUNCTION__])) {
104 $this->object->moveAnswerUp(key($_POST['cmd'][__FUNCTION__]));
105 $this->object->saveToDb();
106 }
107
108 $this->editQuestion();
109 }
110
114 protected function writePostData(bool $always = false): int
115 {
116 $form = $this->buildEditForm();
117 $form->setValuesByPost();
118
119 if ($always) {
120 $answersInput = $form->getItemByPostVar('kprim_answers');
121 $answersInput->setIgnoreMissingUploadsEnabled(true);
122
123 if (!$answersInput->checkUploads($_POST[$answersInput->getPostVar()])) {
124 $this->tpl->setOnScreenMessage('failure', $this->lng->txt("form_input_not_valid"));
125 $this->editQuestion($form);
126 return 1;
127 }
128
129 $answersInput->collectValidFiles();
130 } elseif (!$form->checkInput()) {
131 $this->editQuestion($form);
132 return 1;
133 }
134
136
137 $this->writeQuestionSpecificPostData($form);
138 $this->writeAnswerSpecificPostData($form);
139
141
142 return 0;
143 }
144
148 protected function buildEditForm(): ilPropertyFormGUI
149 {
150 $form = $this->buildBasicEditFormObject();
151
152 $this->addQuestionFormCommandButtons($form);
153
154 $this->addBasicQuestionFormProperties($form);
155
157 $this->populateAnswerSpecificFormPart($form);
158
159 $this->populateTaxonomyFormSection($form);
160
161 return $form;
162 }
163
169 {
170 // shuffle answers
171 $shuffleAnswers = new ilCheckboxInputGUI($this->lng->txt("shuffle_answers"), "shuffle_answers_enabled");
172 $shuffleAnswers->setChecked($this->object->isShuffleAnswersEnabled());
173 $form->addItem($shuffleAnswers);
174
175 if (!$this->object->getSelfAssessmentEditingMode()) {
176 // answer mode (single-/multi-line)
177 $answerType = new ilSelectInputGUI($this->lng->txt('answer_types'), 'answer_type');
178 $answerType->setOptions($this->object->getAnswerTypeSelectOptions($this->lng));
179 $answerType->setValue($this->object->getAnswerType());
180 $form->addItem($answerType);
181 }
182
183 if (!$this->object->getSelfAssessmentEditingMode() && $this->object->isSingleLineAnswerType($this->object->getAnswerType())) {
184 // thumb size
185 $thumb_size = new ilNumberInputGUI($this->lng->txt('thumb_size'), 'thumb_size');
186 $thumb_size->setSuffix($this->lng->txt('thumb_size_unit_pixel'));
187 $thumb_size->setInfo($this->lng->txt('thumb_size_info'));
188 $thumb_size->setDecimals(false);
189 $thumb_size->setMinValue($this->object->getMinimumThumbSize());
190 $thumb_size->setMaxValue($this->object->getMaximumThumbSize());
191 $thumb_size->setSize(6);
192 $thumb_size->setValue($this->object->getThumbSize());
193 } else {
194 $thumb_size = new ilHiddenInputGUI('thumb_size');
195 $thumb_size->setValue($this->object->getThumbSize());
196 }
197 $form->addItem($thumb_size);
198
199 // option label
200 $optionLabel = new ilRadioGroupInputGUI($this->lng->txt('option_label'), 'option_label');
201 $optionLabel->setInfo($this->lng->txt('option_label_info'));
202 $optionLabel->setRequired(true);
203 $optionLabel->setValue($this->object->getOptionLabel());
204 foreach ($this->object->getValidOptionLabelsTranslated($this->lng) as $labelValue => $labelText) {
205 $option = new ilRadioOption($labelText, $labelValue);
206 $optionLabel->addOption($option);
207
208 if ($this->object->isCustomOptionLabel($labelValue)) {
209 $customLabelTrue = new ilTextInputGUI(
210 $this->lng->txt('option_label_custom_true'),
211 'option_label_custom_true'
212 );
213 $customLabelTrue->setValue($this->object->getCustomTrueOptionLabel());
214 $option->addSubItem($customLabelTrue);
215
216 $customLabelFalse = new ilTextInputGUI(
217 $this->lng->txt('option_label_custom_false'),
218 'option_label_custom_false'
219 );
220 $customLabelFalse->setValue($this->object->getCustomFalseOptionLabel());
221 $option->addSubItem($customLabelFalse);
222 }
223 }
224 $form->addItem($optionLabel);
225
226 // points
227 $points = new ilNumberInputGUI($this->lng->txt('points'), 'points');
228 $points->setRequired(true);
229 $points->setSize(3);
230 $points->allowDecimals(true);
231 $points->setMinValue(0);
232 $points->setMinvalueShouldBeGreater(true);
233 $points->setValue($this->object->getPoints());
234 $form->addItem($points);
235
236 // score partial solution
237 $scorePartialSolution = new ilCheckboxInputGUI($this->lng->txt('score_partsol_enabled'), 'score_partsol_enabled');
238 $scorePartialSolution->setInfo($this->lng->txt('score_partsol_enabled_info'));
239 $scorePartialSolution->setChecked($this->object->isScorePartialSolutionEnabled());
240 $form->addItem($scorePartialSolution);
241
242 return $form;
243 }
244
249 {
250 $old_answer_type = $this->object->getAnswerType();
251
252 $this->object->setShuffleAnswersEnabled($form->getItemByPostVar('shuffle_answers_enabled')->getChecked());
253
254 if (!$this->object->getSelfAssessmentEditingMode()) {
255 $this->object->setAnswerType($form->getItemByPostVar('answer_type')->getValue());
256 }
257
258 if (!$this->object->getSelfAssessmentEditingMode() && $this->object->isSingleLineAnswerType($old_answer_type)) {
259 $this->object->setThumbSize((int) ($form->getItemByPostVar('thumb_size')->getValue() ?? $this->object->getThumbSize()));
260 }
261
262 $this->object->setOptionLabel($form->getItemByPostVar('option_label')->getValue());
263
264 if ($this->object->isCustomOptionLabel($this->object->getOptionLabel())) {
265 $this->object->setCustomTrueOptionLabel(strip_tags(
266 $form->getItemByPostVar('option_label_custom_true')->getValue()
267 ));
268 $this->object->setCustomFalseOptionLabel(strip_tags(
269 $form->getItemByPostVar('option_label_custom_false')->getValue()
270 ));
271 }
272
273 $this->object->setPoints($form->getItemByPostVar('points')->getValue());
274
275 $this->object->setScorePartialSolutionEnabled($form->getItemByPostVar('score_partsol_enabled')->getChecked());
276 }
277
283 {
284 require_once 'Modules/TestQuestionPool/classes/class.ilKprimChoiceWizardInputGUI.php';
285 $kprimAnswers = new ilKprimChoiceWizardInputGUI($this->lng->txt('answers'), 'kprim_answers');
286 $kprimAnswers->setInfo($this->lng->txt('kprim_answers_info'));
287 $kprimAnswers->setSize(64);
288 $kprimAnswers->setRequired(true);
289 $kprimAnswers->setAllowMove(true);
290 $kprimAnswers->setQuestionObject($this->object);
291 $kprimAnswers->setSingleline($this->object->isSingleLineAnswerType($this->object->getAnswerType()));
292 $kprimAnswers->setValues($this->object->getAnswers());
293 $form->addItem($kprimAnswers);
294
295 return $form;
296 }
297
302 {
303 $answers = $form->getItemByPostVar('kprim_answers')->getValues();
304 $answers = $this->handleAnswerTextsSubmit($answers);
305 $files = $form->getItemByPostVar('kprim_answers')->getFiles();
306
307 $this->object->handleFileUploads($answers, $files);
308 $this->object->setAnswers($answers);
309 }
310
311 private function handleAnswerTextsSubmit($answers)
312 {
313 if ($this->object->getAnswerType() == assKprimChoice::ANSWER_TYPE_MULTI_LINE) {
314 return $answers;
315 }
316
317 foreach ($answers as $key => $answer) {
318 $answer->setAnswerText(ilUtil::secureString(htmlspecialchars($answer->getAnswerText())));
319 }
320
321 return $answers;
322 }
323
329 public function getSpecificFeedbackOutput(array $userSolution): string
330 {
331 return ''; // question type supports inline answer specific feedback
332 }
333
343 public function getTestOutput(
344 $active_id,
345 // hey: prevPassSolutions - will be always available from now on
346 $pass,
347 // hey.
348 $is_postponed = false,
349 $use_post_solutions = false,
350 $showInlineFeedback = false
351 ): string {
352 // shuffle output
354
355 // get the solution of the user for the active pass or from the last pass if allowed
356 $user_solution = array();
357 if ($active_id) {
358 $solutions = $this->object->getTestOutputSolutions($active_id, $pass);
359 // hey.
360 foreach ($solutions as $idx => $solution_value) {
361 $user_solution[$solution_value["value1"]] = $solution_value["value2"];
362 }
363 }
364
365 // generate the question output
366 include_once "./Services/UICore/classes/class.ilTemplate.php";
367 $template = new ilTemplate("tpl.il_as_qpl_mc_kprim_output.html", true, true, "Modules/TestQuestionPool");
368
369 foreach ($keys as $answer_id) {
370 $answer = $this->object->getAnswer($answer_id);
371 if (strlen($answer->getImageFile())) {
372 if ($this->object->getThumbSize()) {
373 $template->setCurrentBlock("preview");
374 $template->setVariable("URL_PREVIEW", $answer->getImageWebPath());
375 $template->setVariable("TEXT_PREVIEW", $this->lng->txt('preview'));
376 $template->setVariable("IMG_PREVIEW", ilUtil::getImagePath('enlarge.svg'));
377 $template->setVariable("ANSWER_IMAGE_URL", $answer->getThumbWebPath());
378 [$width, $height, $type, $attr] = getimagesize($answer->getImageFsPath());
379 $alt = $answer->getImageFile();
380 if (strlen($answer->getAnswertext())) {
381 $alt = $answer->getAnswertext();
382 }
383 $alt = preg_replace("/<[^>]*?>/", "", $alt);
384 $template->setVariable("ANSWER_IMAGE_ALT", ilLegacyFormElementsUtil::prepareFormOutput($alt));
385 $template->setVariable("ANSWER_IMAGE_TITLE", ilLegacyFormElementsUtil::prepareFormOutput($alt));
386 $template->parseCurrentBlock();
387 } else {
388 $template->setCurrentBlock("answer_image");
389 $template->setVariable("ANSWER_IMAGE_URL", $answer->getImageWebPath());
390 [$width, $height, $type, $attr] = getimagesize($answer->getImageFsPath());
391 $alt = $answer->getImageFile();
392 if (strlen($answer->getAnswertext())) {
393 $alt = $answer->getAnswertext();
394 }
395 $alt = preg_replace("/<[^>]*?>/", "", $alt);
396 $template->setVariable("ATTR", $attr);
397 $template->setVariable("ANSWER_IMAGE_ALT", ilLegacyFormElementsUtil::prepareFormOutput($alt));
398 $template->setVariable("ANSWER_IMAGE_TITLE", ilLegacyFormElementsUtil::prepareFormOutput($alt));
399 $template->parseCurrentBlock();
400 }
401 }
402
403 if ($showInlineFeedback) {
404 $this->populateSpecificFeedbackInline($user_solution, $answer_id, $template);
405 }
406
407 $template->setCurrentBlock("answer_row");
408 $template->setVariable("ANSWER_ID", $answer_id);
409 $template->setVariable("ANSWER_TEXT", $this->object->prepareTextareaOutput($answer->getAnswertext(), true));
410 $template->setVariable('VALUE_TRUE', 1);
411 $template->setVariable('VALUE_FALSE', 0);
412
413 if (isset($user_solution[$answer->getPosition()])) {
414 $tplVar = $user_solution[$answer->getPosition()] ? 'CHECKED_ANSWER_TRUE' : 'CHECKED_ANSWER_FALSE';
415 $template->setVariable($tplVar, " checked=\"checked\"");
416 }
417
418 $template->parseCurrentBlock();
419 }
420 $template->setVariable("QUESTIONTEXT", $this->object->getQuestionForHTMLOutput());
421 $template->setVariable("INSTRUCTIONTEXT", $this->object->getInstructionTextTranslation(
422 $this->lng,
423 $this->object->getOptionLabel()
424 ));
425
426 $template->setVariable("OPTION_LABEL_TRUE", $this->object->getTrueOptionLabelTranslation(
427 $this->lng,
428 $this->object->getOptionLabel()
429 ));
430
431 $template->setVariable("OPTION_LABEL_FALSE", $this->object->getFalseOptionLabelTranslation(
432 $this->lng,
433 $this->object->getOptionLabel()
434 ));
435
436 $questionoutput = $template->get();
437 $pageoutput = $this->outQuestionPage("", $is_postponed, $active_id, $questionoutput, $showInlineFeedback);
438 return $pageoutput;
439 }
440
445 public function getPreview($show_question_only = false, $showInlineFeedback = false): string
446 {
447 $user_solution = is_object($this->getPreviewSession()) ? (array) $this->getPreviewSession()->getParticipantsSolution() : array();
448 // shuffle output
449 $keys = $this->getParticipantsAnswerKeySequence();
450
451 // generate the question output
452 include_once "./Services/UICore/classes/class.ilTemplate.php";
453 $template = new ilTemplate("tpl.il_as_qpl_mc_kprim_output.html", true, true, "Modules/TestQuestionPool");
454
455 foreach ($keys as $answer_id) {
456 $answer = $this->object->getAnswer($answer_id);
457 if (strlen($answer->getImageFile())) {
458 if ($this->object->getThumbSize()) {
459 $template->setCurrentBlock("preview");
460 $template->setVariable("URL_PREVIEW", $answer->getImageWebPath());
461 $template->setVariable("TEXT_PREVIEW", $this->lng->txt('preview'));
462 $template->setVariable("IMG_PREVIEW", ilUtil::getImagePath('enlarge.svg'));
463 $template->setVariable("ANSWER_IMAGE_URL", $answer->getThumbWebPath());
464 [$width, $height, $type, $attr] = getimagesize($answer->getImageFsPath());
465 $alt = $answer->getImageFile();
466 if (strlen($answer->getAnswertext())) {
467 $alt = $answer->getAnswertext();
468 }
469 $alt = preg_replace("/<[^>]*?>/", "", $alt);
470 $template->setVariable("ANSWER_IMAGE_ALT", ilLegacyFormElementsUtil::prepareFormOutput($alt));
471 $template->setVariable("ANSWER_IMAGE_TITLE", ilLegacyFormElementsUtil::prepareFormOutput($alt));
472 $template->parseCurrentBlock();
473 } else {
474 $template->setCurrentBlock("answer_image");
475 $template->setVariable("ANSWER_IMAGE_URL", $answer->getImageWebPath());
476 [$width, $height, $type, $attr] = getimagesize($answer->getImageFsPath());
477 $alt = $answer->getImageFile();
478 if (strlen($answer->getAnswertext())) {
479 $alt = $answer->getAnswertext();
480 }
481 $alt = preg_replace("/<[^>]*?>/", "", $alt);
482 $template->setVariable("ATTR", $attr);
483 $template->setVariable("ANSWER_IMAGE_ALT", ilLegacyFormElementsUtil::prepareFormOutput($alt));
484 $template->setVariable("ANSWER_IMAGE_TITLE", ilLegacyFormElementsUtil::prepareFormOutput($alt));
485 $template->parseCurrentBlock();
486 }
487 }
488
489 if ($showInlineFeedback) {
490 $this->populateSpecificFeedbackInline($user_solution, $answer_id, $template);
491 }
492
493 $template->setCurrentBlock("answer_row");
494 $template->setVariable("ANSWER_ID", $answer_id);
495 $template->setVariable("ANSWER_TEXT", $this->object->prepareTextareaOutput((string) $answer->getAnswertext(), true));
496 $template->setVariable('VALUE_TRUE', 1);
497 $template->setVariable('VALUE_FALSE', 0);
498
499 if (isset($user_solution[$answer->getPosition()])) {
500 $tplVar = $user_solution[$answer->getPosition()] ? 'CHECKED_ANSWER_TRUE' : 'CHECKED_ANSWER_FALSE';
501 $template->setVariable($tplVar, " checked=\"checked\"");
502 }
503
504 $template->parseCurrentBlock();
505 }
506 $questiontext = $this->object->getQuestionForHTMLOutput();
507 if ($showInlineFeedback && $this->hasInlineFeedback()) {
508 $questiontext .= $this->buildFocusAnchorHtml();
509 }
510 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, true));
511
512 $template->setVariable("INSTRUCTIONTEXT", $this->object->getInstructionTextTranslation(
513 $this->lng,
514 $this->object->getOptionLabel()
515 ));
516
517 $template->setVariable("OPTION_LABEL_TRUE", $this->object->getTrueOptionLabelTranslation(
518 $this->lng,
519 $this->object->getOptionLabel()
520 ));
521
522 $template->setVariable("OPTION_LABEL_FALSE", $this->object->getFalseOptionLabelTranslation(
523 $this->lng,
524 $this->object->getOptionLabel()
525 ));
526
527 $questionoutput = $template->get();
528 if (!$show_question_only) {
529 // get page object output
530 $questionoutput = $this->getILIASPage($questionoutput);
531 }
532 return $questionoutput;
533 }
534
546 public function getSolutionOutput(
547 $active_id,
548 $pass = null,
549 $graphicalOutput = false,
550 $result_output = false,
551 $show_question_only = true,
552 $show_feedback = false,
553 $show_correct_solution = false,
554 $show_manual_scoring = false,
555 $show_question_text = true
556 ): string {
557 // shuffle output
558 $keys = $this->getParticipantsAnswerKeySequence();
559
560 // get the solution of the user for the active pass or from the last pass if allowed
561 $user_solution = array();
562 if (($active_id > 0) && (!$show_correct_solution)) {
563 $solutions = $this->object->getSolutionValues($active_id, $pass);
564 foreach ($solutions as $idx => $solution_value) {
565 $user_solution[$solution_value['value1']] = $solution_value['value2'];
566 }
567 } else {
568 // take the correct solution instead of the user solution
569 foreach ($this->object->getAnswers() as $answer) {
570 $user_solution[$answer->getPosition()] = $answer->getCorrectness();
571 }
572 }
573
574 // generate the question output
575 $template = new ilTemplate("tpl.il_as_qpl_mc_kprim_output_solution.html", true, true, "Modules/TestQuestionPool");
576
577 foreach ($keys as $answer_id) {
578 $answer = $this->object->getAnswer($answer_id);
579
580 if (($active_id > 0) &&
581 !$show_correct_solution &&
582 $graphicalOutput) {
583 $correctness_icon = $this->generateCorrectnessIconsForCorrectness(self::CORRECTNESS_NOT_OK);
584 if (isset($user_solution[$answer->getPosition()]) && $user_solution[$answer->getPosition()] == $answer->getCorrectness()) {
585 $correctness_icon = $this->generateCorrectnessIconsForCorrectness(self::CORRECTNESS_OK);
586 }
587 $template->setCurrentBlock("icon_ok");
588 $template->setVariable("ICON_OK", $correctness_icon);
589 $template->parseCurrentBlock();
590 }
591 if (strlen($answer->getImageFile())) {
592 $template->setCurrentBlock("answer_image");
593 if ($this->object->getThumbSize()) {
594 $template->setVariable("ANSWER_IMAGE_URL", $answer->getThumbWebPath());
595 } else {
596 $template->setVariable("ANSWER_IMAGE_URL", $answer->getImageWebPath());
597 }
598
599 $template->setVariable(
600 "ANSWER_IMAGE_ALT",
602 $answer->getImageFile()
603 )
604 );
605 $template->setVariable(
606 "ANSWER_IMAGE_TITLE",
608 $answer->getImageFile()
609 )
610 );
611 $template->parseCurrentBlock();
612 }
613
614 if ($show_feedback) {
615 $this->populateSpecificFeedbackInline($user_solution, $answer_id, $template);
616 }
617
618 $template->setCurrentBlock("answer_row");
619 $template->setVariable("ANSWER_TEXT", $this->object->prepareTextareaOutput($answer->getAnswertext(), true));
620
621 if ($this->renderPurposeSupportsFormHtml() || $this->isRenderPurposePrintPdf()) {
622 if (isset($user_solution[$answer->getPosition()])) {
623 if ($user_solution[$answer->getPosition()]) {
624 $template->setVariable("SOLUTION_IMAGE_TRUE", ilUtil::getHtmlPath(ilUtil::getImagePath("radiobutton_checked.png")));
625 $template->setVariable("SOLUTION_ALT_TRUE", $this->lng->txt("checked"));
626 $template->setVariable("SOLUTION_IMAGE_FALSE", ilUtil::getHtmlPath(ilUtil::getImagePath("radiobutton_unchecked.png")));
627 $template->setVariable("SOLUTION_ALT_FALSE", $this->lng->txt("unchecked"));
628 } else {
629 $template->setVariable("SOLUTION_IMAGE_TRUE", ilUtil::getHtmlPath(ilUtil::getImagePath("radiobutton_unchecked.png")));
630 $template->setVariable("SOLUTION_ALT_TRUE", $this->lng->txt("unchecked"));
631 $template->setVariable("SOLUTION_IMAGE_FALSE", ilUtil::getHtmlPath(ilUtil::getImagePath("radiobutton_checked.png")));
632 $template->setVariable("SOLUTION_ALT_FALSE", $this->lng->txt("checked"));
633 }
634 } else {
635 $template->setVariable("SOLUTION_IMAGE_TRUE", ilUtil::getHtmlPath(ilUtil::getImagePath("radiobutton_unchecked.png")));
636 $template->setVariable("SOLUTION_ALT_TRUE", $this->lng->txt("unchecked"));
637 $template->setVariable("SOLUTION_IMAGE_FALSE", ilUtil::getHtmlPath(ilUtil::getImagePath("radiobutton_unchecked.png")));
638 $template->setVariable("SOLUTION_ALT_FALSE", $this->lng->txt("unchecked"));
639 }
640 } else {
641 $template->setVariable('SOL_QID', $this->object->getId());
642 $template->setVariable('SOL_SUFFIX', $show_correct_solution ? 'bestsolution' : 'usersolution');
643 $template->setVariable('SOL_POSITION', $answer->getPosition());
644
645 $template->setVariable('SOL_TRUE_VALUE', 1);
646 $template->setVariable('SOL_FALSE_VALUE', 0);
647
648 if (isset($user_solution[$answer->getPosition()])) {
649 if ($user_solution[$answer->getPosition()]) {
650 $template->setVariable('SOL_TRUE_CHECKED', 'checked');
651 } else {
652 $template->setVariable('SOL_FALSE_CHECKED', 'checked');
653 }
654 }
655 }
656
657 $template->parseCurrentBlock();
658 }
659
660 if ($show_question_text == true) {
661 $questiontext = $this->object->getQuestionForHTMLOutput();
662 if ($show_feedback && $this->hasInlineFeedback()) {
663 $questiontext .= $this->buildFocusAnchorHtml();
664 }
665 $template->setVariable("QUESTIONTEXT", $this->object->prepareTextareaOutput($questiontext, true));
666
667 $template->setVariable("INSTRUCTIONTEXT", $this->object->getInstructionTextTranslation(
668 $this->lng,
669 $this->object->getOptionLabel()
670 ));
671 }
672
673 $template->setVariable("OPTION_LABEL_TRUE", $this->object->getTrueOptionLabelTranslation(
674 $this->lng,
675 $this->object->getOptionLabel()
676 ));
677
678 $template->setVariable("OPTION_LABEL_FALSE", $this->object->getFalseOptionLabelTranslation(
679 $this->lng,
680 $this->object->getOptionLabel()
681 ));
682
683
684 $questionoutput = $template->get();
685 $feedback = ($show_feedback && !$this->isTestPresentationContext()) ? $this->getGenericFeedbackOutput((int) $active_id, $pass) : "";
686
687 $solutiontemplate = new ilTemplate("tpl.il_as_tst_solution_output.html", true, true, "Modules/TestQuestionPool");
688
689 if (strlen($feedback)) {
690 $cssClass = (
691 $this->hasCorrectSolution($active_id, $pass) ?
693 );
694
695 $solutiontemplate->setVariable("ILC_FB_CSS_CLASS", $cssClass);
696 $solutiontemplate->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($feedback, true));
697 }
698
699 $solutiontemplate->setVariable("SOLUTION_OUTPUT", $questionoutput);
700
701 $solutionoutput = $solutiontemplate->get();
702
703 if (!$show_question_only) {
704 // get page object output
705 $solutionoutput = $this->getILIASPage($solutionoutput);
706 }
707 return $solutionoutput;
708 }
709
711 {
712 $choiceKeys = array_keys($this->object->getAnswers());
713
714 if ($this->object->isShuffleAnswersEnabled()) {
715 $choiceKeys = $this->object->getShuffler()->transform($choiceKeys);
716 }
717
718 return $choiceKeys;
719 }
720
721 private function populateSpecificFeedbackInline($user_solution, $answer_id, $template): void
722 {
723 require_once 'Modules/TestQuestionPool/classes/feedback/class.ilAssConfigurableMultiOptionQuestionFeedback.php';
724
725 if ($this->object->getSpecificFeedbackSetting() == ilAssConfigurableMultiOptionQuestionFeedback::FEEDBACK_SETTING_CHECKED) {
726 if (array_key_exists($answer_id, $user_solution)) {
727 $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation($this->object->getId(), 0, $answer_id);
728 if (strlen($fb)) {
729 $template->setCurrentBlock("feedback");
730 $template->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($fb, true));
731 $template->parseCurrentBlock();
732 }
733 }
734 }
735
736 if ($this->object->getSpecificFeedbackSetting() == ilAssConfigurableMultiOptionQuestionFeedback::FEEDBACK_SETTING_ALL) {
737 $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation($this->object->getId(), 0, $answer_id);
738 if (strlen($fb)) {
739 $template->setCurrentBlock("feedback");
740 $template->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($fb, true));
741 $template->parseCurrentBlock();
742 }
743 }
744
745 if ($this->object->getSpecificFeedbackSetting() == ilAssConfigurableMultiOptionQuestionFeedback::FEEDBACK_SETTING_CORRECT) {
746 $answer = $this->object->getAnswer($answer_id);
747
748 if ($answer->getCorrectness()) {
749 $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation($this->object->getId(), 0, $answer_id);
750 if (strlen($fb)) {
751 $template->setCurrentBlock("feedback");
752 $template->setVariable("FEEDBACK", $this->object->prepareTextareaOutput($fb, true));
753 $template->parseCurrentBlock();
754 }
755 }
756 }
757 }
758
769 {
770 return array();
771 }
772
783 {
784 return array();
785 }
786
793 public function getAggregatedAnswersView(array $relevant_answers): string
794 {
795 return $this->renderAggregateView(
796 $this->aggregateAnswers($relevant_answers, $this->object->getAnswers())
797 )->get();
798
799 return '<pre>' . print_r($relevant_answers, 1) . '</pre>';
800 }
801
802 public function renderAggregateView($aggregate): ilTemplate
803 {
804 $trueOptionLabel = $this->object->getTrueOptionLabelTranslation($this->lng, $this->object->getOptionLabel());
805 $falseOptionLabel = $this->object->getFalseOptionLabelTranslation($this->lng, $this->object->getOptionLabel());
806
807 $tpl = new ilTemplate('tpl.il_as_aggregated_kprim_answers_table.html', true, true, "Modules/TestQuestionPool");
808
809 foreach ($aggregate as $lineData) {
810 $tpl->setCurrentBlock('aggregaterow');
811 $tpl->setVariable('OPTION', $lineData['answertext']);
812 $tpl->setVariable('COUNT_TRUE', $lineData['count_true']);
813 $tpl->setVariable('COUNT_FALSE', $lineData['count_false']);
814 $tpl->parseCurrentBlock();
815 }
816
817 $tpl->setVariable('OPTION_HEAD', $this->lng->txt('answers'));
818 $tpl->setVariable('COUNT_TRUE_HEAD', $trueOptionLabel);
819 $tpl->setVariable('COUNT_FALSE_HEAD', $falseOptionLabel);
820
821 return $tpl;
822 }
823
824 public function aggregateAnswers($rawSolutionData, $answers): array
825 {
826 $aggregate = array();
827
828 foreach ($answers as $answer) {
829 $answerAgg = array(
830 'answertext' => $answer->getAnswerText(), 'count_true' => 0, 'count_false' => 0
831 );
832
833 foreach ($rawSolutionData as $solutionRecord) {
834 if ($solutionRecord['value1'] == $answer->getPosition()) {
835 if ($solutionRecord['value2']) {
836 $answerAgg['count_true']++;
837 } else {
838 $answerAgg['count_false']++;
839 }
840 }
841 }
842
843 $aggregate[] = $answerAgg;
844 }
845
846 return $aggregate;
847 }
848
849 public function getAnswersFrequency($relevantAnswers, $questionIndex): array
850 {
851 $agg = $this->aggregateAnswers($relevantAnswers, $this->object->getAnswers());
852
853 $answers = array();
854
855 foreach ($agg as $ans) {
856 $answers[] = array(
857 'answer' => $ans['answertext'],
858 'frequency_true' => $ans['count_true'],
859 'frequency_false' => $ans['count_false']
860 );
861 }
862
863 return $answers;
864 }
865
873 public function getAnswerFrequencyTableGUI($parentGui, $parentCmd, $relevantAnswers, $questionIndex): ilAnswerFrequencyStatisticTableGUI
874 {
875 require_once 'Modules/TestQuestionPool/classes/tables/class.ilKprimChoiceAnswerFreqStatTableGUI.php';
876
877 $table = new ilKprimChoiceAnswerFreqStatTableGUI($parentGui, $parentCmd, $this->object);
878 $table->setQuestionIndex($questionIndex);
879 $table->setData($this->getAnswersFrequency($relevantAnswers, $questionIndex));
880 $table->initColumns();
881
882 return $table;
883 }
884
886 {
887 // points
888 $points = new ilNumberInputGUI($this->lng->txt('points'), 'points');
889 $points->setRequired(true);
890 $points->setSize(3);
891 $points->allowDecimals(true);
892 $points->setMinValue(0);
893 $points->setMinvalueShouldBeGreater(true);
894 $points->setValue($this->object->getPoints());
895 $form->addItem($points);
896
897 // score partial solution
898 $scorePartialSolution = new ilCheckboxInputGUI($this->lng->txt('score_partsol_enabled'), 'score_partsol_enabled');
899 $scorePartialSolution->setInfo($this->lng->txt('score_partsol_enabled_info'));
900 $scorePartialSolution->setChecked($this->object->isScorePartialSolutionEnabled());
901 $form->addItem($scorePartialSolution);
902
903 // answers
904 require_once 'Modules/TestQuestionPool/classes/forms/class.ilKprimChoiceCorrectionsInputGUI.php';
905 $kprimAnswers = new ilKprimChoiceCorrectionsInputGUI($this->lng->txt('answers'), 'kprim_answers');
906 $kprimAnswers->setInfo($this->lng->txt('kprim_answers_info'));
907 $kprimAnswers->setSize(64);
908 $kprimAnswers->setMaxLength(1000);
909 $kprimAnswers->setRequired(true);
910 $kprimAnswers->setQuestionObject($this->object);
911 $kprimAnswers->setValues($this->object->getAnswers());
912 $form->addItem($kprimAnswers);
913 }
914
919 {
920 $this->object->setPoints(
921 (float) str_replace(',', '.', $form->getInput('points'))
922 );
923
924 $this->object->setScorePartialSolutionEnabled(
925 (bool) $form->getInput('score_partsol_enabled')
926 );
927
928 $this->object->setAnswers(
929 $form->getItemByPostVar('kprim_answers')->getValues()
930 );
931 }
932}
populateSpecificFeedbackInline($user_solution, $answer_id, $template)
getAnswerFrequencyTableGUI($parentGui, $parentCmd, $relevantAnswers, $questionIndex)
getAfterParticipationSuppressionQuestionPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
writeAnswerSpecificPostData(ilPropertyFormGUI $form)
getAfterParticipationSuppressionAnswerPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
writePostData(bool $always=false)
{Evaluates a posted edit form and writes the form data in the question object.integer A positive valu...
populateCorrectionsFormProperties(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)
writeQuestionSpecificPostData(ilPropertyFormGUI $form)
editQuestion(ilPropertyFormGUI $form=null)
getSpecificFeedbackOutput(array $userSolution)
aggregateAnswers($rawSolutionData, $answers)
getPreview($show_question_only=false, $showInlineFeedback=false)
getTestOutput( $active_id, $pass, $is_postponed=false, $use_post_solutions=false, $showInlineFeedback=false)
populateAnswerSpecificFormPart(ilPropertyFormGUI $form)
populateQuestionSpecificFormPart(ilPropertyFormGUI $form)
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)
saveCorrectionsFormProperties(ilPropertyFormGUI $form)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
populateTaxonomyFormSection(ilPropertyFormGUI $form)
addBasicQuestionFormProperties(ilPropertyFormGUI $form)
outQuestionPage($a_temp_var, $a_postponed=false, $active_id="", $html="", $inlineFeedbackEnabled=false)
addQuestionFormCommandButtons(ilPropertyFormGUI $form)
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.
getInput(string $a_post_var, bool $ensureValidation=true)
Returns the input of an item, if item provides getInput method and as fallback the value of the HTTP-...
getItemByPostVar(string $a_post_var)
This class represents a property in a property form.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This class represents a selection list property in a property form.
special template class to simplify handling of ITX/PEAR
This class represents a text property in a property form.
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)
static secureString(string $a_str, bool $a_strip_html=true, string $a_allow="")
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
$keys
Definition: metadata.php:204
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
string $key
Consumer key/client ID value.
Definition: System.php:193
$type