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;
    85         $this->
object->setTitle($this->request_data_collector->string(
'title'));
    86         $this->
object->setAuthor($this->request_data_collector->string(
'author'));
    87         $this->
object->setComment($this->request_data_collector->string(
'comment'));
    88         $this->
object->setQuestion($this->request_data_collector->string(
'question'));
    90         $this->
object->parseQuestionText();
    94         foreach ($this->request_data_collector->getParsedBody() as $key => $value) {
    95             if (preg_match(
"/^unit_(\\\$v\d+)$/", $key, $matches)) {
    96                 array_push($found_vars, $matches[1]);
    98             if (preg_match(
"/^unit_(\\\$r\d+)$/", $key, $matches)) {
    99                 array_push($found_results, $matches[1]);
   109         if (!$this->
object->checkForDuplicateResults()) {
   114         foreach ($found_vars as $variable) {
   115             if ($this->
object->getVariable($variable) != null) {
   116                 $unit = $this->request_data_collector->int(
"unit_{$variable}");
   119                     $this->request_data_collector->float(
"range_min_{$variable}") ?? 0.0,
   120                     $this->request_data_collector->float(
"range_max_{$variable}") ?? 0.0,
   121                     $unit !== null ? $this->
object->getUnitrepository()->getUnit(
   124                     $this->request_data_collector->float(
"precision_{$variable}"),
   125                     $this->request_data_collector->float(
"intprecision_{$variable}")
   127                 $this->
object->addVariable($varObj);
   132         $tmp_quest_vars = [];
   133         foreach ($found_results as $result) {
   134             $tmp_res_match = preg_match_all(
   136                 $this->request_data_collector->string(
"formula_{$result}"),
   139             $tmp_form_vars = array_merge($tmp_form_vars, $form_vars[0]);
   141             $tmp_que_match = preg_match_all(
   143                 $this->request_data_collector->string(
'question'),
   146             $tmp_quest_vars = array_merge($tmp_quest_vars, $quest_vars[0]);
   148         $result_has_undefined_vars = array_diff($tmp_form_vars, $found_vars);
   149         $question_has_unused_vars = array_diff($tmp_quest_vars, $tmp_form_vars);
   151         if ($result_has_undefined_vars !== [] || $question_has_unused_vars !== []) {
   153             if (count($result_has_undefined_vars) > 0) {
   154                 $error_message .= $this->
lng->txt(
"res_contains_undef_var") . 
'<br>';
   156             if (count($question_has_unused_vars) > 0) {
   157                 $error_message .= $this->
lng->txt(
"que_contains_unused_var");
   161                 $this->tpl->setOnScreenMessage(
'failure', $error_message);
   164         foreach ($found_results as $result) {
   165             if ($this->
object->getResult($result) != null) {
   166                 $unit = $this->request_data_collector->int(
"unit_{$result}");
   169                     $this->request_data_collector->float(
"range_min_{$result}") ?? 0.0,
   170                     $this->request_data_collector->float(
"range_max_{$result}") ?? 0.0,
   171                     $this->request_data_collector->float(
"tolerance_{$result}") ?? 0.0,
   172                     $unit !== null ? $this->
object->getUnitrepository()->getUnit(
   175                     $this->request_data_collector->string(
"formula_{$result}"),
   176                     $this->request_data_collector->float(
"points_{$result}"),
   177                     $this->request_data_collector->float(
"precision_{$result}"),
   178                     $this->request_data_collector->int(
"rating_advanced_{$result}") !== 1,
   179                     $this->request_data_collector->int(
"rating_advanced_{$result}") === 1 ? $this->request_data_collector->float(
"rating_sign_{$result}") : null,
   180                     $this->request_data_collector->int(
"rating_advanced_{$result}") === 1 ? $this->request_data_collector->float(
"rating_value_{$result}") : null,
   181                     $this->request_data_collector->int(
"rating_advanced_{$result}") === 1 ? $this->request_data_collector->float(
"rating_unit_{$result}") : null,
   182                     $this->request_data_collector->int(
"result_type_{$result}")
   184                 $this->
object->addResult($result_object);
   185                 $this->
object->addResultUnits(
   187                     $this->request_data_collector->intArray(
"units_{$result}")
   191         if ($checked === 
false) {
   204         $ilUser = $DIC[
'ilUser'];
   206         $question_id = $this->
object->getId();
   208         $ilAssQuestionPreviewSession->setParticipantsSolution([]);
   212         bool $checkonly = 
false,
   213         ?
bool $is_save_cmd = null,
   214         ?
string $suggest_range_for_result = null
   219         $this->editForm = $form;
   221         $form->setFormAction($this->
ctrl->getFormAction($this));
   223         $form->setMultipart(
false);
   224         $form->setTableWidth(
'100%');
   225         $form->setId(
'assformulaquestion');
   230         $question = $form->getItemByPostVar(
'question');
   231         $question->setInfo($this->
lng->txt(
'fq_question_desc'));
   233         $variables = $this->
object->getVariables();
   234         $categorized_units = $this->
object->getUnitrepository()->getCategorizedUnits();
   235         $result_units = $this->
object->getAllResultUnits();
   239         $new_category = 
false;
   240         foreach ($categorized_units as $item) {
   245                 if ($category_name != $item->getDisplayString()) {
   246                     $new_category = 
true;
   247                     $category_name = $item->getDisplayString();
   251             $unit_options[$item->getId()] = $item->getDisplayString() . ($new_category ? 
' (' . $category_name . 
')' : 
'');
   252             $new_category = 
false;
   255         if ($variables !== []) {
   259                 if ($num_v1 > $num_v2) {
   261                 } elseif ($num_v1 < $num_v2) {
   268             foreach ($variables as $variable) {
   273                 $variable_header->setTitle(sprintf($this->
lng->txt(
'variable_x'), $variable->getVariable()));
   275                 $range_min = 
new ilNumberInputGUI($this->
lng->txt(
'range_min'), 
'range_min_' . $variable->getVariable());
   276                 $range_min->allowDecimals(
true);
   277                 $range_min->setSize(3);
   278                 $range_min->setRequired(
true);
   279                 $range_min->setValue($variable->getRangeMin());
   281                 $range_max = 
new ilNumberInputGUI($this->
lng->txt(
'range_max'), 
'range_max_' . $variable->getVariable());
   282                 $range_max->allowDecimals(
true);
   283                 $range_max->setSize(3);
   284                 $range_max->setRequired(
true);
   285                 $range_max->setValue($variable->getRangeMax());
   287                 $units = 
new ilSelectInputGUI($this->
lng->txt(
'unit'), 
'unit_' . $variable->getVariable());
   288                 $units->
setOptions([0 => $this->
lng->txt(
'no_selection')] + $unit_options);
   289                 if (is_object($variable->getUnit())) {
   290                     $units->setValue($variable->getUnit()->getId());
   293                 $precision = 
new ilNumberInputGUI($this->
lng->txt(
'precision'), 
'precision_' . $variable->getVariable());
   294                 $precision->setRequired(
true);
   295                 $precision->setSize(3);
   296                 $precision->setMinValue(0);
   297                 $precision->setValue($variable->getPrecision());
   298                 $precision->setInfo($this->
lng->txt(
'fq_precision_info'));
   300                 $intprecision = 
new ilNumberInputGUI($this->
lng->txt(
'intprecision'), 
'intprecision_' . $variable->getVariable());
   301                 $intprecision->setSize(3);
   302                 $intprecision->setMinValue(1);
   303                 $intprecision->setValue($variable->getIntprecision());
   304                 $intprecision->setInfo($this->
lng->txt(
'intprecision_info'));
   306                 $form->addItem($variable_header);
   307                 $form->addItem($range_min);
   308                 $form->addItem($range_max);
   309                 $form->addItem($units);
   310                 $form->addItem($precision);
   311                 $form->addItem($intprecision);
   316         $results = $this->
object->getResults();
   321                 if ($num_r1 > $num_r2) {
   323                 } elseif ($num_r1 < $num_r2) {
   332                 $result_header->setTitle(sprintf($this->
lng->txt(
'result_x'), $result->getResult()));
   334                 $formula = 
new ilTextInputGUI($this->
lng->txt(
'formula'), 
'formula_' . $result->getResult());
   335                 $formula->setInfo($this->
lng->txt(
'fq_formula_desc'));
   336                 $formula->setRequired(
true);
   337                 $formula->setSize(50);
   338                 $formula->setValue($result->getFormula());
   339                 $formula->setSuffix(
' = ' . $result->getResult());
   342                     $suggest_range_for_result !== null &&
   343                     $suggest_range_for_result === $result->getResult() &&
   344                     strlen($result->substituteFormula($variables, 
$results))
   346                     $result->suggestRange($variables, 
$results);
   349                 $range_min = 
new ilNumberInputGUI($this->
lng->txt(
'range_min'), 
'range_min_' . $result->getResult());
   350                 $range_min->allowDecimals(
true);
   351                 $range_min->setSize(3);
   352                 $range_min->setRequired(
true);
   353                 $range_min->setValue($result->getRangeMin());
   355                 $range_max = 
new ilNumberInputGUI($this->
lng->txt(
'range_max'), 
'range_max_' . $result->getResult());
   356                 $range_max->allowDecimals(
true);
   357                 $range_max->setSize(3);
   358                 $range_max->setRequired(
true);
   359                 $range_max->setValue($result->getRangeMax());
   363                 $precision = 
new ilNumberInputGUI($this->
lng->txt(
'precision'), 
'precision_' . $result->getResult());
   364                 $precision->setRequired(
true);
   365                 $precision->setSize(3);
   366                 $precision->setMinValue(0);
   367                 $precision->setInfo($this->
lng->txt(
'fq_precision_info'));
   368                 $precision->setValue($result->getPrecision());
   370                 $tolerance = 
new ilNumberInputGUI($this->
lng->txt(
'tolerance'), 
'tolerance_' . $result->getResult());
   371                 $tolerance->setSize(3);
   372                 $tolerance->setMinValue(0);
   373                 $tolerance->setMaxValue(100);
   374                 $tolerance->allowDecimals(
true);
   375                 $tolerance->setInfo($this->
lng->txt(
'tolerance_info'));
   376                 $tolerance->setValue($result->getTolerance());
   379                 $suggest_range_button->setHtml(
   380                     $this->ui_renderer->render(
   381                         $this->ui_factory->button()->standard(
   382                             $this->
lng->txt(
'suggest_range'),
   390                 $sel_result_units = 
new ilSelectInputGUI($this->
lng->txt(
'unit'), 
'unit_' . $result->getResult());
   391                 $sel_result_units->
setOptions([0 => $this->
lng->txt(
'no_selection')] + $unit_options);
   392                 $sel_result_units->setInfo($this->
lng->txt(
'result_unit_info'));
   393                 if (is_object($result->getUnit())) {
   394                     $sel_result_units->setValue($result->getUnit()->getId());
   399                 $mc_result_units->setInfo($this->
lng->txt(
'result_units_info'));
   400                 $selectedvalues = [];
   401                 foreach ($unit_options as $unit_id => 
$txt) {
   402                     if ($this->
hasResultUnit($result, $unit_id, $result_units)) {
   403                         $selectedvalues[] = $unit_id;
   406                 $mc_result_units->setValue($selectedvalues);
   408                 $result_type = 
new ilRadioGroupInputGUI($this->
lng->txt(
'result_type_selection'), 
'result_type_' . $result->getResult());
   412                 $no_type->
setInfo($this->
lng->txt(
'fq_no_restriction_info'));
   415                 $result_dec->
setInfo($this->
lng->txt(
'result_dec_info'));
   418                 $result_frac->
setInfo($this->
lng->txt(
'result_frac_info'));
   420                 $result_co_frac = 
new ilRadioOption($this->
lng->txt(
'result_co_frac'), 
'3');
   421                 $result_co_frac->
setInfo($this->
lng->txt(
'result_co_frac_info'));
   423                 $result_type->addOption($no_type);
   424                 $result_type->addOption($result_dec);
   425                 $result_type->addOption($result_frac);
   426                 $result_type->addOption($result_co_frac);
   427                 $result_type->setValue(strlen($result->getResultType()) ? $result->getResultType() : 0);
   429                 $points = 
new ilNumberInputGUI($this->
lng->txt(
'points'), 
'points_' . $result->getResult());
   430                 $points->allowDecimals(
true);
   431                 $points->setRequired(
true);
   433                 $points->setMinValue(0);
   434                 $points->setValue(strlen($result->getPoints()) ? $result->getPoints() : 1);
   436                 $rating_type = 
new ilCheckboxInputGUI($this->
lng->txt(
'advanced_rating'), 
'rating_advanced_' . $result->getResult());
   437                 $rating_type->setValue(1);
   438                 $rating_type->setInfo($this->
lng->txt(
'advanced_rating_info'));
   442                     if (!$advanced_rating) {
   443                         $rating_type->setDisabled(
true);
   444                         $rating_type->setChecked(
false);
   446                         $rating_type->setChecked(strlen($result->getRatingSimple()) && $result->getRatingSimple() ? false : 
true);
   450                 $sign = 
new ilNumberInputGUI($this->
lng->txt(
'rating_sign'), 
'rating_sign_' . $result->getResult());
   451                 $sign->setRequired(
true);
   453                 $sign->setMinValue(0);
   454                 $sign->setValue($result->getRatingSign());
   455                 $rating_type->addSubItem($sign);
   457                 $value = 
new ilNumberInputGUI($this->
lng->txt(
'rating_value'), 
'rating_value_' . $result->getResult());
   458                 $value->setRequired(
true);
   460                 $value->setMinValue(0);
   461                 $value->setValue($result->getRatingValue());
   462                 $rating_type->addSubItem($value);
   464                 $unit = 
new ilNumberInputGUI($this->
lng->txt(
'rating_unit'), 
'rating_unit_' . $result->getResult());
   465                 $unit->setRequired(
true);
   467                 $unit->setMinValue(0);
   468                 $unit->setValue($result->getRatingUnit());
   469                 $rating_type->addSubItem($unit);
   472                 $rating_type->addSubItem($info_text);
   474                 $form->addItem($result_header);
   475                 $form->addItem($formula);
   476                 $form->addItem($range_min);
   477                 $form->addItem($range_max);
   478                 $form->addItem($suggest_range_button);
   479                 $form->addItem($precision);
   480                 $form->addItem($tolerance);
   481                 $form->addItem($sel_result_units);
   482                 $form->addItem($mc_result_units);
   483                 $form->addItem($result_type);
   484                 $form->addItem($points);
   485                 $form->addItem($rating_type);
   488             $defined_result_vars = [];
   490             $defined_result_res = [];
   492             foreach ($variables as $key => 
$object) {
   493                 $quest_vars[$key] = $key;
   497                 $result_vars[$key] = $key;
   504                 $formula = $tmp_result->getFormula() ?? 
'';
   506                 preg_match_all(
"/([$][v][0-9]*)/", $formula, $form_vars);
   507                 preg_match_all(
"/([$][r][0-9]*)/", $formula, $form_res);
   508                 foreach ($form_vars[0] as $res_var) {
   509                     $defined_result_vars[$res_var] = $res_var;
   512                 foreach ($form_res[0] as $res_res) {
   513                     $defined_result_res[$res_res] = $res_res;
   518         $result_has_undefined_vars = [];
   519         $question_has_unused_vars = [];
   520         $result_has_undefined_res = [];
   522         if (is_array($quest_vars) && count($quest_vars) > 0) {
   523             $result_has_undefined_vars = array_diff($defined_result_vars, $quest_vars);
   524             $question_has_unused_vars = array_diff($quest_vars, $defined_result_vars);
   527         if (is_array($result_vars) && count($result_vars) > 0) {
   528             $result_has_undefined_res = array_diff($defined_result_res, $result_vars);
   532         if ($result_has_undefined_vars !== [] || $question_has_unused_vars !== []) {
   533             if (count($result_has_undefined_vars) > 0) {
   534                 $error_message .= $this->
lng->txt(
"res_contains_undef_var") . 
'<br>';
   536             if (count($question_has_unused_vars) > 0) {
   537                 $error_message .= $this->
lng->txt(
"que_contains_unused_var") . 
'<br>';
   542                 $this->tpl->setOnScreenMessage(
'failure', $error_message);
   546         if (is_array($result_has_undefined_res) && count($result_has_undefined_res) > 0) {
   547             $error_message .= $this->
lng->txt(
"res_contains_undef_res") . 
'<br>';
   551         if ($save && !$checked) {
   552             $this->tpl->setOnScreenMessage(
'failure', $error_message);
   557         $form->addCommandButton(
'parseQuestion', $this->
lng->txt(
'parseQuestion'));
   558         $form->addCommandButton(
'saveReturn', $this->
lng->txt(
'save_return'));
   559         $form->addCommandButton(
'save', $this->
lng->txt(
'save'));
   566             foreach ($this->request_data_collector->getParsedBody() as $key => $value) {
   567                 if (preg_match(
"/^unit_(\\\$v\d+)$/", $key, $matches)) {
   568                     array_push($found_vars, $matches[1]);
   570                 if (preg_match(
"/^unit_(\\\$r\d+)$/", $key, $matches)) {
   571                     array_push($found_results, $matches[1]);
   576             foreach ($this->request_data_collector->getParsedBody() as $key => $value) {
   577                 $item = $form->getItemByPostVar($key);
   578                 if ($item !== null) {
   579                     switch (get_class($item)) {
   580                         case 'ilDurationInputGUI':
   581                             $item->setHours($value[
'hh']);
   582                             $item->setMinutes($value[
'mm']);
   583                             $item->setSeconds($value[
'ss']);
   586                             $item->setValue($value);
   591             $check = array_merge($found_vars, $found_results);
   592             foreach ((array) $form->getItems() as $item) {
   593                 $postvar = $item->getPostVar();
   594                 if (preg_match(
"/_\\\$[r|v]\d+/", $postvar, $matches)) {
   595                     $k = substr(array_shift($matches), 1);
   596                     if (!in_array($k, 
$check)) {
   597                         $form->removeItemByPostVar($postvar);
   601             $variables = array_filter($variables, fn($k, $v) => in_array($v, 
$check), ARRAY_FILTER_USE_BOTH);
   604             $errors = !$form->checkInput();
   606             $custom_errors = 
false;
   607             if ($variables !== []) {
   608                 foreach ($variables as $variable) {
   609                     $min_range = $form->getItemByPostVar(
'range_min_' . $variable->getVariable());
   610                     $max_range = $form->getItemByPostVar(
'range_max_' . $variable->getVariable());
   611                     if ($min_range->getValue() > $max_range->getValue()) {
   612                         $min_range->setAlert($this->
lng->txt(
'err_range'));
   613                         $max_range->setAlert($this->
lng->txt(
'err_range'));
   614                         $custom_errors = 
true;
   616                     $intPrecision = $form->getItemByPostVar(
'intprecision_' . $variable->getVariable());
   617                     $decimal_spots = $form->getItemByPostVar(
'precision_' . $variable->getVariable());
   618                     if ($decimal_spots->getValue() == 0
   619                         && $min_range->getValue() !== null
   620                         && $max_range->getValue() !== null
   621                         && !$variable->isIntPrecisionValid(
   622                             $intPrecision->getValue(),
   623                             $min_range->getValue(),
   624                             $max_range->getValue()
   627                         $intPrecision->setAlert($this->
lng->txt(
'err_division'));
   628                         $custom_errors = 
true;
   638                     $min_range = $form->getItemByPostVar(
'range_min_' . $result->getResult());
   639                     $max_range = $form->getItemByPostVar(
'range_max_' . $result->getResult());
   640                     if ($min_range->getValue() > $max_range->getValue()) {
   641                         $min_range->setAlert($this->
lng->txt(
'err_range'));
   642                         $max_range->setAlert($this->
lng->txt(
'err_range'));
   643                         $custom_errors = 
true;
   647                     $formula = $form->getItemByPostVar(
'formula_' . $result->getResult());
   648                     if (strpos($formula->getValue(), $result->getResult()) !== 
false) {
   649                         $formula->setAlert($this->
lng->txt(
'errRecursionInResult'));
   650                         $custom_errors = 
true;
   653                     $result_unit = $form->getItemByPostVar(
'unit_' . $result->getResult());
   654                     $rating_advanced = $form->getItemByPostVar(
'rating_advanced_' . $result->getResult());
   655                     if (((
int) $result_unit->getValue() <= 0) && $rating_advanced->getChecked()) {
   656                         unset(
$_POST[
'rating_advanced_' . $result->getResult()]); 
   657                         $rating_advanced->setDisabled(
true);
   658                         $rating_advanced->setChecked(
false);
   659                         $rating_advanced->setAlert($this->
lng->txt(
'err_rating_advanced_not_allowed'));
   660                         $custom_errors = 
true;
   661                     } elseif ($rating_advanced->getChecked()) {
   662                         $rating_sign = $form->getItemByPostVar(
'rating_sign_' . $result->getResult());
   663                         $rating_value = $form->getItemByPostVar(
'rating_value_' . $result->getResult());
   664                         $rating_unit = $form->getItemByPostVar(
'rating_unit_' . $result->getResult());
   666                         $percentage = $rating_sign->getValue() + $rating_value->getValue() + $rating_unit->getValue();
   667                         if ($percentage != 100) {
   668                             $rating_advanced->setAlert($this->
lng->txt(
'err_wrong_rating_advanced'));
   669                             $custom_errors = 
true;
   673                     preg_match_all(
"/([$][v][0-9]*)/", $formula->getValue(), $form_vars);
   674                     $result_has_undefined_vars = array_diff($form_vars[0], $found_vars);
   675                     if (count($result_has_undefined_vars)) {
   677                         $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'res_contains_undef_var'));
   682             if ($custom_errors && !$errors) {
   684                 $this->tpl->setOnScreenMessage(
'failure', $this->
lng->txt(
'form_input_not_valid'));
   686             foreach ($this->request_data_collector->getParsedBody() as $key => $value) {
   687                 $item = $form->getItemByPostVar($key);
   688                 if ($item !== null) {
   689                     switch (get_class($item)) {
   690                         case 'ilDurationInputGUI':
   691                             $item->setHours($value[
'hh']);
   692                             $item->setMinutes($value[
'mm']);
   693                             $item->setSeconds($value[
'ss']);
   696                             $item->setValue($value);
   713         return static function (
$id) use ($result): 
string {
   714             return "document.getElementById('$id').addEventListener('click', "   716                 . 
'  e.target.setAttribute("name", "cmd[suggestRange]");'   717                 . 
'  let input = document.createElement("input");'   718                 . 
'  input.type = "hidden";'   719                 . 
'  input.name = "suggest_range_for";'   720                 . 
"  input.value = '$result';"   721                 . 
'  e.target.form.appendChild(input);'   722                 . 
'  e.target.form.requestSubmit(e.target);'   729         if (array_key_exists($result->getResult(), $resultunits)) {
   730             if (array_key_exists($unit_id, $resultunits[$result->getResult()])) {
   746         $resultunit = $result->getUnit();
   754         if (is_object($resultunit)) {
   775         $title = $this->request_data_collector->string(
'title');
   776         $author = $this->request_data_collector->string(
'author');
   777         $question = $this->request_data_collector->string(
'question');
   779         if (empty($title) || empty($author) || empty($question)) {
   790         bool $graphical_output = 
false,
   791         bool $result_output = 
false,
   792         bool $show_question_only = 
true,
   793         bool $show_feedback = 
false,
   794         bool $show_correct_solution = 
false,
   795         bool $show_manual_scoring = 
false,
   796         bool $show_question_text = 
true,
   797         bool $show_inline_feedback = 
true   800         if ($pass !== null) {
   801             $user_solution = $this->
object->getVariableSolutionValuesForPass($active_id, $pass);
   803             $user_solution = array_reduce(
   804                 $this->
object->fetchAllVariables($this->object->getQuestion()),
   812         if (($active_id > 0) && (!$show_correct_solution)) {
   813             $user_solution[
'active_id'] = $active_id;
   814             $user_solution[
'pass'] = $pass;
   815             $solutions = $this->
object->getSolutionValues($active_id, $pass);
   816             foreach ($solutions as $solution_value) {
   817                 if (preg_match(
'/^(\$v\d+)$/', $solution_value[
'value1'], $matches)) {
   818                     $user_solution[$matches[1]] = $solution_value[
'value2'];
   819                 } elseif (preg_match(
'/^(\$r\d+)$/', $solution_value[
'value1'], $matches)) {
   820                     if (!array_key_exists($matches[1], $user_solution)) {
   821                         $user_solution[$matches[1]] = [];
   823                     $user_solution[$matches[1]][
"value"] = $solution_value[
'value2'];
   824                 } elseif (preg_match(
'/^(\$r\d+)_unit$/', $solution_value[
'value1'], $matches)) {
   825                     if (!array_key_exists($matches[1], $user_solution)) {
   826                         $user_solution[$matches[1]] = [];
   828                     $user_solution[$matches[1]][
'unit'] = $solution_value[
'value2'];
   831         } elseif ($active_id !== 0) {
   832             $user_solution = $this->
object->getBestSolution($this->
object->getSolutionValues($active_id, $pass));
   834             $solutionValues = [];
   836             if (is_array($participants_solution)) {
   837                 foreach ($participants_solution as $val1 => $val2) {
   838                     $solutionValues[] = [
'value1' => $val1, 
'value2' => $val2];
   841             $user_solution = $this->
object->getBestSolution($solutionValues);
   852             $show_correct_solution,
   853             $show_manual_scoring,
   856             $show_inline_feedback
   861         mixed $user_solutions,
   864         bool $graphical_output = 
false,
   865         bool $result_output = 
false,
   866         bool $show_question_only = 
true,
   867         bool $show_feedback = 
false,
   868         bool $show_correct_solution = 
false,
   869         bool $show_manual_scoring = 
false,
   870         bool $show_question_text = 
true,
   871         bool $show_autosave_title = 
false,
   872         bool $show_inline_feedback = 
false,
   874         $template = 
new ilTemplate(
"tpl.il_as_qpl_formulaquestion_output_solution.html", 
true, 
true, 
'components/ILIAS/TestQuestionPool');
   875         $correctness_icons = [
   879         $questiontext = $this->
object->substituteVariables($user_solutions, $graphical_output, 
true, $result_output, $correctness_icons);
   881         $questionoutput = $template->get();
   882         $solutiontemplate = 
new ilTemplate(
"tpl.il_as_tst_solution_output.html", 
true, 
true, 
"components/ILIAS/TestQuestionPool");
   884         if (strlen($feedback)) {
   889             $solutiontemplate->setVariable(
"ILC_FB_CSS_CLASS", $cssClass);
   892         $solutiontemplate->setVariable(
"SOLUTION_OUTPUT", $questionoutput);
   894         $solutionoutput = $solutiontemplate->get();
   895         if (!$show_question_only) {
   898         return $solutionoutput;
   902         bool $show_question_only = 
false,
   903         bool $show_inline_feedback = 
false   908             foreach ($solutions as $val1 => $val2) {
   909                 if (preg_match(
'/^(\$v\d+)$/', $val1, $matches)) {
   910                     $user_solution[$matches[1]] = $val2;
   911                 } elseif (preg_match(
'/^(\$r\d+)$/', $val1, $matches)) {
   912                     if (!array_key_exists($matches[1], $user_solution)) {
   913                         $user_solution[$matches[1]] = [];
   915                     $user_solution[$matches[1]][
'value'] = $val2;
   916                 } elseif (preg_match(
'/^(\$r\d+)_unit$/', $val1, $matches)) {
   917                     if (!array_key_exists($matches[1], $user_solution)) {
   918                         $user_solution[$matches[1]] = [];
   920                     $user_solution[$matches[1]][
'unit'] = $val2;
   923                 if (preg_match(
'/^(\$r\d+)/', $val1, $matches) && !isset($user_solution[$matches[1]][
'result_type'])) {
   929         if (!$this->
object->hasRequiredVariableSolutionValues($user_solution)) {
   930             $user_solution = $this->
object->getInitialVariableSolutionValues();
   937         $template = 
new ilTemplate(
"tpl.il_as_qpl_formulaquestion_output.html", 
true, 
true, 
'components/ILIAS/TestQuestionPool');
   939             $questiontext = $this->
object->substituteVariables($user_solution);
   941             $questiontext = $this->
object->substituteVariables([]);
   944         $questionoutput = $template->get();
   945         if (!$show_question_only) {
   949         return $questionoutput;
   955         bool $is_question_postponed = 
false,
   956         array|
bool $user_post_solutions = 
false,
   957         bool $show_specific_inline_feedback = 
false   959         $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'enter_valid_values'));
   963             $solutions = $this->
object->getTestOutputSolutions($active_id, $pass);
   964             $actualPassIndex = null;
   965             if ($this->
object->getTestPresentationConfig()->isSolutionInitiallyPrefilled()) {
   968             foreach ($solutions as $idx => $solution_value) {
   969                 if (preg_match(
'/^(\$v\d+)$/', $solution_value[
'value1'], $matches)) {
   970                     if ($this->
object->getTestPresentationConfig()->isSolutionInitiallyPrefilled()) {
   971                         $this->
object->saveCurrentSolution($active_id, $actualPassIndex, $matches[1], $solution_value[
'value2'], 
true);
   973                     $user_solution[$matches[1]] = $solution_value[
'value2'];
   974                 } elseif (preg_match(
'/^(\$r\d+)$/', $solution_value[
'value1'], $matches)) {
   975                     if (!array_key_exists($matches[1], $user_solution)) {
   976                         $user_solution[$matches[1]] = [];
   978                     $user_solution[$matches[1]][
'value'] = $solution_value[
'value2'];
   979                 } elseif (preg_match(
'/^(\$r\d+)_unit$/', $solution_value[
'value1'], $matches)) {
   980                     if (!array_key_exists($matches[1], $user_solution)) {
   981                         $user_solution[$matches[1]] = [];
   983                     $user_solution[$matches[1]][[
'unit']] = $solution_value[
'value2'];
   985                 if (preg_match(
'/^(\$r\d+)/', $solution_value[
'value1'], $matches) && !isset($user_solution[$matches[1]][
'result_type'])) {
   992         $solutions = $this->
object->getSolutionValues($active_id, $pass, 
true);
   993         foreach ($solutions as $idx => $solution_value) {
   994             if (preg_match(
'/^(\$v\d+)$/', $solution_value[
'value1'], $matches)) {
   995                 $user_solution[$matches[1]] = $solution_value[
'value2'];
   999         if ($user_solution === []) {
  1000             $user_solution = $this->
object->getVariableSolutionValuesForPass($active_id, $pass);
  1004         $template = 
new ilTemplate(
"tpl.il_as_qpl_formulaquestion_output.html", 
true, 
true, 
'components/ILIAS/TestQuestionPool');
  1006         $questiontext = $this->
object->substituteVariables($user_solution);
  1010         $questionoutput = $template->get();
  1011         $pageoutput = $this->
outQuestionPage(
"", $is_question_postponed, $active_id, $questionoutput);
 
setAdditionalContentEditingModeFromPost()
 
hasCorrectSolution($activeId, $passIndex)
 
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
 
static getInstance($identifier)
 
generateCorrectnessIconsForCorrectness(int $correctness)
 
static _getPass($active_id)
Retrieves the actual pass of a given user for a given test. 
 
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)
 
addBasicQuestionFormProperties(ilPropertyFormGUI $form)
 
withAdditionalOnLoadCode(Closure $binder)
 
const CSS_CLASS_FEEDBACK_CORRECT
 
populateTaxonomyFormSection(ilPropertyFormGUI $form)
 
editQuestion(bool $checkonly=false, ?bool $is_save_cmd=null)
 
const CSS_CLASS_FEEDBACK_WRONG
 
saveTaxonomyAssignments()
 
getILIASPage(string $html="")
Returns the ILIAS Page around a question. 
 
addSaveOnEnterOnLoadCode()
 
outQuestionPage($a_temp_var, $a_postponed=false, $active_id="", $html="", $inlineFeedbackEnabled=false)
 
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins 
 
__construct(Container $dic, ilPlugin $plugin)
 
addErrorMessage(string $errormessage)
 
setTestSpecificProperties()
 
renderEditForm(ilPropertyFormGUI $form)
 
getGenericFeedbackOutput(int $active_id, ?int $pass)