48 $this->ui_factory =
$DIC->ui()->factory();
49 $this->ui_renderer =
$DIC->ui()->renderer();
53 $this->
object->loadFromDb(
$id);
59 $this->
ctrl->setParameterByClass(ilLocalUnitConfigurationGUI::class,
'q_id', $this->
object->getId());
60 $ilTabs->
addTarget(
'units', $this->
ctrl->getLinkTargetByClass(ilLocalUnitConfigurationGUI::class,
''),
'',
'illocalunitconfigurationgui');
66 $suggest_range_for_result = $this->request_data_collector->string(
'suggest_range_for');
71 $this->
editQuestion(
false,
null, $suggest_range_for_result);
79 $hasErrors = (!$always) ? $this->
editQuestion(
true) :
false;
82 $this->
object->setTitle($this->request_data_collector->string(
'title'));
83 $this->
object->setAuthor($this->request_data_collector->string(
'author'));
84 $this->
object->setComment($this->request_data_collector->string(
'comment'));
85 $this->
object->setQuestion($this->request_data_collector->string(
'question'));
87 $this->
object->parseQuestionText();
91 foreach ($this->request_data_collector->getParsedBody() as $key => $value) {
92 if (preg_match(
"/^unit_(\\\$v\d+)$/", $key, $matches)) {
93 array_push($found_vars, $matches[1]);
95 if (preg_match(
"/^unit_(\\\$r\d+)$/", $key, $matches)) {
96 array_push($found_results, $matches[1]);
106 if (!$this->
object->checkForDuplicateResults()) {
111 foreach ($found_vars as $variable) {
112 if ($this->
object->getVariable($variable) !=
null) {
113 $unit = $this->request_data_collector->int(
"unit_{$variable}");
116 $this->request_data_collector->float(
"range_min_{$variable}") ?? 0.0,
117 $this->request_data_collector->float(
"range_max_{$variable}") ?? 0.0,
118 $unit !==
null ? $this->object->getUnitrepository()->getUnit(
121 $this->request_data_collector->float(
"precision_{$variable}"),
122 $this->request_data_collector->float(
"intprecision_{$variable}")
124 $this->
object->addVariable($varObj);
129 $tmp_quest_vars = [];
130 foreach ($found_results as $result) {
131 $tmp_res_match = preg_match_all(
133 $this->request_data_collector->string(
"formula_{$result}"),
136 $tmp_form_vars = array_merge($tmp_form_vars, $form_vars[0]);
138 $tmp_que_match = preg_match_all(
140 $this->request_data_collector->string(
'question'),
143 $tmp_quest_vars = array_merge($tmp_quest_vars, $quest_vars[0]);
145 $result_has_undefined_vars = array_diff($tmp_form_vars, $found_vars);
146 $question_has_unused_vars = array_diff($tmp_quest_vars, $tmp_form_vars);
148 if ($result_has_undefined_vars !== [] || $question_has_unused_vars !== []) {
150 if (count($result_has_undefined_vars) > 0) {
151 $error_message .= $this->
lng->txt(
"res_contains_undef_var") .
'<br>';
153 if (count($question_has_unused_vars) > 0) {
154 $error_message .= $this->
lng->txt(
"que_contains_unused_var");
158 $this->tpl->setOnScreenMessage(
'failure', $error_message);
161 foreach ($found_results as $result) {
162 if ($this->
object->getResult($result) !=
null) {
163 $unit = $this->request_data_collector->int(
"unit_{$result}");
166 $this->request_data_collector->float(
"range_min_{$result}") ?? 0.0,
167 $this->request_data_collector->float(
"range_max_{$result}") ?? 0.0,
168 $this->request_data_collector->float(
"tolerance_{$result}") ?? 0.0,
169 $unit !==
null ? $this->object->getUnitrepository()->getUnit(
172 $this->request_data_collector->string(
"formula_{$result}"),
173 $this->request_data_collector->float(
"points_{$result}"),
174 $this->request_data_collector->float(
"precision_{$result}"),
175 $this->request_data_collector->int(
"rating_advanced_{$result}") !== 1,
176 $this->request_data_collector->int(
"rating_advanced_{$result}") === 1 ? $this->request_data_collector->float(
"rating_sign_{$result}") :
null,
177 $this->request_data_collector->int(
"rating_advanced_{$result}") === 1 ? $this->request_data_collector->float(
"rating_value_{$result}") :
null,
178 $this->request_data_collector->int(
"rating_advanced_{$result}") === 1 ? $this->request_data_collector->float(
"rating_unit_{$result}") :
null,
179 $this->request_data_collector->int(
"result_type_{$result}")
181 $this->
object->addResult($resObj);
182 $available_units = $this->request_data_collector->intArray(
"units_{$result}");
183 if (!empty($available_units)) {
184 $this->
object->addResultUnits($resObj, $available_units);
188 if ($checked ===
false) {
202 bool $checkonly =
false,
203 ?
bool $is_save_cmd =
null,
204 ?
string $suggest_range_for_result =
null
209 $this->editForm = $form;
211 $form->setFormAction($this->
ctrl->getFormAction($this));
213 $form->setMultipart(
false);
214 $form->setTableWidth(
'100%');
215 $form->setId(
'assformulaquestion');
220 $question = $form->getItemByPostVar(
'question');
221 $question->setInfo($this->
lng->txt(
'fq_question_desc'));
223 $variables = $this->
object->getVariables();
224 $categorized_units = $this->
object->getUnitrepository()->getCategorizedUnits();
225 $result_units = $this->
object->getAllResultUnits();
229 $new_category =
false;
230 foreach ($categorized_units as $item) {
235 if ($category_name != $item->getDisplayString()) {
236 $new_category =
true;
237 $category_name = $item->getDisplayString();
241 $unit_options[$item->getId()] = $item->getDisplayString() . ($new_category ?
' (' . $category_name .
')' :
'');
242 $new_category =
false;
245 if ($variables !== []) {
249 if ($num_v1 > $num_v2) {
251 } elseif ($num_v1 < $num_v2) {
258 foreach ($variables as $variable) {
263 $variable_header->setTitle(sprintf($this->
lng->txt(
'variable_x'), $variable->getVariable()));
265 $range_min =
new ilNumberInputGUI($this->
lng->txt(
'range_min'),
'range_min_' . $variable->getVariable());
266 $range_min->allowDecimals(
true);
267 $range_min->setSize(3);
268 $range_min->setRequired(
true);
269 $range_min->setValue($variable->getRangeMin());
271 $range_max =
new ilNumberInputGUI($this->
lng->txt(
'range_max'),
'range_max_' . $variable->getVariable());
272 $range_max->allowDecimals(
true);
273 $range_max->setSize(3);
274 $range_max->setRequired(
true);
275 $range_max->setValue($variable->getRangeMax());
277 $units =
new ilSelectInputGUI($this->
lng->txt(
'unit'),
'unit_' . $variable->getVariable());
278 $units->setOptions([0 => $this->
lng->txt(
'no_selection')] + $unit_options);
279 if (is_object($variable->getUnit())) {
280 $units->setValue($variable->getUnit()->getId());
283 $precision =
new ilNumberInputGUI($this->
lng->txt(
'precision'),
'precision_' . $variable->getVariable());
284 $precision->setRequired(
true);
285 $precision->setSize(3);
286 $precision->setMinValue(0);
287 $precision->setValue($variable->getPrecision());
288 $precision->setInfo($this->
lng->txt(
'fq_precision_info'));
290 $intprecision =
new ilNumberInputGUI($this->
lng->txt(
'intprecision'),
'intprecision_' . $variable->getVariable());
291 $intprecision->setSize(3);
292 $intprecision->setMinValue(1);
293 $intprecision->setValue($variable->getIntprecision());
294 $intprecision->setInfo($this->
lng->txt(
'intprecision_info'));
296 $form->addItem($variable_header);
297 $form->addItem($range_min);
298 $form->addItem($range_max);
299 $form->addItem($units);
300 $form->addItem($precision);
301 $form->addItem($intprecision);
306 $results = $this->
object->getResults();
311 if ($num_r1 > $num_r2) {
313 } elseif ($num_r1 < $num_r2) {
322 $result_header->setTitle(sprintf($this->
lng->txt(
'result_x'), $result->getResult()));
324 $formula =
new ilTextInputGUI($this->
lng->txt(
'formula'),
'formula_' . $result->getResult());
325 $formula->setInfo($this->
lng->txt(
'fq_formula_desc'));
326 $formula->setRequired(
true);
327 $formula->setSize(50);
328 $formula->setValue($result->getFormula());
329 $formula->setSuffix(
' = ' . $result->getResult());
332 $suggest_range_for_result !==
null &&
333 $suggest_range_for_result === $result->getResult() &&
334 strlen($result->substituteFormula($variables,
$results))
336 $result->suggestRange($variables,
$results);
339 $range_min =
new ilNumberInputGUI($this->
lng->txt(
'range_min'),
'range_min_' . $result->getResult());
340 $range_min->allowDecimals(
true);
341 $range_min->setSize(3);
342 $range_min->setRequired(
true);
343 $range_min->setValue($result->getRangeMin());
345 $range_max =
new ilNumberInputGUI($this->
lng->txt(
'range_max'),
'range_max_' . $result->getResult());
346 $range_max->allowDecimals(
true);
347 $range_max->setSize(3);
348 $range_max->setRequired(
true);
349 $range_max->setValue($result->getRangeMax());
353 $precision =
new ilNumberInputGUI($this->
lng->txt(
'precision'),
'precision_' . $result->getResult());
354 $precision->setRequired(
true);
355 $precision->setSize(3);
356 $precision->setMinValue(0);
357 $precision->setInfo($this->
lng->txt(
'fq_precision_info'));
358 $precision->setValue($result->getPrecision());
360 $tolerance =
new ilNumberInputGUI($this->
lng->txt(
'tolerance'),
'tolerance_' . $result->getResult());
361 $tolerance->setSize(3);
362 $tolerance->setMinValue(0);
363 $tolerance->setMaxValue(100);
364 $tolerance->allowDecimals(
true);
365 $tolerance->setInfo($this->
lng->txt(
'tolerance_info'));
366 $tolerance->setValue($result->getTolerance());
369 $suggest_range_button->setHtml(
370 $this->ui_renderer->render(
371 $this->ui_factory->button()->standard(
372 $this->lng->txt(
'suggest_range'),
374 )->withAdditionalOnLoadCode(
375 $this->getSuggestRangeOnLoadCode($result->getResult())
380 $sel_result_units =
new ilSelectInputGUI($this->
lng->txt(
'unit'),
'unit_' . $result->getResult());
381 $sel_result_units->setOptions([0 => $this->
lng->txt(
'no_selection')] + $unit_options);
382 $sel_result_units->setInfo($this->
lng->txt(
'result_unit_info'));
383 if (is_object($result->getUnit())) {
384 $sel_result_units->setValue($result->getUnit()->getId());
388 $mc_result_units->setOptions($unit_options);
389 $mc_result_units->setInfo($this->
lng->txt(
'result_units_info'));
390 $selectedvalues = [];
391 foreach ($unit_options as $unit_id =>
$txt) {
392 if ($this->
hasResultUnit($result, $unit_id, $result_units)) {
393 $selectedvalues[] = $unit_id;
396 $mc_result_units->setValue($selectedvalues);
398 $result_type =
new ilRadioGroupInputGUI($this->
lng->txt(
'result_type_selection'),
'result_type_' . $result->getResult());
399 $result_type->setRequired(
true);
402 $no_type->setInfo($this->
lng->txt(
'fq_no_restriction_info'));
405 $result_dec->setInfo($this->
lng->txt(
'result_dec_info'));
408 $result_frac->setInfo($this->
lng->txt(
'result_frac_info'));
410 $result_co_frac =
new ilRadioOption($this->
lng->txt(
'result_co_frac'),
'3');
411 $result_co_frac->setInfo($this->
lng->txt(
'result_co_frac_info'));
413 $result_type->addOption($no_type);
414 $result_type->addOption($result_dec);
415 $result_type->addOption($result_frac);
416 $result_type->addOption($result_co_frac);
417 $result_type->setValue(strlen($result->getResultType()) ? $result->getResultType() : 0);
419 $points =
new ilNumberInputGUI($this->
lng->txt(
'points'),
'points_' . $result->getResult());
420 $points->allowDecimals(
true);
421 $points->setRequired(
true);
423 $points->setMinValue(0);
424 $points->setValue(strlen($result->getPoints()) ? $result->getPoints() : 1);
426 $rating_type =
new ilCheckboxInputGUI($this->
lng->txt(
'advanced_rating'),
'rating_advanced_' . $result->getResult());
427 $rating_type->setValue(1);
428 $rating_type->setInfo($this->
lng->txt(
'advanced_rating_info'));
432 if (!$advanced_rating) {
433 $rating_type->setDisabled(
true);
434 $rating_type->setChecked(
false);
436 $rating_type->setChecked(strlen($result->getRatingSimple()) && $result->getRatingSimple() ?
false :
true);
440 $sign =
new ilNumberInputGUI($this->
lng->txt(
'rating_sign'),
'rating_sign_' . $result->getResult());
441 $sign->setRequired(
true);
443 $sign->setMinValue(0);
444 $sign->setValue($result->getRatingSign());
445 $rating_type->addSubItem($sign);
447 $value =
new ilNumberInputGUI($this->
lng->txt(
'rating_value'),
'rating_value_' . $result->getResult());
448 $value->setRequired(
true);
450 $value->setMinValue(0);
451 $value->setValue($result->getRatingValue());
452 $rating_type->addSubItem($value);
454 $unit =
new ilNumberInputGUI($this->
lng->txt(
'rating_unit'),
'rating_unit_' . $result->getResult());
455 $unit->setRequired(
true);
457 $unit->setMinValue(0);
458 $unit->setValue($result->getRatingUnit());
459 $rating_type->addSubItem($unit);
462 $rating_type->addSubItem($info_text);
464 $form->addItem($result_header);
465 $form->addItem($formula);
466 $form->addItem($range_min);
467 $form->addItem($range_max);
468 $form->addItem($suggest_range_button);
469 $form->addItem($precision);
470 $form->addItem($tolerance);
471 $form->addItem($sel_result_units);
472 $form->addItem($mc_result_units);
473 $form->addItem($result_type);
474 $form->addItem($points);
475 $form->addItem($rating_type);
478 $defined_result_vars = [];
480 $defined_result_res = [];
482 foreach ($variables as $key =>
$object) {
483 $quest_vars[$key] = $key;
487 $result_vars[$key] = $key;
494 $formula = $tmp_result->getFormula() ??
'';
496 preg_match_all(
"/([$][v][0-9]*)/", $formula, $form_vars);
497 preg_match_all(
"/([$][r][0-9]*)/", $formula, $form_res);
498 foreach ($form_vars[0] as $res_var) {
499 $defined_result_vars[$res_var] = $res_var;
502 foreach ($form_res[0] as $res_res) {
503 $defined_result_res[$res_res] = $res_res;
508 $result_has_undefined_vars = [];
509 $question_has_unused_vars = [];
510 $result_has_undefined_res = [];
512 if (is_array($quest_vars) && count($quest_vars) > 0) {
513 $result_has_undefined_vars = array_diff($defined_result_vars, $quest_vars);
514 $question_has_unused_vars = array_diff($quest_vars, $defined_result_vars);
517 if (is_array($result_vars) && count($result_vars) > 0) {
518 $result_has_undefined_res = array_diff($defined_result_res, $result_vars);
522 if ($result_has_undefined_vars !== [] || $question_has_unused_vars !== []) {
523 if (count($result_has_undefined_vars) > 0) {
524 $error_message .= $this->
lng->txt(
"res_contains_undef_var") .
'<br>';
526 if (count($question_has_unused_vars) > 0) {
527 $error_message .= $this->
lng->txt(
"que_contains_unused_var") .
'<br>';
532 $this->tpl->setOnScreenMessage(
'failure', $error_message);
536 if (is_array($result_has_undefined_res) && count($result_has_undefined_res) > 0) {
537 $error_message .= $this->
lng->txt(
"res_contains_undef_res") .
'<br>';
541 if ($save && !$checked) {
542 $this->tpl->setOnScreenMessage(
'failure', $error_message);
547 $form->addCommandButton(
'parseQuestion', $this->
lng->txt(
'parseQuestion'));
548 $form->addCommandButton(
'saveReturn', $this->
lng->txt(
'save_return'));
549 $form->addCommandButton(
'save', $this->
lng->txt(
'save'));
556 foreach ($this->request_data_collector->getParsedBody() as $key => $value) {
557 if (preg_match(
"/^unit_(\\\$v\d+)$/", $key, $matches)) {
558 array_push($found_vars, $matches[1]);
560 if (preg_match(
"/^unit_(\\\$r\d+)$/", $key, $matches)) {
561 array_push($found_results, $matches[1]);
566 foreach ($this->request_data_collector->getParsedBody() as $key => $value) {
567 $item = $form->getItemByPostVar($key);
568 if ($item !==
null) {
569 switch (get_class($item)) {
570 case 'ilDurationInputGUI':
571 $item->setHours($value[
'hh']);
572 $item->setMinutes($value[
'mm']);
573 $item->setSeconds($value[
'ss']);
576 $item->setValue($value);
581 $check = array_merge($found_vars, $found_results);
582 foreach ((array) $form->getItems() as $item) {
583 $postvar = $item->getPostVar();
584 if (preg_match(
"/_\\\$[r|v]\d+/", $postvar, $matches)) {
585 $k = substr(array_shift($matches), 1);
586 if (!in_array($k,
$check)) {
587 $form->removeItemByPostVar($postvar);
591 $variables = array_filter($variables, fn($k, $v) => in_array($v,
$check), ARRAY_FILTER_USE_BOTH);
594 $errors = !$form->checkInput();
596 $custom_errors =
false;
597 if ($variables !== []) {
598 foreach ($variables as $variable) {
599 $min_range = $form->getItemByPostVar(
'range_min_' . $variable->getVariable());
600 $max_range = $form->getItemByPostVar(
'range_max_' . $variable->getVariable());
601 if ($min_range->getValue() > $max_range->getValue()) {
602 $min_range->setAlert($this->
lng->txt(
'err_range'));
603 $max_range->setAlert($this->
lng->txt(
'err_range'));
604 $custom_errors =
true;
606 $intPrecision = $form->getItemByPostVar(
'intprecision_' . $variable->getVariable());
607 $decimal_spots = $form->getItemByPostVar(
'precision_' . $variable->getVariable());
608 if ($decimal_spots->getValue() == 0
609 && $min_range->getValue() !==
null
610 && $max_range->getValue() !==
null
611 && !$variable->isIntPrecisionValid(
612 $intPrecision->getValue(),
613 $min_range->getValue(),
614 $max_range->getValue()
617 $intPrecision->setAlert($this->
lng->txt(
'err_division'));
618 $custom_errors =
true;
628 $min_range = $form->getItemByPostVar(
'range_min_' . $result->getResult());
629 $max_range = $form->getItemByPostVar(
'range_max_' . $result->getResult());
630 if ($min_range->getValue() > $max_range->getValue()) {
631 $min_range->setAlert($this->
lng->txt(
'err_range'));
632 $max_range->setAlert($this->
lng->txt(
'err_range'));
633 $custom_errors =
true;
637 $formula = $form->getItemByPostVar(
'formula_' . $result->getResult());
638 if (strpos($formula->getValue(), $result->getResult()) !==
false) {
639 $formula->setAlert($this->
lng->txt(
'errRecursionInResult'));
640 $custom_errors =
true;
643 $result_unit = $form->getItemByPostVar(
'unit_' . $result->getResult());
644 $rating_advanced = $form->getItemByPostVar(
'rating_advanced_' . $result->getResult());
645 if (((
int) $result_unit->getValue() <= 0) && $rating_advanced->getChecked()) {
646 unset(
$_POST[
'rating_advanced_' . $result->getResult()]);
647 $rating_advanced->setDisabled(
true);
648 $rating_advanced->setChecked(
false);
649 $rating_advanced->setAlert($this->
lng->txt(
'err_rating_advanced_not_allowed'));
650 $custom_errors =
true;
651 } elseif ($rating_advanced->getChecked()) {
652 $rating_sign = $form->getItemByPostVar(
'rating_sign_' . $result->getResult());
653 $rating_value = $form->getItemByPostVar(
'rating_value_' . $result->getResult());
654 $rating_unit = $form->getItemByPostVar(
'rating_unit_' . $result->getResult());
656 $percentage = $rating_sign->getValue() + $rating_value->getValue() + $rating_unit->getValue();
657 if ($percentage != 100) {
658 $rating_advanced->setAlert($this->
lng->txt(
'err_wrong_rating_advanced'));
659 $custom_errors =
true;
663 preg_match_all(
"/([$][v][0-9]*)/", $formula->getValue(), $form_vars);
664 $result_has_undefined_vars = array_diff($form_vars[0], $found_vars);
665 if (count($result_has_undefined_vars)) {
667 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'res_contains_undef_var'));
672 if ($custom_errors && !$errors) {
674 $this->tpl->setOnScreenMessage(
'failure', $this->
lng->txt(
'form_input_not_valid'));
676 foreach ($this->request_data_collector->getParsedBody() as $key => $value) {
677 $item = $form->getItemByPostVar($key);
678 if ($item !==
null) {
679 switch (get_class($item)) {
680 case 'ilDurationInputGUI':
681 $item->setHours($value[
'hh']);
682 $item->setMinutes($value[
'mm']);
683 $item->setSeconds($value[
'ss']);
686 $item->setValue($value);
703 return static function (
$id) use ($result):
string {
704 return "document.getElementById('$id').addEventListener('click', "
706 .
' e.target.setAttribute("name", "cmd[suggestRange]");'
707 .
' let input = document.createElement("input");'
708 .
' input.type = "hidden";'
709 .
' input.name = "suggest_range_for";'
710 .
" input.value = '$result';"
711 .
' e.target.form.appendChild(input);'
712 .
' e.target.form.requestSubmit(e.target);'
719 if (array_key_exists($result->getResult(), $resultunits)) {
720 if (array_key_exists($unit_id, $resultunits[$result->getResult()])) {
736 $resultunit = $result->getUnit();
744 if (is_object($resultunit)) {
753 $this->setAdditionalContentEditingModeFromPost();
754 $this->writePostData();
755 $this->addSaveOnEnterOnLoadCode();
756 $this->setTestSpecificProperties();
757 $this->editQuestion();
765 $title = $this->request_data_collector->string(
'title');
766 $author = $this->request_data_collector->string(
'author');
767 $question = $this->request_data_collector->string(
'question');
769 if (empty($title) || empty($author) || empty($question)) {
770 $this->addErrorMessage($this->
lng->txt(
'fill_out_all_required_fields'));
780 bool $graphical_output =
false,
781 bool $result_output =
false,
782 bool $show_question_only =
true,
783 bool $show_feedback =
false,
784 bool $show_correct_solution =
false,
785 bool $show_manual_scoring =
false,
786 bool $show_question_text =
true,
787 bool $show_inline_feedback =
true
790 if ($pass !==
null) {
791 $user_solution = $this->
object->getVariableSolutionValuesForPass($active_id, $pass);
793 $user_solution = array_reduce(
794 $this->
object->fetchAllVariables($this->object->getQuestion()),
802 if (($active_id > 0) && (!$show_correct_solution)) {
803 $user_solution[
'active_id'] = $active_id;
804 $user_solution[
'pass'] = $pass;
805 $solutions = $this->
object->getSolutionValues($active_id, $pass);
806 foreach ($solutions as $solution_value) {
807 if (preg_match(
'/^(\$v\d+)$/', $solution_value[
'value1'], $matches)) {
808 $user_solution[$matches[1]] = $solution_value[
'value2'];
809 } elseif (preg_match(
'/^(\$r\d+)$/', $solution_value[
'value1'], $matches)) {
810 if (!array_key_exists($matches[1], $user_solution)) {
811 $user_solution[$matches[1]] = [];
813 $user_solution[$matches[1]][
"value"] = $solution_value[
'value2'];
814 } elseif (preg_match(
'/^(\$r\d+)_unit$/', $solution_value[
'value1'], $matches)) {
815 if (!array_key_exists($matches[1], $user_solution)) {
816 $user_solution[$matches[1]] = [];
818 $user_solution[$matches[1]][
'unit'] = $solution_value[
'value2'];
821 } elseif ($active_id !== 0) {
822 $user_solution = $this->
object->getBestSolution($this->
object->getSolutionValues($active_id, $pass));
823 } elseif (is_object($this->getPreviewSession())) {
824 $solutionValues = [];
825 $participants_solution = $this->getPreviewSession()->getParticipantsSolution();
826 if (is_array($participants_solution)) {
827 foreach ($participants_solution as $val1 => $val2) {
828 $solutionValues[] = [
'value1' => $val1,
'value2' => $val2];
831 $user_solution = $this->
object->getBestSolution($solutionValues);
834 return $this->renderSolutionOutput(
842 $show_correct_solution,
843 $show_manual_scoring,
846 $show_inline_feedback
851 mixed $user_solutions,
854 bool $graphical_output =
false,
855 bool $result_output =
false,
856 bool $show_question_only =
true,
857 bool $show_feedback =
false,
858 bool $show_correct_solution =
false,
859 bool $show_manual_scoring =
false,
860 bool $show_question_text =
true,
861 bool $show_autosave_title =
false,
862 bool $show_inline_feedback =
false,
864 $template = new
ilTemplate(
"tpl.il_as_qpl_formulaquestion_output_solution.html",
true,
true,
'components/ILIAS/TestQuestionPool');
865 $correctness_icons = [
866 'correct' => $this->generateCorrectnessIconsForCorrectness(self::CORRECTNESS_OK),
867 'not_correct' => $this->generateCorrectnessIconsForCorrectness(self::CORRECTNESS_NOT_OK)
869 $questiontext = $this->
object->substituteVariables($user_solutions, $graphical_output,
true, $result_output, $correctness_icons);
870 $template->
setVariable(
"QUESTIONTEXT", $this->renderLatex(
873 $questionoutput = $template->get();
874 $solutiontemplate =
new ilTemplate(
"tpl.il_as_tst_solution_output.html",
true,
true,
"components/ILIAS/TestQuestionPool");
875 $feedback = ($show_feedback) ? $this->getGenericFeedbackOutput((
int) $active_id, $pass) :
"";
876 if (strlen($feedback)) {
878 $this->hasCorrectSolution($active_id, $pass) ?
881 $solutiontemplate->setVariable(
"ILC_FB_CSS_CLASS", $cssClass);
882 $solutiontemplate->setVariable(
"FEEDBACK", $this->renderLatex(
886 $solutiontemplate->setVariable(
"SOLUTION_OUTPUT", $questionoutput);
888 $solutionoutput = $solutiontemplate->get();
889 if (!$show_question_only) {
890 $solutionoutput = $this->getILIASPage($solutionoutput);
892 return $solutionoutput;
896 bool $show_question_only =
false,
897 bool $show_inline_feedback =
false
900 if (is_object($this->getPreviewSession())) {
901 $solutions = $this->getPreviewSession()->getParticipantsSolution() ?? [];
902 foreach ($solutions as $val1 => $val2) {
903 if (preg_match(
'/^(\$v\d+)$/', $val1, $matches)) {
904 $user_solution[$matches[1]] = $val2;
905 } elseif (preg_match(
'/^(\$r\d+)$/', $val1, $matches)) {
906 if (!array_key_exists($matches[1], $user_solution)) {
907 $user_solution[$matches[1]] = [];
909 $user_solution[$matches[1]][
'value'] = $val2;
910 } elseif (preg_match(
'/^(\$r\d+)_unit$/', $val1, $matches)) {
911 if (!array_key_exists($matches[1], $user_solution)) {
912 $user_solution[$matches[1]] = [];
914 $user_solution[$matches[1]][
'unit'] = $val2;
917 if (preg_match(
'/^(\$r\d+)/', $val1, $matches) && !isset($user_solution[$matches[1]][
'result_type'])) {
923 if (!$this->
object->hasRequiredVariableSolutionValues($user_solution)) {
924 $user_solution = $this->
object->getInitialVariableSolutionValues();
926 if (is_object($this->getPreviewSession())) {
927 $this->getPreviewSession()->setParticipantsSolution($user_solution);
931 $template =
new ilTemplate(
"tpl.il_as_qpl_formulaquestion_output.html",
true,
true,
'components/ILIAS/TestQuestionPool');
932 if (is_object($this->getPreviewSession())) {
933 $questiontext = $this->
object->substituteVariables($user_solution);
935 $questiontext = $this->
object->substituteVariables([]);
937 $template->setVariable(
"QUESTIONTEXT", $this->renderLatex(
940 $questionoutput = $template->get();
941 if (!$show_question_only) {
943 $questionoutput = $this->getILIASPage($questionoutput);
945 return $questionoutput;
951 bool $is_question_postponed =
false,
952 array|
bool $user_post_solutions =
false,
953 bool $show_specific_inline_feedback =
false
955 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'enter_valid_values'));
959 $solutions = $this->
object->getTestOutputSolutions($active_id, $pass);
960 $actualPassIndex =
null;
961 if ($this->
object->getTestPresentationConfig()->isSolutionInitiallyPrefilled()) {
964 foreach ($solutions as $idx => $solution_value) {
965 if (preg_match(
'/^(\$v\d+)$/', $solution_value[
'value1'], $matches)) {
966 if ($this->
object->getTestPresentationConfig()->isSolutionInitiallyPrefilled()) {
967 $this->
object->saveCurrentSolution($active_id, $actualPassIndex, $matches[1], $solution_value[
'value2'],
true);
969 $user_solution[$matches[1]] = $solution_value[
'value2'];
970 } elseif (preg_match(
'/^(\$r\d+)$/', $solution_value[
'value1'], $matches)) {
971 if (!array_key_exists($matches[1], $user_solution)) {
972 $user_solution[$matches[1]] = [];
974 $user_solution[$matches[1]][
'value'] = $solution_value[
'value2'];
975 } elseif (preg_match(
'/^(\$r\d+)_unit$/', $solution_value[
'value1'], $matches)) {
976 if (!array_key_exists($matches[1], $user_solution)) {
977 $user_solution[$matches[1]] = [];
979 $user_solution[$matches[1]][[
'unit']] = $solution_value[
'value2'];
981 if (preg_match(
'/^(\$r\d+)/', $solution_value[
'value1'], $matches) && !isset($user_solution[$matches[1]][
'result_type'])) {
988 $solutions = $this->
object->getSolutionValues($active_id, $pass,
true);
989 foreach ($solutions as $idx => $solution_value) {
990 if (preg_match(
'/^(\$v\d+)$/', $solution_value[
'value1'], $matches)) {
991 $user_solution[$matches[1]] = $solution_value[
'value2'];
995 if ($user_solution === []) {
996 $user_solution = $this->
object->getVariableSolutionValuesForPass($active_id, $pass);
1000 $template =
new ilTemplate(
"tpl.il_as_qpl_formulaquestion_output.html",
true,
true,
'components/ILIAS/TestQuestionPool');
1002 $questiontext = $this->
object->substituteVariables($user_solution);
1004 $template->setVariable(
"QUESTIONTEXT", $this->renderLatex(
1008 $questionoutput = $template->get();
1009 $pageoutput = $this->outQuestionPage(
"", $is_question_postponed, $active_id, $questionoutput);
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
setVariable($variable, $value='')
Sets a variable value.
Builds a Color from either hex- or rgb values.
populateTaxonomyFormSection(ilPropertyFormGUI $form)
editQuestion(bool $checkonly=false, ?bool $is_save_cmd=null)
addBasicQuestionFormProperties(ilPropertyFormGUI $form)
renderEditForm(ilPropertyFormGUI $form)
setTestSpecificProperties()
setAdditionalContentEditingModeFromPost()
resetSavedPreviewSession()
saveTaxonomyAssignments()
addErrorMessage(string $errormessage)
const CSS_CLASS_FEEDBACK_WRONG
const CSS_CLASS_FEEDBACK_CORRECT
static getInstance($identifier)
This class represents a non editable value in a property form.
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test.
This class represents an option in a radio group.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
addTarget(string $a_text, string $a_link, $a_cmd="", $a_cmdClass="", string $a_frame="", bool $a_activate=false, bool $a_dir_text=false)
special template class to simplify handling of ITX/PEAR
This class represents a text property in a property form.
An entity that renders components to a string output.
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc