19 require_once
'./Modules/Test/classes/inc.AssessmentConstants.php';
50 $this->
object->loadFromDb(
$id);
59 return $this->
object->feedbackOBJ->isSpecificAnswerFeedbackAvailable($this->
object->getId());
67 $hasErrors = (!$always) ? $this->
editQuestion(
true) :
false;
87 if ($this->
object->getSelfAssessmentEditingMode()) {
88 return $this->
object->isSingleline();
92 $types = $_POST[
'types'] ??
'0';
93 return $types ===
'0' ? true :
false;
96 $lastChange = $this->
object->getLastChange();
97 if (empty($lastChange) && !isset($_POST[
'types'])) {
99 return $this->
object->getMultilineAnswerSetting() ? false :
true;
102 return $this->
object->isSingleline();
116 $this->editForm = $form;
118 $form->setFormAction($this->
ctrl->getFormAction($this));
121 if ($is_singleline) {
122 $form->setMultipart(
true);
124 $form->setMultipart(
false);
126 $form->setTableWidth(
"100%");
127 $form->setId(
"asssinglechoice");
141 foreach ($this->request->getParsedBody() as
$key => $value) {
142 $item = $form->getItemByPostVar($key);
143 if ($item !== null) {
144 switch (get_class($item)) {
145 case 'ilDurationInputGUI':
146 $item->setHours($value[
'hh']);
147 $item->setMinutes($value[
'mm']);
148 $item->setSeconds($value[
'ss']);
151 $item->setValue($value);
156 $errors = !$form->checkInput();
157 foreach ($this->request->getParsedBody() as $key => $value) {
158 $item = $form->getItemByPostVar($key);
159 if ($item !== null) {
160 switch (get_class($item)) {
161 case 'ilDurationInputGUI':
162 $item->setHours($value[
'hh']);
163 $item->setMinutes($value[
'mm']);
164 $item->setSeconds($value[
'ss']);
167 $item->setValue($value);
178 $this->tpl->setVariable(
"QUESTION_DATA", $form->getHTML());
189 $position = key($_POST[
'cmd'][
'uploadchoice']);
199 $position = key($_POST[
'cmd'][
'removeimagechoice']);
200 $filename = $_POST[
'choice'][
'imagename'][$position];
201 $this->
object->removeAnswerImage($position);
211 $position = key($_POST[
'cmd'][
'addchoice']);
212 $this->
object->addAnswer(
"", 0, $position + 1);
222 $position = key($_POST[
'cmd'][
'removechoice']);
223 $this->
object->deleteAnswer($position);
242 $graphicalOutput =
false,
243 $result_output =
false,
244 $show_question_only =
true,
245 $show_feedback =
false,
246 $show_correct_solution =
false,
247 $show_manual_scoring =
false,
248 $show_question_text =
true,
249 bool $show_inline_feedback =
true 252 if (($active_id > 0) && (!$show_correct_solution)) {
253 $user_solutions = $this->
object->getSolutionValues($active_id, $pass);
258 foreach ($this->
object->answers as $index => $answer) {
259 if ($answer->getPoints() > $max_points) {
260 $max_points = $answer->getPoints();
261 $found_index = $index;
264 $user_solutions = [[
'value1' => $found_index]];
275 $show_correct_solution,
276 $show_manual_scoring,
279 $show_inline_feedback,
284 mixed $user_solutions,
287 bool $graphical_output =
false,
288 bool $result_output =
false,
289 bool $show_question_only =
true,
290 bool $show_feedback =
false,
291 bool $show_correct_solution =
false,
292 bool $show_manual_scoring =
false,
293 bool $show_question_text =
true,
294 bool $show_autosave_title =
false,
295 bool $show_inline_feedback =
false,
298 foreach ($user_solutions as $idx => $solution_value) {
299 $user_solution = $solution_value[
'value1'];
303 $template =
new ilTemplate(
"tpl.il_as_qpl_mc_sr_output_solution.html",
true,
true,
"Modules/TestQuestionPool");
304 $solutiontemplate =
new ilTemplate(
"tpl.il_as_tst_solution_output.html",
true,
true,
"Modules/TestQuestionPool");
305 foreach ($keys as $answer_id) {
306 $answer = $this->
object->answers[$answer_id];
307 if ($active_id > 0 && !$show_correct_solution && $graphical_output) {
309 (
string) $user_solution,
311 $answer->getPoints(),
312 $this->
object->getMaximumPoints()
314 $template->setCurrentBlock(
"icon_ok");
316 $template->parseCurrentBlock();
318 if ($answer->hasImage()) {
319 $template->setCurrentBlock(
"answer_image");
320 if ($this->
object->getThumbSize()) {
321 $template->setVariable(
"ANSWER_IMAGE_URL", $this->
object->getImagePathWeb() . $this->
object->getThumbPrefix() . $answer->getImage());
323 $template->setVariable(
"ANSWER_IMAGE_URL", $this->
object->getImagePathWeb() . $answer->getImage());
325 $alt = $answer->getImage();
326 if (strlen($answer->getAnswertext())) {
327 $alt = $answer->getAnswertext();
329 $alt = preg_replace(
"/<[^>]*?>/",
"", $alt);
332 $template->parseCurrentBlock();
338 $template->setCurrentBlock(
"answer_row");
342 if ((
string) $user_solution === (string) $answer_id) {
344 $template->setVariable(
"SOLUTION_ALT", $this->
lng->txt(
"checked"));
347 $template->setVariable(
"SOLUTION_ALT", $this->
lng->txt(
"unchecked"));
350 $template->setVariable(
'QID', $this->
object->getId());
351 $template->setVariable(
'SUFFIX', $show_correct_solution ?
'bestsolution' :
'usersolution');
352 $template->setVariable(
'SOLUTION_VALUE', $answer_id);
353 if ((
string) $user_solution === (
string) $answer_id) {
354 $template->setVariable(
'SOLUTION_CHECKED',
'checked');
358 if ($result_output) {
359 $points = $this->
object->answers[$answer_id]->getPoints();
360 $resulttext = ($points == 1) ?
"(%s " . $this->
lng->txt(
"point") .
")" :
"(%s " . $this->
lng->txt(
"points") .
")";
361 $template->setVariable(
"RESULT_OUTPUT", sprintf($resulttext, $points));
363 $template->parseCurrentBlock();
366 $questiontext = $this->
object->getQuestionForHTMLOutput();
370 if ($show_question_text ==
true) {
373 $questionoutput = $template->get();
375 if ($feedback !==
'') {
381 $solutiontemplate->setVariable(
"ILC_FB_CSS_CLASS", $cssClass);
384 $solutiontemplate->setVariable(
"SOLUTION_OUTPUT", $questionoutput);
386 $solutionoutput = $solutiontemplate->get();
388 if (!$show_question_only) {
392 return $solutionoutput;
396 string $user_solution,
398 float $answer_points,
399 float $maximum_points
401 if ($user_solution === $answer_id
402 && $answer_points === $maximum_points
403 || $user_solution !== $answer_id
404 && $answer_points === 0.0
406 return self::CORRECTNESS_OK;
409 if ($user_solution === $answer_id
410 && $answer_points > 0.0) {
411 return self::CORRECTNESS_MOSTLY_OK;
414 return self::CORRECTNESS_NOT_OK;
417 public function getPreview($show_question_only =
false, $showInlineFeedback =
false): string
421 $template =
new ilTemplate(
"tpl.il_as_qpl_mc_sr_output.html",
true,
true,
"Modules/TestQuestionPool");
422 foreach ($keys as $answer_id) {
423 $answer = $this->
object->answers[$answer_id];
424 if ($answer->hasImage()) {
425 if ($this->
object->getThumbSize()) {
426 $template->setCurrentBlock(
"preview");
427 $template->setVariable(
"URL_PREVIEW", $this->
object->getImagePathWeb() . $answer->getImage());
428 $template->setVariable(
"TEXT_PREVIEW", $this->
lng->txt(
'preview'));
430 $template->setVariable(
"ANSWER_IMAGE_URL", $this->
object->getImagePathWeb() . $this->
object->getThumbPrefix() . $answer->getImage());
431 list($width, $height, $type, $attr) = getimagesize($this->
object->getImagePath() . $answer->getImage());
432 $alt = $answer->getImage();
433 if (strlen($answer->getAnswertext())) {
434 $alt = $answer->getAnswertext();
436 $alt = preg_replace(
"/<[^>]*?>/",
"", $alt);
439 $template->parseCurrentBlock();
441 $template->setCurrentBlock(
"answer_image");
442 $template->setVariable(
"ANSWER_IMAGE_URL", $this->
object->getImagePathWeb() . $answer->getImage());
443 list($width, $height, $type, $attr) = getimagesize($this->
object->getImagePath() . $answer->getImage());
444 $alt = $answer->getImage();
445 if (strlen($answer->getAnswertext())) {
446 $alt = $answer->getAnswertext();
448 $alt = preg_replace(
"/<[^>]*?>/",
"", $alt);
449 $template->setVariable(
"ATTR", $attr);
452 $template->parseCurrentBlock();
458 $template->setCurrentBlock(
"answer_row");
459 $template->setVariable(
"QID", $this->
object->getId() .
'ID');
460 $template->setVariable(
"ANSWER_ID", $answer_id);
465 if ((
string) $user_solution === (
string) $answer_id) {
466 $template->setVariable(
"CHECKED_ANSWER",
" checked=\"checked\"");
470 $template->parseCurrentBlock();
472 $questiontext = $this->
object->getQuestionForHTMLOutput();
477 $questionoutput = $template->get();
478 if (!$show_question_only) {
482 return $questionoutput;
486 public function getTestOutput($active_id, $pass, $is_postponed =
false, $use_post_solutions =
false, $show_feedback =
false): string
494 $solutions = $this->
object->getTestOutputSolutions($active_id, $pass);
495 foreach ($solutions as $idx => $solution_value) {
496 $user_solution = $solution_value[
'value1'];
500 $template =
new ilTemplate(
"tpl.il_as_qpl_mc_sr_output.html",
true,
true,
"Modules/TestQuestionPool");
501 foreach ($keys as $answer_id) {
502 $answer = $this->
object->answers[$answer_id];
503 if ($answer->hasImage()) {
504 if ($this->
object->getThumbSize()) {
505 $template->setCurrentBlock(
"preview");
506 $template->setVariable(
"URL_PREVIEW", $this->
object->getImagePathWeb() . $answer->getImage());
507 $template->setVariable(
"TEXT_PREVIEW", $this->
lng->txt(
'preview'));
509 $template->setVariable(
"ANSWER_IMAGE_URL", $this->
object->getImagePathWeb() . $this->
object->getThumbPrefix() . $answer->getImage());
510 list($width, $height, $type, $attr) = getimagesize($this->
object->getImagePath() . $answer->getImage());
511 $alt = $answer->getImage();
512 if (strlen($answer->getAnswertext())) {
513 $alt = $answer->getAnswertext();
515 $alt = preg_replace(
"/<[^>]*?>/",
"", $alt);
518 $template->parseCurrentBlock();
520 $template->setCurrentBlock(
"answer_image");
521 $template->setVariable(
"ANSWER_IMAGE_URL", $this->
object->getImagePathWeb() . $answer->getImage());
522 list($width, $height, $type, $attr) = getimagesize($this->
object->getImagePath() . $answer->getImage());
523 $alt = $answer->getImage();
524 if (strlen($answer->getAnswertext())) {
525 $alt = $answer->getAnswertext();
527 $alt = preg_replace(
"/<[^>]*?>/",
"", $alt);
528 $template->setVariable(
"ATTR", $attr);
531 $template->parseCurrentBlock();
534 if ($show_feedback) {
535 $feedbackOutputRequired =
false;
537 switch ($this->
object->getSpecificFeedbackSetting()) {
539 $feedbackOutputRequired =
true;
543 if ((
string) $user_solution === (string) $answer_id) {
544 $feedbackOutputRequired =
true;
549 if ($this->
object->getAnswer($answer_id)->getPoints() > 0) {
550 $feedbackOutputRequired =
true;
555 if ($feedbackOutputRequired) {
556 $fb = $this->
object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation(
562 $template->setCurrentBlock(
"feedback");
564 $template->parseCurrentBlock();
568 $template->setCurrentBlock(
"answer_row");
569 $template->setVariable(
"ANSWER_ID", $answer_id);
571 if ((
string) $user_solution === (string) $answer_id) {
572 $template->setVariable(
"CHECKED_ANSWER",
" checked=\"checked\"");
574 $template->parseCurrentBlock();
576 $template->setVariable(
"QUESTIONTEXT", $this->
object->getQuestionForHTMLOutput());
577 $questionoutput = $template->get();
578 $pageoutput = $this->
outQuestionPage(
"", $is_postponed, $active_id, $questionoutput, $show_feedback);
589 $choice_keys = array_keys($this->
object->answers);
591 if ($this->
object->getShuffle()) {
592 $choice_keys = $this->
object->getShuffler()->transform($choice_keys);
607 $types = $_POST[
"types"] ??
'0';
609 $this->
object->setShuffle($_POST[
"shuffle"] ??
'0');
610 $this->
object->setMultilineAnswerSetting($types);
612 if (isset($_POST[
'choice']) && isset($_POST[
'choice'][
'imagename']) && is_array($_POST[
'choice'][
'imagename']) && $types ===
'1') {
613 $this->
object->setIsSingleline(
true);
614 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'info_answer_type_change'),
true);
616 $this->
object->setIsSingleline($types ===
'0' ?
true :
false);
618 if (isset($_POST[
"thumb_size"])
619 && (
int) $_POST[
"thumb_size"] !== $this->
object->getThumbSize()) {
620 $this->
object->setThumbSize((
int) $_POST[
"thumb_size"]);
621 $this->rebuild_thumbnails =
true;
629 $shuffle->setValue(1);
630 $shuffle->setChecked($this->
object->getShuffle());
631 $shuffle->setRequired(
false);
634 if ($this->
object->getId()) {
636 $hidden->setValue($this->
object->getId());
640 if (!$this->
object->getSelfAssessmentEditingMode()) {
644 $types->setValue(($is_singleline) ? 0 : 1);
647 0 => $this->
lng->txt(
'answers_singleline'),
648 1 => $this->
lng->txt(
'answers_multiline'),
654 if ($is_singleline) {
657 $thumb_size->setSuffix($this->
lng->txt(
"thumb_size_unit_pixel"));
658 $thumb_size->setMinValue($this->
object->getMinimumThumbSize());
659 $thumb_size->setMaxValue($this->
object->getMaximumThumbSize());
660 $thumb_size->setDecimals(0);
661 $thumb_size->setSize(6);
662 $thumb_size->setInfo($this->
lng->txt(
'thumb_size_info'));
663 $thumb_size->setValue($this->
object->getThumbSize());
664 $thumb_size->setRequired(
true);
667 $thumb_size->setValue($this->
object->getThumbSize());
691 $this->
object->flushAnswers();
693 if (!$this->
object->isSingleline()) {
694 foreach ($choice[
'answer'] as $index => $answer) {
695 $answertext = $answer;
696 $this->
object->addAnswer(
698 $this->
refinery->kindlyTo()->float()->transform($choice[
'points'][$index]),
701 $choice[
'answer_id'][$index]
708 foreach ($choice[
'answer'] as $index => $answertext) {
709 $answertext = htmlentities($answertext);
710 $picturefile = $choice[
'imagename'][$index] ?? null;
711 $file_org_name = $_FILES[
'choice'][
'name'][
'image'][$index] ??
'';
712 $file_temp_name = $_FILES[
'choice'][
'tmp_name'][
'image'][$index] ??
'';
714 if ($file_temp_name !==
'') {
716 $file_name_parts = explode(
".", $file_org_name);
717 $suffix = strtolower(array_pop($file_name_parts));
718 if (in_array($suffix, [
"jpg",
"jpeg",
"png",
"gif"])) {
720 $filename = $this->
object->buildHashedImageFilename($file_org_name);
727 $points = (float) str_replace(
',',
'.', $choice[
'points'][$index]);
728 $this->
object->addAnswer(
733 $choice[
'answer_id'][$index]
737 if ($this->rebuild_thumbnails) {
738 $this->
object->setAnswers(
739 $this->
object->rebuildThumbnails(
740 $this->object->isSingleline(),
741 $this->
object->getThumbSize(),
742 $this->
object->getImagePath(),
743 $this->
object->getAnswers()
753 $choices->setQuestionObject($this->
object);
754 $choices->setSingleline($is_singleline);
755 $choices->setAllowMove(
false);
756 if ($this->
object->getSelfAssessmentEditingMode()) {
757 $choices->setSize(40);
759 if ($this->
object->getAnswerCount() == 0) {
760 $this->
object->addAnswer(
"", 0, 0);
762 $choices->setValues(array_map(
764 $value->setAnswerText(html_entity_decode($value->getAnswerText()));
767 $this->
object->getAnswers()
800 public function aggregateAnswers($relevant_answers_chosen, $answers_defined_on_question): array
803 foreach ($answers_defined_on_question as $answer) {
804 $aggregated_info_for_answer = [];
805 $aggregated_info_for_answer[
'answertext'] = $answer->getAnswerText();
806 $aggregated_info_for_answer[
'count_checked'] = 0;
808 foreach ($relevant_answers_chosen as $relevant_answer) {
809 if ($relevant_answer[
'value1'] == $answer->getOrder()) {
810 $aggregated_info_for_answer[
'count_checked']++;
813 $aggregated_info_for_answer[
'count_unchecked'] =
814 ceil(count($relevant_answers_chosen) / count($answers_defined_on_question))
815 - $aggregated_info_for_answer[
'count_checked'];
817 $aggregate[] = $aggregated_info_for_answer;
829 $tpl =
new ilTemplate(
'tpl.il_as_aggregated_answers_table.html',
true,
true,
"Modules/TestQuestionPool");
839 foreach ($aggregate as $line_data) {
850 $feedbackOutputRequired =
false;
852 switch ($this->
object->getSpecificFeedbackSetting()) {
854 $feedbackOutputRequired =
true;
858 if (strcmp((
string) $user_solution, $answer_id) == 0) {
859 $feedbackOutputRequired =
true;
864 if ($this->
object->getAnswer($answer_id)->getPoints() > 0) {
865 $feedbackOutputRequired =
true;
870 if ($feedbackOutputRequired) {
871 $fb = $this->
object->feedbackOBJ->getSpecificAnswerFeedbackTestPresentation($this->
object->getId(), 0, $answer_id);
873 $template->setCurrentBlock(
"feedback");
875 $template->parseCurrentBlock();
886 foreach ($agg as $ans) {
888 'answer' => $ans[
'answertext'],
889 'frequency' => $ans[
'count_checked']
900 $choices->setQuestionObject($this->
object);
901 $choices->setValues($this->
object->getAnswers());
911 $values = $input->getValues();
913 foreach ($this->
object->getAnswers() as $index => $answer) {
915 $points = (float) str_replace(
',',
'.', $values[$index]->getPoints());
916 $answer->setPoints($points);
isTestPresentationContext()
hasCorrectSolution($activeId, $passIndex)
populateQuestionSpecificFormPart(\ilPropertyFormGUI $form, bool $is_singleline=false)
generateCorrectnessIconsForCorrectness(int $correctness)
aggregateAnswers($relevant_answers_chosen, $answers_defined_on_question)
setCurrentBlock(string $blockname=self::DEFAULT_BLOCK)
Sets the template to the given block.
writeAnswerSpecificPostData(ilPropertyFormGUI $form)
Extracts the answer specific values from $_POST and applies them to the data object.
Class for answers with a binary state indicator.
populateInlineFeedback($template, $answer_id, $user_solution)
static getImagePath(string $img, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
addBasicQuestionFormProperties(ilPropertyFormGUI $form)
renderAggregateView($aggregate)
parseCurrentBlock(string $blockname=self::DEFAULT_BLOCK)
Parses the given block.
const CSS_CLASS_FEEDBACK_CORRECT
ilGlobalPageTemplate $tpl
getSpecificFeedbackOutput(array $user_solution)
getAnswersFrequency($relevantAnswers, $questionIndex)
populateTaxonomyFormSection(ilPropertyFormGUI $form)
generateCorrectness(string $user_solution, string $answer_id, float $answer_points, float $maximum_points)
addQuestionFormCommandButtons(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, bool $show_inline_feedback=true)
Get the question solution output.
getTestOutput($active_id, $pass, $is_postponed=false, $use_post_solutions=false, $show_feedback=false)
writeQuestionGenericPostData()
getPreview($show_question_only=false, $showInlineFeedback=false)
getAfterParticipationSuppressionAnswerPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
Class for single choice questions.
writePostData(bool $always=false)
{}
getAfterParticipationSuppressionQuestionPostVars()
Returns a list of postvars which will be suppressed in the form output when used in scoring adjustmen...
populateAnswerSpecificFormPart(\ilPropertyFormGUI $form, bool $is_singleline=false)
removechoice()
Remove an answer.
static getHtmlPath(string $relative_path)
get url of path
const CSS_CLASS_FEEDBACK_WRONG
Basic GUI class for assessment questions.
populateCorrectionsFormProperties(ilPropertyFormGUI $form)
saveTaxonomyAssignments()
addchoice()
Add a new answer.
getILIASPage(string $html="")
Returns the ILIAS Page around a question.
saveCorrectionsFormProperties(ilPropertyFormGUI $form)
outQuestionPage($a_temp_var, $a_postponed=false, $active_id="", $html="", $inlineFeedbackEnabled=false)
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
cleanupAnswerText(array $answer_text, bool $is_rte)
sk - 12.05.2023: This is one more of those that we need, but don't want.
isRenderPurposePrintPdf()
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...
__construct($id=-1)
assSingleChoiceGUI constructor
editQuestion($checkonly=false)
Creates an output of the edit form for the question.
removeimagechoice()
Remove an image.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getAggregatedAnswersView(array $relevant_answers)
Returns an html string containing a question specific representation of the answers so far given in t...
getEditAnswersSingleLine($checkonly=false)
Get the single/multiline editing of answers.
setVariable(string $variable, $value='')
Sets the given variable to the given value.
uploadchoice()
Upload an image.
renderSolutionOutput(mixed $user_solutions, int $active_id, ?int $pass, bool $graphical_output=false, bool $result_output=false, bool $show_question_only=true, bool $show_feedback=false, bool $show_correct_solution=false, bool $show_manual_scoring=false, bool $show_question_text=true, bool $show_autosave_title=false, bool $show_inline_feedback=false,)
writeQuestionSpecificPostData(ilPropertyFormGUI $form)
Extracts the question specific values from $_POST and applies them to the data object.
renderPurposeSupportsFormHtml()
getGenericFeedbackOutput(int $active_id, ?int $pass)